Merge "Clean up remote animation definitions when activity is destroyed"
diff --git a/Android.bp b/Android.bp
index bf901ec..536f688 100644
--- a/Android.bp
+++ b/Android.bp
@@ -264,7 +264,9 @@
":framework-appsearch-sources",
":framework-sdkext-sources",
":framework-statsd-sources",
+ ":framework-tethering-srcs",
":updatable-media-srcs",
+ ":framework-mediaprovider-sources",
":framework-wifi-updatable-sources",
]
}
@@ -380,6 +382,8 @@
"ext",
"unsupportedappusage",
"updatable_media_stubs",
+ "framework_mediaprovider_stubs",
+ "framework-tethering",
],
jarjar_rules: ":framework-jarjar-rules",
@@ -468,6 +472,7 @@
static_libs: [
"framework-minus-apex",
"updatable_media_stubs",
+ "framework_mediaprovider_stubs",
"framework-appsearch", // TODO(b/146218515): should be framework-appsearch-stubs
"framework-sdkext-stubs-systemapi",
// TODO(b/146167933): Use framework-statsd-stubs instead.
@@ -583,11 +588,14 @@
filegroup {
name: "framework-annotations",
srcs: [
- "core/java/android/annotation/NonNull.java",
- "core/java/android/annotation/Nullable.java",
"core/java/android/annotation/IntDef.java",
"core/java/android/annotation/IntRange.java",
+ "core/java/android/annotation/NonNull.java",
+ "core/java/android/annotation/Nullable.java",
+ "core/java/android/annotation/RequiresPermission.java",
+ "core/java/android/annotation/SdkConstant.java",
"core/java/android/annotation/SystemApi.java",
+ "core/java/android/annotation/TestApi.java",
"core/java/android/annotation/UnsupportedAppUsage.java",
"core/java/com/android/internal/annotations/GuardedBy.java",
"core/java/com/android/internal/annotations/VisibleForTesting.java",
@@ -621,10 +629,26 @@
],
}
+// keep these files in sync with the package/Tethering/jarjar-rules.txt for the tethering module.
filegroup {
name: "framework-tethering-shared-srcs",
srcs: [
"core/java/android/util/LocalLog.java",
+ "core/java/com/android/internal/util/BitUtils.java",
+ "core/java/com/android/internal/util/IndentingPrintWriter.java",
+ "core/java/com/android/internal/util/IState.java",
+ "core/java/com/android/internal/util/MessageUtils.java",
+ "core/java/com/android/internal/util/Preconditions.java",
+ "core/java/com/android/internal/util/State.java",
+ "core/java/com/android/internal/util/StateMachine.java",
+ ],
+}
+
+filegroup {
+ name: "framework-tethering-annotations",
+ srcs: [
+ "core/java/android/annotation/NonNull.java",
+ "core/java/android/annotation/SystemApi.java",
],
}
// Build ext.jar
@@ -1648,20 +1672,23 @@
filegroup {
name: "framework-media-annotation-srcs",
srcs: [
+ ":framework-annotations",
"core/java/android/annotation/CallbackExecutor.java",
"core/java/android/annotation/CallSuper.java",
"core/java/android/annotation/DrawableRes.java",
- "core/java/android/annotation/IntDef.java",
"core/java/android/annotation/LongDef.java",
- "core/java/android/annotation/NonNull.java",
- "core/java/android/annotation/Nullable.java",
- "core/java/android/annotation/RequiresPermission.java",
- "core/java/android/annotation/SdkConstant.java",
"core/java/android/annotation/StringDef.java",
- "core/java/android/annotation/SystemApi.java",
- "core/java/android/annotation/TestApi.java",
- "core/java/android/annotation/UnsupportedAppUsage.java",
- "core/java/com/android/internal/annotations/GuardedBy.java",
+ ],
+}
+
+filegroup {
+ name: "framework-mediaprovider-annotation-sources",
+ srcs: [
+ ":framework-annotations",
+ "core/java/android/annotation/BytesLong.java",
+ "core/java/android/annotation/CurrentTimeMillisLong.java",
+ "core/java/android/annotation/CurrentTimeSecondsLong.java",
+ "core/java/android/annotation/DurationMillisLong.java",
],
}
diff --git a/CleanSpec.mk b/CleanSpec.mk
index b84e715..0b7ea28 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -259,6 +259,7 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/service-statsd.jar)
$(call add-clean-step, rm -rf $(SOONG_OUT_DIR)/.intermediates/frameworks/base/libincremental_aidl-cpp-source/)
$(call add-clean-step, rm -rf $(SOONG_OUT_DIR)/.intermediates/frameworks/base/libincremental_manager_aidl-cpp-source/)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/InProcessTethering)
# ******************************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
# ******************************************************************
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 278a786..661f32f 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -146,7 +146,8 @@
final CountDownLatch latch = new CountDownLatch(1);
registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userId);
- // Don't use this.startUserInBackground() since only waiting until ACTION_USER_STARTED.
+ // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until
+ // ACTION_USER_STARTED.
mIam.startUserInBackground(userId);
latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
@@ -156,6 +157,48 @@
}
}
+ /**
+ * Measures the time until ACTION_USER_STARTED is received.
+ */
+ @Test
+ public void startUser() throws Exception {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createUserNoFlags();
+ final CountDownLatch latch = new CountDownLatch(1);
+ registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userId);
+ mRunner.resumeTiming();
+
+ mIam.startUserInBackground(userId);
+ latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
+
+ mRunner.pauseTiming();
+ removeUser(userId);
+ mRunner.resumeTiming();
+ }
+ }
+
+ /**
+ * Measures the time until unlock listener is triggered and user is unlocked.
+ */
+ @Test
+ public void startAndUnlockUser() throws Exception {
+ while (mRunner.keepRunning()) {
+ mRunner.pauseTiming();
+ final int userId = createUserNoFlags();
+ mRunner.resumeTiming();
+
+ // Waits for UserState.mUnlockProgress.finish().
+ startUserInBackgroundAndWaitForUnlock(userId);
+
+ mRunner.pauseTiming();
+ removeUser(userId);
+ mRunner.resumeTiming();
+ }
+ }
+
+
+
@Test
public void switchUser() throws Exception {
while (mRunner.keepRunning()) {
@@ -309,7 +352,7 @@
final int userId = createManagedProfile();
mRunner.resumeTiming();
- startUserInBackground(userId);
+ startUserInBackgroundAndWaitForUnlock(userId);
mRunner.pauseTiming();
removeUser(userId);
@@ -326,11 +369,11 @@
mRunner.pauseTiming();
final int userId = createManagedProfile();
// Start the profile initially, then stop it. Similar to setQuietModeEnabled.
- startUserInBackground(userId);
+ startUserInBackgroundAndWaitForUnlock(userId);
stopUser(userId, true);
mRunner.resumeTiming();
- startUserInBackground(userId);
+ startUserInBackgroundAndWaitForUnlock(userId);
mRunner.pauseTiming();
removeUser(userId);
@@ -352,7 +395,7 @@
installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
mRunner.resumeTiming();
- startUserInBackground(userId);
+ startUserInBackgroundAndWaitForUnlock(userId);
startApp(userId, DUMMY_PACKAGE_NAME);
mRunner.pauseTiming();
@@ -376,13 +419,13 @@
final int userId = createManagedProfile();
WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
- startUserInBackground(userId);
+ startUserInBackgroundAndWaitForUnlock(userId);
startApp(userId, DUMMY_PACKAGE_NAME);
stopUser(userId, true);
TimeUnit.SECONDS.sleep(1); // Brief cool-down before re-starting profile.
mRunner.resumeTiming();
- startUserInBackground(userId);
+ startUserInBackgroundAndWaitForUnlock(userId);
startApp(userId, DUMMY_PACKAGE_NAME);
mRunner.pauseTiming();
@@ -423,7 +466,7 @@
mRunner.resumeTiming();
final int userId = createManagedProfile();
- startUserInBackground(userId);
+ startUserInBackgroundAndWaitForUnlock(userId);
installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
startApp(userId, DUMMY_PACKAGE_NAME);
@@ -441,7 +484,7 @@
while (mRunner.keepRunning()) {
mRunner.pauseTiming();
final int userId = createManagedProfile();
- startUserInBackground(userId);
+ startUserInBackgroundAndWaitForUnlock(userId);
mRunner.resumeTiming();
stopUser(userId, true);
@@ -467,7 +510,7 @@
final int userId = createManagedProfile();
mRunner.resumeTiming();
- startUserInBackground(userId);
+ startUserInBackgroundAndWaitForUnlock(userId);
mRunner.pauseTiming();
removeUser(userId);
@@ -490,7 +533,7 @@
final int userId = createManagedProfile();
mRunner.resumeTiming();
- startUserInBackground(userId);
+ startUserInBackgroundAndWaitForUnlock(userId);
mRunner.pauseTiming();
removeUser(userId);
@@ -526,18 +569,19 @@
}
/**
- * Start user in background and wait for it to unlock (equivalent to ACTION_USER_UNLOCKED).
- * To start in foreground instead, see {@link #switchUser(int)}.
- * This should always be used for profiles since profiles cannot be started in foreground.
+ * Start user in background and wait for it to unlock by waiting for
+ * UserState.mUnlockProgress.finish().
+ * <p> To start in foreground instead, see {@link #switchUser(int)}.
+ * <p> This should always be used for profiles since profiles cannot be started in foreground.
*/
- private void startUserInBackground(int userId) {
+ private void startUserInBackgroundAndWaitForUnlock(int userId) {
final ProgressWaiter waiter = new ProgressWaiter();
try {
mIam.startUserInBackgroundWithListener(userId, waiter);
boolean success = waiter.waitForFinish(TIMEOUT_IN_SECOND);
attestTrue("Failed to start user " + userId + " in background.", success);
} catch (RemoteException e) {
- Log.e(TAG, "startUserInBackground failed", e);
+ Log.e(TAG, "startUserInBackgroundAndWaitForUnlock failed", e);
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 701ea84..3f58c72 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -617,6 +617,14 @@
}
};
+ /** AlarmListener to start monitoring motion if there are registered stationary listeners. */
+ private final AlarmManager.OnAlarmListener mMotionRegistrationAlarmListener = () -> {
+ synchronized (DeviceIdleController.this) {
+ if (mStationaryListeners.size() > 0) {
+ startMonitoringMotionLocked();
+ }
+ }
+ };
private final AlarmManager.OnAlarmListener mMotionTimeoutAlarmListener = () -> {
synchronized (DeviceIdleController.this) {
@@ -753,6 +761,7 @@
@Override
public void onTrigger(TriggerEvent event) {
synchronized (DeviceIdleController.this) {
+ active = false;
motionLocked();
}
}
@@ -760,6 +769,8 @@
@Override
public void onSensorChanged(SensorEvent event) {
synchronized (DeviceIdleController.this) {
+ mSensorManager.unregisterListener(this, mMotionSensor);
+ active = false;
motionLocked();
}
}
@@ -1878,6 +1889,27 @@
return controller.new MyHandler(BackgroundThread.getHandler().getLooper());
}
+ Sensor getMotionSensor() {
+ final SensorManager sensorManager = getSensorManager();
+ Sensor motionSensor = null;
+ int sigMotionSensorId = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
+ if (sigMotionSensorId > 0) {
+ motionSensor = sensorManager.getDefaultSensor(sigMotionSensorId, true);
+ }
+ if (motionSensor == null && mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
+ motionSensor = sensorManager.getDefaultSensor(
+ Sensor.TYPE_WRIST_TILT_GESTURE, true);
+ }
+ if (motionSensor == null) {
+ // As a last ditch, fall back to SMD.
+ motionSensor = sensorManager.getDefaultSensor(
+ Sensor.TYPE_SIGNIFICANT_MOTION, true);
+ }
+ return motionSensor;
+ }
+
PowerManager getPowerManager() {
return mContext.getSystemService(PowerManager.class);
}
@@ -2031,21 +2063,7 @@
mSensorManager = mInjector.getSensorManager();
if (mUseMotionSensor) {
- int sigMotionSensorId = getContext().getResources().getInteger(
- com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
- if (sigMotionSensorId > 0) {
- mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
- }
- if (mMotionSensor == null && getContext().getResources().getBoolean(
- com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
- mMotionSensor = mSensorManager.getDefaultSensor(
- Sensor.TYPE_WRIST_TILT_GESTURE, true);
- }
- if (mMotionSensor == null) {
- // As a last ditch, fall back to SMD.
- mMotionSensor = mSensorManager.getDefaultSensor(
- Sensor.TYPE_SIGNIFICANT_MOTION, true);
- }
+ mMotionSensor = mInjector.getMotionSensor();
}
if (getContext().getResources().getBoolean(
@@ -3434,6 +3452,10 @@
if (mStationaryListeners.size() > 0) {
postStationaryStatusUpdated();
scheduleMotionTimeoutAlarmLocked();
+ // We need to re-register the motion listener, but we don't want the sensors to be
+ // constantly active or to churn the CPU by registering too early, register after some
+ // delay.
+ scheduleMotionRegistrationAlarmLocked();
}
if (mQuickDozeActivated && !mQuickDozeActivatedWhileIdling) {
// Don't exit idle due to motion if quick doze is enabled.
@@ -3500,9 +3522,12 @@
*/
private void maybeStopMonitoringMotionLocked() {
if (DEBUG) Slog.d(TAG, "maybeStopMonitoringMotionLocked()");
- if (mMotionSensor != null && mMotionListener.active && mStationaryListeners.size() == 0) {
- mMotionListener.unregisterLocked();
- cancelMotionTimeoutAlarmLocked();
+ if (mMotionSensor != null && mStationaryListeners.size() == 0) {
+ if (mMotionListener.active) {
+ mMotionListener.unregisterLocked();
+ cancelMotionTimeoutAlarmLocked();
+ }
+ cancelMotionRegistrationAlarmLocked();
}
}
@@ -3533,6 +3558,10 @@
mAlarmManager.cancel(mMotionTimeoutAlarmListener);
}
+ private void cancelMotionRegistrationAlarmLocked() {
+ mAlarmManager.cancel(mMotionRegistrationAlarmListener);
+ }
+
void cancelSensingTimeoutAlarmLocked() {
if (mNextSensingTimeoutAlarmTime != 0) {
mNextSensingTimeoutAlarmTime = 0;
@@ -3573,6 +3602,15 @@
mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler);
}
+ private void scheduleMotionRegistrationAlarmLocked() {
+ if (DEBUG) Slog.d(TAG, "scheduleMotionRegistrationAlarmLocked");
+ long nextMotionRegistrationAlarmTime =
+ mInjector.getElapsedRealtime() + mConstants.MOTION_INACTIVE_TIMEOUT / 2;
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextMotionRegistrationAlarmTime,
+ "DeviceIdleController.motion_registration", mMotionRegistrationAlarmListener,
+ mHandler);
+ }
+
private void scheduleMotionTimeoutAlarmLocked() {
if (DEBUG) Slog.d(TAG, "scheduleMotionAlarmLocked");
long nextMotionTimeoutAlarmTime =
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
index 7c25c6c..c5fd3f2 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
@@ -112,7 +112,6 @@
import android.util.Slog;
import android.util.StatsLog;
import android.util.proto.ProtoOutputStream;
-import android.util.proto.ProtoStream;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.procstats.IProcessStats;
@@ -543,9 +542,9 @@
private void informAllUidsLocked(Context context) throws RemoteException {
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
PackageManager pm = context.getPackageManager();
- final List<UserInfo> users = um.getUsers(true);
+ final List<UserHandle> users = um.getUserHandles(true);
if (DEBUG) {
- Slog.d(TAG, "Iterating over " + users.size() + " profiles.");
+ Slog.d(TAG, "Iterating over " + users.size() + " userHandles.");
}
ParcelFileDescriptor[] fds;
@@ -572,11 +571,11 @@
ProtoOutputStream output = new ProtoOutputStream(fout);
int numRecords = 0;
// Add in all the apps for every user/profile.
- for (UserInfo profile : users) {
+ for (UserHandle userHandle : users) {
List<PackageInfo> pi =
pm.getInstalledPackagesAsUser(PackageManager.MATCH_UNINSTALLED_PACKAGES
| PackageManager.MATCH_ANY_USER,
- profile.id);
+ userHandle.getIdentifier());
for (int j = 0; j < pi.size(); j++) {
if (pi.get(j).applicationInfo != null) {
String installer;
@@ -586,23 +585,24 @@
installer = "";
}
long applicationInfoToken =
- output.start(ProtoStream.FIELD_TYPE_MESSAGE
- | ProtoStream.FIELD_COUNT_REPEATED
+ output.start(ProtoOutputStream.FIELD_TYPE_MESSAGE
+ | ProtoOutputStream.FIELD_COUNT_REPEATED
| APPLICATION_INFO_FIELD_ID);
- output.write(ProtoStream.FIELD_TYPE_INT32
- | ProtoStream.FIELD_COUNT_SINGLE | UID_FIELD_ID,
+ output.write(ProtoOutputStream.FIELD_TYPE_INT32
+ | ProtoOutputStream.FIELD_COUNT_SINGLE | UID_FIELD_ID,
pi.get(j).applicationInfo.uid);
- output.write(ProtoStream.FIELD_TYPE_INT64
- | ProtoStream.FIELD_COUNT_SINGLE
+ output.write(ProtoOutputStream.FIELD_TYPE_INT64
+ | ProtoOutputStream.FIELD_COUNT_SINGLE
| VERSION_FIELD_ID, pi.get(j).getLongVersionCode());
- output.write(ProtoStream.FIELD_TYPE_STRING
- | ProtoStream.FIELD_COUNT_SINGLE | VERSION_STRING_FIELD_ID,
+ output.write(ProtoOutputStream.FIELD_TYPE_STRING
+ | ProtoOutputStream.FIELD_COUNT_SINGLE
+ | VERSION_STRING_FIELD_ID,
pi.get(j).versionName);
- output.write(ProtoStream.FIELD_TYPE_STRING
- | ProtoStream.FIELD_COUNT_SINGLE
+ output.write(ProtoOutputStream.FIELD_TYPE_STRING
+ | ProtoOutputStream.FIELD_COUNT_SINGLE
| PACKAGE_NAME_FIELD_ID, pi.get(j).packageName);
- output.write(ProtoStream.FIELD_TYPE_STRING
- | ProtoStream.FIELD_COUNT_SINGLE
+ output.write(ProtoOutputStream.FIELD_TYPE_STRING
+ | ProtoOutputStream.FIELD_COUNT_SINGLE
| INSTALLER_FIELD_ID,
installer == null ? "" : installer);
numRecords++;
diff --git a/api/current.txt b/api/current.txt
index 39d5263..86aa80b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -99,6 +99,7 @@
field public static final String MOUNT_FORMAT_FILESYSTEMS = "android.permission.MOUNT_FORMAT_FILESYSTEMS";
field public static final String MOUNT_UNMOUNT_FILESYSTEMS = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS";
field public static final String NFC = "android.permission.NFC";
+ field public static final String NFC_PREFERRED_PAYMENT_INFO = "android.permission.NFC_PREFERRED_PAYMENT_INFO";
field public static final String NFC_TRANSACTION_EVENT = "android.permission.NFC_TRANSACTION_EVENT";
field public static final String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS";
field @Deprecated public static final String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
@@ -4308,7 +4309,7 @@
method public static String permissionToOp(String);
method public void setNotedAppOpsCollector(@Nullable android.app.AppOpsManager.AppOpsCollector);
method @Deprecated public int startOp(@NonNull String, int, @NonNull String);
- method public int startOp(@NonNull String, int, @Nullable String, @NonNull String, @Nullable String);
+ method public int startOp(@NonNull String, int, @Nullable String, @Nullable String, @Nullable String);
method @Deprecated public int startOpNoThrow(@NonNull String, int, @NonNull String);
method public int startOpNoThrow(@NonNull String, int, @NonNull String, @NonNull String, @Nullable String);
method public void startWatchingActive(@NonNull String[], @NonNull java.util.concurrent.Executor, @NonNull android.app.AppOpsManager.OnOpActiveChangedListener);
@@ -19617,6 +19618,197 @@
}
+package android.icu.number {
+
+ public class CompactNotation extends android.icu.number.Notation {
+ }
+
+ public abstract class CurrencyPrecision extends android.icu.number.Precision {
+ method public android.icu.number.Precision withCurrency(android.icu.util.Currency);
+ }
+
+ public class FormattedNumber implements java.lang.CharSequence {
+ method public char charAt(int);
+ method public int length();
+ method public CharSequence subSequence(int, int);
+ method public java.math.BigDecimal toBigDecimal();
+ method public java.text.AttributedCharacterIterator toCharacterIterator();
+ }
+
+ public class FormattedNumberRange implements java.lang.CharSequence {
+ method public char charAt(int);
+ method public java.math.BigDecimal getFirstBigDecimal();
+ method public android.icu.number.NumberRangeFormatter.RangeIdentityResult getIdentityResult();
+ method public java.math.BigDecimal getSecondBigDecimal();
+ method public int length();
+ method public CharSequence subSequence(int, int);
+ method public java.text.AttributedCharacterIterator toCharacterIterator();
+ }
+
+ public abstract class FractionPrecision extends android.icu.number.Precision {
+ method public android.icu.number.Precision withMaxDigits(int);
+ method public android.icu.number.Precision withMinDigits(int);
+ }
+
+ public class IntegerWidth {
+ method public android.icu.number.IntegerWidth truncateAt(int);
+ method public static android.icu.number.IntegerWidth zeroFillTo(int);
+ }
+
+ public class LocalizedNumberFormatter extends android.icu.number.NumberFormatterSettings<android.icu.number.LocalizedNumberFormatter> {
+ method public android.icu.number.FormattedNumber format(long);
+ method public android.icu.number.FormattedNumber format(double);
+ method public android.icu.number.FormattedNumber format(Number);
+ method public android.icu.number.FormattedNumber format(android.icu.util.Measure);
+ method public java.text.Format toFormat();
+ }
+
+ public class LocalizedNumberRangeFormatter extends android.icu.number.NumberRangeFormatterSettings<android.icu.number.LocalizedNumberRangeFormatter> {
+ method public android.icu.number.FormattedNumberRange formatRange(int, int);
+ method public android.icu.number.FormattedNumberRange formatRange(double, double);
+ method public android.icu.number.FormattedNumberRange formatRange(Number, Number);
+ }
+
+ public class Notation {
+ method public static android.icu.number.CompactNotation compactLong();
+ method public static android.icu.number.CompactNotation compactShort();
+ method public static android.icu.number.ScientificNotation engineering();
+ method public static android.icu.number.ScientificNotation scientific();
+ method public static android.icu.number.SimpleNotation simple();
+ }
+
+ public final class NumberFormatter {
+ method public static android.icu.number.UnlocalizedNumberFormatter with();
+ method public static android.icu.number.LocalizedNumberFormatter withLocale(java.util.Locale);
+ method public static android.icu.number.LocalizedNumberFormatter withLocale(android.icu.util.ULocale);
+ }
+
+ public enum NumberFormatter.DecimalSeparatorDisplay {
+ enum_constant public static final android.icu.number.NumberFormatter.DecimalSeparatorDisplay ALWAYS;
+ enum_constant public static final android.icu.number.NumberFormatter.DecimalSeparatorDisplay AUTO;
+ }
+
+ public enum NumberFormatter.GroupingStrategy {
+ enum_constant public static final android.icu.number.NumberFormatter.GroupingStrategy AUTO;
+ enum_constant public static final android.icu.number.NumberFormatter.GroupingStrategy MIN2;
+ enum_constant public static final android.icu.number.NumberFormatter.GroupingStrategy OFF;
+ enum_constant public static final android.icu.number.NumberFormatter.GroupingStrategy ON_ALIGNED;
+ enum_constant public static final android.icu.number.NumberFormatter.GroupingStrategy THOUSANDS;
+ }
+
+ public enum NumberFormatter.SignDisplay {
+ enum_constant public static final android.icu.number.NumberFormatter.SignDisplay ACCOUNTING;
+ enum_constant public static final android.icu.number.NumberFormatter.SignDisplay ACCOUNTING_ALWAYS;
+ enum_constant public static final android.icu.number.NumberFormatter.SignDisplay ACCOUNTING_EXCEPT_ZERO;
+ enum_constant public static final android.icu.number.NumberFormatter.SignDisplay ALWAYS;
+ enum_constant public static final android.icu.number.NumberFormatter.SignDisplay AUTO;
+ enum_constant public static final android.icu.number.NumberFormatter.SignDisplay EXCEPT_ZERO;
+ enum_constant public static final android.icu.number.NumberFormatter.SignDisplay NEVER;
+ }
+
+ public enum NumberFormatter.UnitWidth {
+ enum_constant public static final android.icu.number.NumberFormatter.UnitWidth FULL_NAME;
+ enum_constant public static final android.icu.number.NumberFormatter.UnitWidth HIDDEN;
+ enum_constant public static final android.icu.number.NumberFormatter.UnitWidth ISO_CODE;
+ enum_constant public static final android.icu.number.NumberFormatter.UnitWidth NARROW;
+ enum_constant public static final android.icu.number.NumberFormatter.UnitWidth SHORT;
+ }
+
+ public abstract class NumberFormatterSettings<T extends android.icu.number.NumberFormatterSettings<?>> {
+ method public T decimal(android.icu.number.NumberFormatter.DecimalSeparatorDisplay);
+ method public T grouping(android.icu.number.NumberFormatter.GroupingStrategy);
+ method public T integerWidth(android.icu.number.IntegerWidth);
+ method public T notation(android.icu.number.Notation);
+ method public T perUnit(android.icu.util.MeasureUnit);
+ method public T precision(android.icu.number.Precision);
+ method public T roundingMode(java.math.RoundingMode);
+ method public T scale(android.icu.number.Scale);
+ method public T sign(android.icu.number.NumberFormatter.SignDisplay);
+ method public T symbols(android.icu.text.DecimalFormatSymbols);
+ method public T symbols(android.icu.text.NumberingSystem);
+ method public T unit(android.icu.util.MeasureUnit);
+ method public T unitWidth(android.icu.number.NumberFormatter.UnitWidth);
+ }
+
+ public abstract class NumberRangeFormatter {
+ method public static android.icu.number.UnlocalizedNumberRangeFormatter with();
+ method public static android.icu.number.LocalizedNumberRangeFormatter withLocale(java.util.Locale);
+ method public static android.icu.number.LocalizedNumberRangeFormatter withLocale(android.icu.util.ULocale);
+ }
+
+ public enum NumberRangeFormatter.RangeCollapse {
+ enum_constant public static final android.icu.number.NumberRangeFormatter.RangeCollapse ALL;
+ enum_constant public static final android.icu.number.NumberRangeFormatter.RangeCollapse AUTO;
+ enum_constant public static final android.icu.number.NumberRangeFormatter.RangeCollapse NONE;
+ enum_constant public static final android.icu.number.NumberRangeFormatter.RangeCollapse UNIT;
+ }
+
+ public enum NumberRangeFormatter.RangeIdentityFallback {
+ enum_constant public static final android.icu.number.NumberRangeFormatter.RangeIdentityFallback APPROXIMATELY;
+ enum_constant public static final android.icu.number.NumberRangeFormatter.RangeIdentityFallback APPROXIMATELY_OR_SINGLE_VALUE;
+ enum_constant public static final android.icu.number.NumberRangeFormatter.RangeIdentityFallback RANGE;
+ enum_constant public static final android.icu.number.NumberRangeFormatter.RangeIdentityFallback SINGLE_VALUE;
+ }
+
+ public enum NumberRangeFormatter.RangeIdentityResult {
+ enum_constant public static final android.icu.number.NumberRangeFormatter.RangeIdentityResult EQUAL_AFTER_ROUNDING;
+ enum_constant public static final android.icu.number.NumberRangeFormatter.RangeIdentityResult EQUAL_BEFORE_ROUNDING;
+ enum_constant public static final android.icu.number.NumberRangeFormatter.RangeIdentityResult NOT_EQUAL;
+ }
+
+ public abstract class NumberRangeFormatterSettings<T extends android.icu.number.NumberRangeFormatterSettings<?>> {
+ method public T collapse(android.icu.number.NumberRangeFormatter.RangeCollapse);
+ method public T identityFallback(android.icu.number.NumberRangeFormatter.RangeIdentityFallback);
+ method public T numberFormatterBoth(android.icu.number.UnlocalizedNumberFormatter);
+ method public T numberFormatterFirst(android.icu.number.UnlocalizedNumberFormatter);
+ method public T numberFormatterSecond(android.icu.number.UnlocalizedNumberFormatter);
+ }
+
+ public abstract class Precision implements java.lang.Cloneable {
+ method public Object clone();
+ method public static android.icu.number.CurrencyPrecision currency(android.icu.util.Currency.CurrencyUsage);
+ method public static android.icu.number.FractionPrecision fixedFraction(int);
+ method public static android.icu.number.Precision fixedSignificantDigits(int);
+ method public static android.icu.number.Precision increment(java.math.BigDecimal);
+ method public static android.icu.number.FractionPrecision integer();
+ method public static android.icu.number.FractionPrecision maxFraction(int);
+ method public static android.icu.number.Precision maxSignificantDigits(int);
+ method public static android.icu.number.FractionPrecision minFraction(int);
+ method public static android.icu.number.FractionPrecision minMaxFraction(int, int);
+ method public static android.icu.number.Precision minMaxSignificantDigits(int, int);
+ method public static android.icu.number.Precision minSignificantDigits(int);
+ method public static android.icu.number.Precision unlimited();
+ }
+
+ public class Scale {
+ method public static android.icu.number.Scale byBigDecimal(java.math.BigDecimal);
+ method public static android.icu.number.Scale byDouble(double);
+ method public static android.icu.number.Scale byDoubleAndPowerOfTen(double, int);
+ method public static android.icu.number.Scale none();
+ method public static android.icu.number.Scale powerOfTen(int);
+ }
+
+ public class ScientificNotation extends android.icu.number.Notation implements java.lang.Cloneable {
+ method public Object clone();
+ method public android.icu.number.ScientificNotation withExponentSignDisplay(android.icu.number.NumberFormatter.SignDisplay);
+ method public android.icu.number.ScientificNotation withMinExponentDigits(int);
+ }
+
+ public class SimpleNotation extends android.icu.number.Notation {
+ }
+
+ public class UnlocalizedNumberFormatter extends android.icu.number.NumberFormatterSettings<android.icu.number.UnlocalizedNumberFormatter> {
+ method public android.icu.number.LocalizedNumberFormatter locale(java.util.Locale);
+ method public android.icu.number.LocalizedNumberFormatter locale(android.icu.util.ULocale);
+ }
+
+ public class UnlocalizedNumberRangeFormatter extends android.icu.number.NumberRangeFormatterSettings<android.icu.number.UnlocalizedNumberRangeFormatter> {
+ method public android.icu.number.LocalizedNumberRangeFormatter locale(java.util.Locale);
+ method public android.icu.number.LocalizedNumberRangeFormatter locale(android.icu.util.ULocale);
+ }
+
+}
+
package android.icu.text {
public final class AlphabeticIndex<V> implements java.lang.Iterable<android.icu.text.AlphabeticIndex.Bucket<V>> {
@@ -22131,6 +22323,7 @@
field public static final android.icu.util.MeasureUnit ARC_MINUTE;
field public static final android.icu.util.MeasureUnit ARC_SECOND;
field public static final android.icu.util.MeasureUnit ASTRONOMICAL_UNIT;
+ field public static final android.icu.util.MeasureUnit ATMOSPHERE;
field public static final android.icu.util.MeasureUnit BIT;
field public static final android.icu.util.MeasureUnit BUSHEL;
field public static final android.icu.util.MeasureUnit BYTE;
@@ -22232,6 +22425,9 @@
field public static final android.icu.util.MeasureUnit OUNCE_TROY;
field public static final android.icu.util.MeasureUnit PARSEC;
field public static final android.icu.util.MeasureUnit PART_PER_MILLION;
+ field public static final android.icu.util.MeasureUnit PERCENT;
+ field public static final android.icu.util.MeasureUnit PERMILLE;
+ field public static final android.icu.util.MeasureUnit PETABYTE;
field public static final android.icu.util.MeasureUnit PICOMETER;
field public static final android.icu.util.MeasureUnit PINT;
field public static final android.icu.util.MeasureUnit PINT_METRIC;
@@ -23240,10 +23436,10 @@
}
public interface LocationListener {
- method public void onLocationChanged(android.location.Location);
- method public void onProviderDisabled(String);
- method public void onProviderEnabled(String);
- method @Deprecated public void onStatusChanged(String, int, android.os.Bundle);
+ method public void onLocationChanged(@NonNull android.location.Location);
+ method public default void onProviderDisabled(@NonNull String);
+ method public default void onProviderEnabled(@NonNull String);
+ method @Deprecated public default void onStatusChanged(String, int, android.os.Bundle);
}
public class LocationManager {
@@ -30417,8 +30613,11 @@
method public int getMaxMatchFilterLength();
method public int getMaxServiceNameLength();
method public int getMaxServiceSpecificInfoLength();
+ method public int getSupportedCipherSuites();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.Characteristics> CREATOR;
+ field public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_128 = 1; // 0x1
+ field public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_256 = 2; // 0x2
}
public class DiscoverySession implements java.lang.AutoCloseable {
@@ -31130,6 +31329,7 @@
method @Deprecated public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...);
field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
field public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
+ field @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static final String ACTION_PREFERRED_PAYMENT_CHANGED = "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
field public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
field public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
field @RequiresPermission(android.Manifest.permission.NFC_TRANSACTION_EVENT) public static final String ACTION_TRANSACTION_DETECTED = "android.nfc.action.TRANSACTION_DETECTED";
@@ -31138,6 +31338,7 @@
field public static final String EXTRA_DATA = "android.nfc.extra.DATA";
field public static final String EXTRA_ID = "android.nfc.extra.ID";
field public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
+ field public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON = "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
field public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
field public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME";
field public static final String EXTRA_TAG = "android.nfc.extra.TAG";
@@ -31148,6 +31349,9 @@
field public static final int FLAG_READER_NFC_V = 8; // 0x8
field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100
field public static final int FLAG_READER_SKIP_NDEF_CHECK = 128; // 0x80
+ field public static final int PREFERRED_PAYMENT_CHANGED = 2; // 0x2
+ field public static final int PREFERRED_PAYMENT_LOADED = 1; // 0x1
+ field public static final int PREFERRED_PAYMENT_UPDATED = 3; // 0x3
field public static final int STATE_OFF = 1; // 0x1
field public static final int STATE_ON = 3; // 0x3
field public static final int STATE_TURNING_OFF = 4; // 0x4
@@ -31203,8 +31407,11 @@
public final class CardEmulation {
method public boolean categoryAllowsForegroundPreference(String);
+ method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService();
method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String);
+ method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getDescriptionForPreferredPaymentService();
method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
+ method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService();
method public int getSelectionModeForCategory(String);
method public boolean isDefaultServiceForAid(android.content.ComponentName, String);
method public boolean isDefaultServiceForCategory(android.content.ComponentName, String);
@@ -35442,11 +35649,12 @@
method public boolean isIgnoringBatteryOptimizations(String);
method public boolean isInteractive();
method public boolean isPowerSaveMode();
+ method public boolean isRebootingUserspaceSupported();
method @Deprecated public boolean isScreenOn();
method public boolean isSustainedPerformanceModeSupported();
method public boolean isWakeLockLevelSupported(int);
method public android.os.PowerManager.WakeLock newWakeLock(int, String);
- method public void reboot(String);
+ method public void reboot(@Nullable String);
method public void removeThermalStatusListener(@NonNull android.os.PowerManager.OnThermalStatusChangedListener);
field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000
field public static final String ACTION_DEVICE_IDLE_MODE_CHANGED = "android.os.action.DEVICE_IDLE_MODE_CHANGED";
@@ -39060,6 +39268,8 @@
field public static final String GENRE = "genre";
field public static final String HEIGHT = "height";
field public static final String INSTANCE_ID = "instance_id";
+ field public static final String IS_DOWNLOAD = "is_download";
+ field public static final String IS_DRM = "is_drm";
field public static final String IS_FAVORITE = "is_favorite";
field public static final String IS_PENDING = "is_pending";
field public static final String IS_TRASHED = "is_trashed";
@@ -44839,6 +45049,11 @@
field public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
}
+ public static final class CarrierConfigManager.Gps {
+ field public static final String KEY_PERSIST_LPP_MODE_BOOL = "gps.persist_lpp_mode_bool";
+ field public static final String KEY_PREFIX = "gps.";
+ }
+
public static final class CarrierConfigManager.Ims {
field public static final String KEY_PREFIX = "ims.";
}
@@ -49475,6 +49690,71 @@
}
+package android.util.proto {
+
+ public final class ProtoOutputStream {
+ ctor public ProtoOutputStream();
+ ctor public ProtoOutputStream(int);
+ ctor public ProtoOutputStream(@NonNull java.io.OutputStream);
+ method public static int checkFieldId(long, long);
+ method public void dump(@NonNull String);
+ method public void end(long);
+ method public void flush();
+ method @NonNull public byte[] getBytes();
+ method @Nullable public static String getFieldCountString(long);
+ method @NonNull public static String getFieldIdString(long);
+ method @Nullable public static String getFieldTypeString(long);
+ method public int getRawSize();
+ method @Nullable public static String getWireTypeString(int);
+ method public static long makeFieldId(int, long);
+ method public static long makeToken(int, boolean, int, int, int);
+ method public long start(long);
+ method @NonNull public static String token2String(long);
+ method public void write(long, double);
+ method public void write(long, float);
+ method public void write(long, int);
+ method public void write(long, long);
+ method public void write(long, boolean);
+ method public void write(long, @Nullable String);
+ method public void write(long, @Nullable byte[]);
+ method public void writeTag(int, int);
+ field public static final long FIELD_COUNT_MASK = 16492674416640L; // 0xf0000000000L
+ field public static final long FIELD_COUNT_PACKED = 5497558138880L; // 0x50000000000L
+ field public static final long FIELD_COUNT_REPEATED = 2199023255552L; // 0x20000000000L
+ field public static final int FIELD_COUNT_SHIFT = 40; // 0x28
+ field public static final long FIELD_COUNT_SINGLE = 1099511627776L; // 0x10000000000L
+ field public static final long FIELD_COUNT_UNKNOWN = 0L; // 0x0L
+ field public static final int FIELD_ID_SHIFT = 3; // 0x3
+ field public static final long FIELD_TYPE_BOOL = 34359738368L; // 0x800000000L
+ field public static final long FIELD_TYPE_BYTES = 51539607552L; // 0xc00000000L
+ field public static final long FIELD_TYPE_DOUBLE = 4294967296L; // 0x100000000L
+ field public static final long FIELD_TYPE_ENUM = 60129542144L; // 0xe00000000L
+ field public static final long FIELD_TYPE_FIXED32 = 30064771072L; // 0x700000000L
+ field public static final long FIELD_TYPE_FIXED64 = 25769803776L; // 0x600000000L
+ field public static final long FIELD_TYPE_FLOAT = 8589934592L; // 0x200000000L
+ field public static final long FIELD_TYPE_INT32 = 21474836480L; // 0x500000000L
+ field public static final long FIELD_TYPE_INT64 = 12884901888L; // 0x300000000L
+ field public static final long FIELD_TYPE_MASK = 1095216660480L; // 0xff00000000L
+ field public static final long FIELD_TYPE_MESSAGE = 47244640256L; // 0xb00000000L
+ field public static final long FIELD_TYPE_SFIXED32 = 64424509440L; // 0xf00000000L
+ field public static final long FIELD_TYPE_SFIXED64 = 68719476736L; // 0x1000000000L
+ field public static final int FIELD_TYPE_SHIFT = 32; // 0x20
+ field public static final long FIELD_TYPE_SINT32 = 73014444032L; // 0x1100000000L
+ field public static final long FIELD_TYPE_SINT64 = 77309411328L; // 0x1200000000L
+ field public static final long FIELD_TYPE_STRING = 38654705664L; // 0x900000000L
+ field public static final long FIELD_TYPE_UINT32 = 55834574848L; // 0xd00000000L
+ field public static final long FIELD_TYPE_UINT64 = 17179869184L; // 0x400000000L
+ field public static final int WIRE_TYPE_END_GROUP = 4; // 0x4
+ field public static final int WIRE_TYPE_FIXED32 = 5; // 0x5
+ field public static final int WIRE_TYPE_FIXED64 = 1; // 0x1
+ field public static final int WIRE_TYPE_LENGTH_DELIMITED = 2; // 0x2
+ field public static final int WIRE_TYPE_MASK = 7; // 0x7
+ field public static final int WIRE_TYPE_START_GROUP = 3; // 0x3
+ field public static final int WIRE_TYPE_VARINT = 0; // 0x0
+ }
+
+}
+
package android.view {
public abstract class AbsSavedState implements android.os.Parcelable {
diff --git a/api/lint-baseline.txt b/api/lint-baseline.txt
index 4a37e67..508718e 100644
--- a/api/lint-baseline.txt
+++ b/api/lint-baseline.txt
@@ -527,6 +527,14 @@
MissingNullability: android.icu.text.DateTimePatternGenerator#getFieldDisplayName(int, android.icu.text.DateTimePatternGenerator.DisplayWidth) parameter #1:
+MissingNullability: android.icu.util.MeasureUnit#ATMOSPHERE:
+ Missing nullability on field `ATMOSPHERE` in class `class android.icu.util.MeasureUnit`
+MissingNullability: android.icu.util.MeasureUnit#PERCENT:
+ Missing nullability on field `PERCENT` in class `class android.icu.util.MeasureUnit`
+MissingNullability: android.icu.util.MeasureUnit#PERMILLE:
+ Missing nullability on field `PERMILLE` in class `class android.icu.util.MeasureUnit`
+MissingNullability: android.icu.util.MeasureUnit#PETABYTE:
+ Missing nullability on field `PETABYTE` in class `class android.icu.util.MeasureUnit`
MissingNullability: android.icu.util.VersionInfo#UNICODE_12_0:
MissingNullability: android.icu.util.VersionInfo#UNICODE_12_1:
diff --git a/api/system-current.txt b/api/system-current.txt
index d67305d..2d0213f 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -15,6 +15,7 @@
field public static final String ACCESS_SHARED_LIBRARIES = "android.permission.ACCESS_SHARED_LIBRARIES";
field public static final String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS";
field public static final String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
+ field public static final String ACCESS_TV_TUNER = "android.permission.ACCESS_TV_TUNER";
field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
field public static final String ADJUST_RUNTIME_PERMISSIONS_POLICY = "android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY";
field public static final String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
@@ -365,6 +366,7 @@
field public static final String OPSTR_GPS = "android:gps";
field public static final String OPSTR_INSTANT_APP_START_FOREGROUND = "android:instant_app_start_foreground";
field public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
+ field public static final String OPSTR_MANAGE_EXTERNAL_STORAGE = "android:manage_external_storage";
field public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
field public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
field public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
@@ -473,15 +475,20 @@
public static final class AppOpsManager.OpEntry implements android.os.Parcelable {
method public int describeContents();
- method public long getDuration();
+ method @Deprecated public long getDuration();
method @NonNull public java.util.Map<java.lang.String,android.app.AppOpsManager.OpFeatureEntry> getFeatures();
method public long getLastAccessBackgroundTime(int);
method public long getLastAccessForegroundTime(int);
method public long getLastAccessTime(int);
method public long getLastAccessTime(int, int, int);
method public long getLastBackgroundDuration(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastBackgroundProxyInfo(int);
+ method public long getLastDuration(int);
method public long getLastDuration(int, int, int);
method public long getLastForegroundDuration(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastForegroundProxyInfo(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int, int, int);
method public long getLastRejectBackgroundTime(int);
method public long getLastRejectForegroundTime(int);
method public long getLastRejectTime(int);
@@ -489,34 +496,44 @@
method public int getMode();
method @NonNull public String getOpStr();
method @Deprecated @Nullable public String getProxyPackageName();
- method @Nullable public String getProxyPackageName(int, int);
+ method @Deprecated @Nullable public String getProxyPackageName(int, int);
method @Deprecated public int getProxyUid();
- method public int getProxyUid(int, int);
+ method @Deprecated public int getProxyUid(int, int);
method public boolean isRunning();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.OpEntry> CREATOR;
}
- public static final class AppOpsManager.OpFeatureEntry {
- method public long getDuration();
+ public static final class AppOpsManager.OpEventProxyInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public String getFeatureId();
+ method @Nullable public String getPackageName();
+ method @IntRange(from=0) public int getUid();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.OpEventProxyInfo> CREATOR;
+ }
+
+ public static final class AppOpsManager.OpFeatureEntry implements android.os.Parcelable {
+ method public int describeContents();
method public long getLastAccessBackgroundTime(int);
method public long getLastAccessForegroundTime(int);
method public long getLastAccessTime(int);
method public long getLastAccessTime(int, int, int);
method public long getLastBackgroundDuration(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastBackgroundProxyInfo(int);
+ method public long getLastDuration(int);
method public long getLastDuration(int, int, int);
method public long getLastForegroundDuration(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastForegroundProxyInfo(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int, int, int);
method public long getLastRejectBackgroundTime(int);
method public long getLastRejectForegroundTime(int);
method public long getLastRejectTime(int);
method public long getLastRejectTime(int, int, int);
- method @Nullable public String getProxyFeatureId();
- method @Nullable public String getProxyFeatureId(int, int);
- method @Nullable public String getProxyPackageName();
- method @Nullable public String getProxyPackageName(int, int);
- method public int getProxyUid();
- method public int getProxyUid(int, int);
method public boolean isRunning();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.OpFeatureEntry> CREATOR;
}
public static final class AppOpsManager.PackageOps implements android.os.Parcelable {
@@ -524,7 +541,7 @@
method @NonNull public java.util.List<android.app.AppOpsManager.OpEntry> getOps();
method @NonNull public String getPackageName();
method public int getUid();
- method public void writeToParcel(android.os.Parcel, int);
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.PackageOps> CREATOR;
}
@@ -1653,6 +1670,7 @@
field public static final String SYSTEM_UPDATE_SERVICE = "system_update";
field public static final String TELEPHONY_IMS_SERVICE = "telephony_ims";
field public static final String TELEPHONY_REGISTRY_SERVICE = "telephony_registry";
+ field public static final String TETHERING_SERVICE = "tethering";
field public static final String VR_SERVICE = "vrmanager";
field @Deprecated public static final String WIFI_RTT_SERVICE = "rttmanager";
field public static final String WIFI_SCANNING_SERVICE = "wifiscanner";
@@ -1915,6 +1933,13 @@
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_PROFILES) public void startActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
}
+ public class DataLoaderParams {
+ ctor public DataLoaderParams(@NonNull String, @NonNull String, @Nullable java.util.Map<java.lang.String,android.os.ParcelFileDescriptor>);
+ method @NonNull public final java.util.Map<java.lang.String,android.os.ParcelFileDescriptor> getDynamicArgs();
+ method @NonNull public final String getPackageName();
+ method @NonNull public final String getStaticArgs();
+ }
+
public final class InstantAppInfo implements android.os.Parcelable {
ctor public InstantAppInfo(android.content.pm.ApplicationInfo, String[], String[]);
ctor public InstantAppInfo(String, CharSequence, String[], String[]);
@@ -2004,6 +2029,7 @@
}
public static class PackageInstaller.Session implements java.io.Closeable {
+ method public void addFile(@NonNull String, long, @NonNull byte[]);
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void commitTransferred(@NonNull android.content.IntentSender);
}
@@ -2017,6 +2043,7 @@
method public boolean getInstallAsInstantApp(boolean);
method public boolean getInstallAsVirtualPreload();
method public boolean getRequestDowngrade();
+ method public int getRollbackDataPolicy();
method @NonNull public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions();
}
@@ -2025,7 +2052,9 @@
method @Deprecated public void setAllowDowngrade(boolean);
method public void setDontKillApp(boolean);
method public void setEnableRollback(boolean);
+ method public void setEnableRollback(boolean, int);
method @RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS) public void setGrantedRuntimePermissions(String[]);
+ method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setIncrementalParams(@NonNull android.content.pm.DataLoaderParams);
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex();
method public void setInstallAsInstantApp(boolean);
method public void setInstallAsVirtualPreload();
@@ -2088,6 +2117,7 @@
field public static final int FLAG_PERMISSION_APPLY_RESTRICTION = 16384; // 0x4000
field public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 32; // 0x20
field public static final int FLAG_PERMISSION_GRANTED_BY_ROLE = 32768; // 0x8000
+ field public static final int FLAG_PERMISSION_ONE_TIME = 65536; // 0x10000
field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4
field public static final int FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT = 2048; // 0x800
field public static final int FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT = 4096; // 0x1000
@@ -2162,7 +2192,7 @@
method public void onPermissionsChanged(int);
}
- @IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags {
+ @IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags {
}
public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -2175,6 +2205,7 @@
public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
field public static final int FLAG_REMOVED = 2; // 0x2
field public static final int PROTECTION_FLAG_APP_PREDICTOR = 2097152; // 0x200000
+ field public static final int PROTECTION_FLAG_COMPANION = 8388608; // 0x800000
field public static final int PROTECTION_FLAG_CONFIGURATOR = 524288; // 0x80000
field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000
field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000
@@ -4015,6 +4046,7 @@
field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1
field public static final int AUDIOFOCUS_FLAG_LOCK = 4; // 0x4
field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
+ field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int STREAM_ASSISTANT = 11; // 0xb
field public static final int SUCCESS = 0; // 0x0
}
@@ -4477,6 +4509,24 @@
}
+package android.media.tv.tuner {
+
+ public abstract class FrontendSettings {
+ method public final int getFrequency();
+ method public abstract int getType();
+ }
+
+ public final class Tuner implements java.lang.AutoCloseable {
+ ctor public Tuner(@NonNull android.content.Context);
+ method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.Tuner.Descrambler openDescrambler();
+ method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int tune(@NonNull android.media.tv.tuner.FrontendSettings);
+ }
+
+ public class Tuner.Descrambler {
+ }
+
+}
+
package android.metrics {
public class LogMaker {
@@ -6208,6 +6258,130 @@
}
+package android.net.wifi.wificond {
+
+ public final class NativeScanResult implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public byte[] getBssid();
+ method @NonNull public java.util.BitSet getCapabilities();
+ method public int getFrequencyMhz();
+ method @NonNull public byte[] getInformationElements();
+ method @NonNull public java.util.List<android.net.wifi.wificond.RadioChainInfo> getRadioChainInfos();
+ method public int getSignalMbm();
+ method @NonNull public byte[] getSsid();
+ method public long getTsf();
+ method public boolean isAssociated();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.wificond.NativeScanResult> CREATOR;
+ }
+
+ public final class NativeWifiClient implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.wificond.NativeWifiClient> CREATOR;
+ field @NonNull public final byte[] macAddress;
+ }
+
+ public final class PnoNetwork implements android.os.Parcelable {
+ ctor public PnoNetwork();
+ method public int describeContents();
+ method @NonNull public int[] getFrequenciesMhz();
+ method @NonNull public byte[] getSsid();
+ method public boolean isHidden();
+ method public void setFrequenciesMhz(@NonNull int[]);
+ method public void setHidden(boolean);
+ method public void setSsid(@NonNull byte[]);
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.wificond.PnoNetwork> CREATOR;
+ }
+
+ public final class PnoSettings implements android.os.Parcelable {
+ ctor public PnoSettings();
+ method public int describeContents();
+ method public int getIntervalMillis();
+ method public int getMin2gRssiDbm();
+ method public int getMin5gRssiDbm();
+ method public int getMin6gRssiDbm();
+ method @NonNull public java.util.List<android.net.wifi.wificond.PnoNetwork> getPnoNetworks();
+ method public void setIntervalMillis(int);
+ method public void setMin2gRssiDbm(int);
+ method public void setMin5gRssiDbm(int);
+ method public void setMin6gRssiDbm(int);
+ method public void setPnoNetworks(@NonNull java.util.List<android.net.wifi.wificond.PnoNetwork>);
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.wificond.PnoSettings> CREATOR;
+ }
+
+ public final class RadioChainInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getChainId();
+ method public int getLevelDbm();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.wificond.RadioChainInfo> CREATOR;
+ }
+
+ public class WifiCondManager {
+ method public void abortScan(@NonNull String);
+ method public void enableVerboseLogging(boolean);
+ method @NonNull public int[] getChannelsMhzForBand(int);
+ method @NonNull public java.util.List<android.net.wifi.wificond.NativeScanResult> getScanResults(@NonNull String, int);
+ method @Nullable public android.net.wifi.wificond.WifiCondManager.TxPacketCounters getTxPacketCounters(@NonNull String);
+ method public boolean initialize(@NonNull Runnable);
+ method public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.wificond.WifiCondManager.SoftApCallback);
+ method public void sendMgmtFrame(@NonNull String, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.wificond.WifiCondManager.SendMgmtFrameCallback);
+ method public boolean setupInterfaceForClientMode(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.wificond.WifiCondManager.ScanEventCallback, @NonNull android.net.wifi.wificond.WifiCondManager.ScanEventCallback);
+ method public boolean setupInterfaceForSoftApMode(@NonNull String);
+ method @Nullable public android.net.wifi.wificond.WifiCondManager.SignalPollResult signalPoll(@NonNull String);
+ method public boolean startPnoScan(@NonNull String, @NonNull android.net.wifi.wificond.PnoSettings, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.wificond.WifiCondManager.PnoScanRequestCallback);
+ method public boolean startScan(@NonNull String, int, @Nullable java.util.Set<java.lang.Integer>, @Nullable java.util.List<byte[]>);
+ method public boolean stopPnoScan(@NonNull String);
+ method public boolean tearDownClientInterface(@NonNull String);
+ method public boolean tearDownInterfaces();
+ method public boolean tearDownSoftApInterface(@NonNull String);
+ field public static final int SCAN_TYPE_PNO_SCAN = 1; // 0x1
+ field public static final int SCAN_TYPE_SINGLE_SCAN = 0; // 0x0
+ field public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5; // 0x5
+ field public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2; // 0x2
+ field public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3; // 0x3
+ field public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4; // 0x4
+ field public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; // 0x1
+ }
+
+ public static interface WifiCondManager.PnoScanRequestCallback {
+ method public void onPnoRequestFailed();
+ method public void onPnoRequestSucceeded();
+ }
+
+ public static interface WifiCondManager.ScanEventCallback {
+ method public void onScanFailed();
+ method public void onScanResultReady();
+ }
+
+ public static interface WifiCondManager.SendMgmtFrameCallback {
+ method public void onAck(int);
+ method public void onFailure(int);
+ }
+
+ public static class WifiCondManager.SignalPollResult {
+ field public final int associationFrequencyMHz;
+ field public final int currentRssiDbm;
+ field public final int rxBitrateMbps;
+ field public final int txBitrateMbps;
+ }
+
+ public static interface WifiCondManager.SoftApCallback {
+ method public void onConnectedClientsChanged(@NonNull android.net.wifi.wificond.NativeWifiClient, boolean);
+ method public void onFailure();
+ method public void onSoftApChannelSwitched(int, int);
+ }
+
+ public static class WifiCondManager.TxPacketCounters {
+ field public final int txPacketFailed;
+ field public final int txPacketSucceeded;
+ }
+
+}
+
package android.nfc {
public final class NfcAdapter {
@@ -6623,6 +6797,7 @@
method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.USER_ACTIVITY}) public void userActivity(long, int, int);
field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1
field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0
+ field public static final String REBOOT_USERSPACE = "userspace";
field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3
field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1
field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0
@@ -6816,6 +6991,7 @@
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isRestrictedProfile();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isRestrictedProfile(@NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isSameProfileGroup(@NonNull android.os.UserHandle, @NonNull android.os.UserHandle);
+ method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}) public boolean isUserNameSet();
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public boolean isUserUnlockingOrUnlocked(@NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean removeUser(@NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(@NonNull android.graphics.Bitmap);
@@ -7015,6 +7191,7 @@
method @BinderThread public abstract void onGetPermissionUsages(boolean, long, @NonNull java.util.function.Consumer<java.util.List<android.permission.RuntimePermissionUsageInfo>>);
method @BinderThread public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream, @NonNull Runnable);
method @BinderThread public abstract void onGrantOrUpgradeDefaultRuntimePermissions(@NonNull Runnable);
+ method @BinderThread public void onOneTimePermissionSessionTimeout(@NonNull String);
method @Deprecated @BinderThread public void onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method @Deprecated @BinderThread public void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable);
method @BinderThread public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String, @NonNull Runnable);
@@ -7031,6 +7208,8 @@
method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS) public void grantDefaultPermissionsToLuiApp(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS) public void revokeDefaultPermissionsFromLuiApps(@NonNull String[], @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public void setRuntimePermissionsVersion(@IntRange(from=0) int);
+ method @RequiresPermission(allOf={android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void startOneTimePermissionSession(@NonNull String, long, int, int);
+ method @RequiresPermission(allOf={android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void stopOneTimePermissionSession(@NonNull String);
}
public static final class PermissionManager.SplitPermissionInfo {
@@ -7272,8 +7451,12 @@
}
public final class MediaStore {
+ method @NonNull public static android.net.Uri rewriteToLegacy(@NonNull android.net.Uri);
method @NonNull public static android.net.Uri scanFile(@NonNull android.content.ContentResolver, @NonNull java.io.File);
method public static void scanVolume(@NonNull android.content.ContentResolver, @NonNull String);
+ method public static void waitForIdle(@NonNull android.content.ContentResolver);
+ field public static final String AUTHORITY_LEGACY = "media_legacy";
+ field @NonNull public static final android.net.Uri AUTHORITY_LEGACY_URI;
}
public abstract class SearchIndexableData {
@@ -7417,6 +7600,7 @@
field public static final String INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS = "install_carrier_app_notification_sleep_millis";
field public static final String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
field public static final String REQUIRE_PASSWORD_TO_DECRYPT = "require_password_to_decrypt";
+ field public static final String TETHER_SUPPORTED = "tether_supported";
field public static final String THEATER_MODE_ON = "theater_mode_on";
field public static final String WEBVIEW_MULTIPROCESS = "webview_multiprocess";
field public static final String WIFI_BADGING_THRESHOLDS = "wifi_badging_thresholds";
@@ -7904,6 +8088,14 @@
}
+package android.service.dataloader {
+
+ public abstract class DataLoaderService extends android.app.Service {
+ ctor public DataLoaderService();
+ }
+
+}
+
package android.service.euicc {
public final class DownloadSubscriptionResult implements android.os.Parcelable {
@@ -8709,6 +8901,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void updateConfigForPhoneId(int, String);
field public static final String KEY_CARRIER_SETUP_APP_STRING = "carrier_setup_app_string";
+ field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
}
public final class CarrierRestrictionRules implements android.os.Parcelable {
@@ -9502,6 +9695,7 @@
}
public class ServiceState implements android.os.Parcelable {
+ method public int getDataRegistrationState();
method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int);
method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList();
method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
@@ -9665,6 +9859,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean);
+ field @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED";
field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
field public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff
field public static final int PROFILE_CLASS_OPERATIONAL = 2; // 0x2
diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt
index 9a635757..da0aae0 100644
--- a/api/system-lint-baseline.txt
+++ b/api/system-lint-baseline.txt
@@ -24,6 +24,11 @@
ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setWifiP2pChannels(android.net.wifi.p2p.WifiP2pManager.Channel, int, int, android.net.wifi.p2p.WifiP2pManager.ActionListener):
Registration methods should have overload that accepts delivery Executor: `setWifiP2pChannels`
+HeavyBitSet: android.net.wifi.wificond.NativeScanResult#getCapabilities():
+ Type must not be heavy BitSet (method android.net.wifi.wificond.NativeScanResult.getCapabilities())
+PairedRegistration: android.net.wifi.wificond.WifiCondManager#registerApCallback(String, java.util.concurrent.Executor, android.net.wifi.wificond.WifiCondManager.SoftApCallback):
+ Found registerApCallback but not unregisterApCallback in android.net.wifi.wificond.WifiCondManager
+
GenericException: android.app.prediction.AppPredictor#finalize():
diff --git a/api/test-current.txt b/api/test-current.txt
index 7deac26..503941c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -158,6 +158,7 @@
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void getHistoricalOpsFromDiskRaw(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
method public static int getNumOps();
method public static String[] getOpStrs();
+ method @NonNull @RequiresPermission("android.permission.GET_APP_OPS_STATS") public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...);
method public boolean isOperationActive(int, int, String);
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void offsetHistory(long);
method public static int opToDefaultMode(@NonNull String);
@@ -308,15 +309,20 @@
public static final class AppOpsManager.OpEntry implements android.os.Parcelable {
method public int describeContents();
- method public long getDuration();
+ method @Deprecated public long getDuration();
method @NonNull public java.util.Map<java.lang.String,android.app.AppOpsManager.OpFeatureEntry> getFeatures();
method public long getLastAccessBackgroundTime(int);
method public long getLastAccessForegroundTime(int);
method public long getLastAccessTime(int);
method public long getLastAccessTime(int, int, int);
method public long getLastBackgroundDuration(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastBackgroundProxyInfo(int);
+ method public long getLastDuration(int);
method public long getLastDuration(int, int, int);
method public long getLastForegroundDuration(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastForegroundProxyInfo(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int, int, int);
method public long getLastRejectBackgroundTime(int);
method public long getLastRejectForegroundTime(int);
method public long getLastRejectTime(int);
@@ -324,34 +330,53 @@
method public int getMode();
method @NonNull public String getOpStr();
method @Deprecated @Nullable public String getProxyPackageName();
- method @Nullable public String getProxyPackageName(int, int);
+ method @Deprecated @Nullable public String getProxyPackageName(int, int);
method @Deprecated public int getProxyUid();
- method public int getProxyUid(int, int);
+ method @Deprecated public int getProxyUid(int, int);
method public boolean isRunning();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.OpEntry> CREATOR;
}
- public static final class AppOpsManager.OpFeatureEntry {
- method public long getDuration();
+ public static final class AppOpsManager.OpEventProxyInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public String getFeatureId();
+ method @Nullable public String getPackageName();
+ method @IntRange(from=0) public int getUid();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.OpEventProxyInfo> CREATOR;
+ }
+
+ public static final class AppOpsManager.OpFeatureEntry implements android.os.Parcelable {
+ method public int describeContents();
method public long getLastAccessBackgroundTime(int);
method public long getLastAccessForegroundTime(int);
method public long getLastAccessTime(int);
method public long getLastAccessTime(int, int, int);
method public long getLastBackgroundDuration(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastBackgroundProxyInfo(int);
+ method public long getLastDuration(int);
method public long getLastDuration(int, int, int);
method public long getLastForegroundDuration(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastForegroundProxyInfo(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int);
+ method @Nullable public android.app.AppOpsManager.OpEventProxyInfo getLastProxyInfo(int, int, int);
method public long getLastRejectBackgroundTime(int);
method public long getLastRejectForegroundTime(int);
method public long getLastRejectTime(int);
method public long getLastRejectTime(int, int, int);
- method @Nullable public String getProxyFeatureId();
- method @Nullable public String getProxyFeatureId(int, int);
- method @Nullable public String getProxyPackageName();
- method @Nullable public String getProxyPackageName(int, int);
- method public int getProxyUid();
- method public int getProxyUid(int, int);
method public boolean isRunning();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.OpFeatureEntry> CREATOR;
+ }
+
+ public static final class AppOpsManager.PackageOps implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public java.util.List<android.app.AppOpsManager.OpEntry> getOps();
+ method @NonNull public String getPackageName();
+ method public int getUid();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.PackageOps> CREATOR;
}
public class DownloadManager {
@@ -753,11 +778,13 @@
}
public static class PackageInstaller.SessionInfo implements android.os.Parcelable {
+ method public int getRollbackDataPolicy();
method @NonNull public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions();
}
public static class PackageInstaller.SessionParams implements android.os.Parcelable {
method public void setEnableRollback(boolean);
+ method public void setEnableRollback(boolean, int);
method @RequiresPermission("android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS") public void setGrantedRuntimePermissions(String[]);
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex();
method public void setInstallerPackageName(@Nullable String);
@@ -813,6 +840,7 @@
public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
field public static final int FLAG_REMOVED = 2; // 0x2
field public static final int PROTECTION_FLAG_APP_PREDICTOR = 2097152; // 0x200000
+ field public static final int PROTECTION_FLAG_COMPANION = 8388608; // 0x800000
field public static final int PROTECTION_FLAG_CONFIGURATOR = 524288; // 0x80000
field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000
field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000
@@ -4247,138 +4275,10 @@
method public void writeRawZigZag64(long);
}
- public final class ProtoOutputStream extends android.util.proto.ProtoStream {
- ctor public ProtoOutputStream();
- ctor public ProtoOutputStream(int);
- ctor public ProtoOutputStream(java.io.OutputStream);
- ctor public ProtoOutputStream(java.io.FileDescriptor);
- method public static int checkFieldId(long, long);
- method public void dump(String);
- method public void end(long);
- method @Deprecated public void endObject(long);
- method @Deprecated public void endRepeatedObject(long);
- method public void flush();
- method public byte[] getBytes();
- method public int getRawSize();
- method public static long makeFieldId(int, long);
- method public long start(long);
- method @Deprecated public long startObject(long);
- method @Deprecated public long startRepeatedObject(long);
- method public void write(long, double);
- method public void write(long, float);
- method public void write(long, int);
- method public void write(long, long);
- method public void write(long, boolean);
- method public void write(long, String);
- method public void write(long, byte[]);
- method @Deprecated public void writeBool(long, boolean);
- method @Deprecated public void writeBytes(long, byte[]);
- method @Deprecated public void writeDouble(long, double);
- method @Deprecated public void writeEnum(long, int);
- method @Deprecated public void writeFixed32(long, int);
- method @Deprecated public void writeFixed64(long, long);
- method @Deprecated public void writeFloat(long, float);
- method @Deprecated public void writeInt32(long, int);
- method @Deprecated public void writeInt64(long, long);
- method @Deprecated public void writeObject(long, byte[]);
- method @Deprecated public void writePackedBool(long, boolean[]);
- method @Deprecated public void writePackedDouble(long, double[]);
- method @Deprecated public void writePackedEnum(long, int[]);
- method @Deprecated public void writePackedFixed32(long, int[]);
- method @Deprecated public void writePackedFixed64(long, long[]);
- method @Deprecated public void writePackedFloat(long, float[]);
- method @Deprecated public void writePackedInt32(long, int[]);
- method @Deprecated public void writePackedInt64(long, long[]);
- method @Deprecated public void writePackedSFixed32(long, int[]);
- method @Deprecated public void writePackedSFixed64(long, long[]);
- method @Deprecated public void writePackedSInt32(long, int[]);
- method @Deprecated public void writePackedSInt64(long, long[]);
- method @Deprecated public void writePackedUInt32(long, int[]);
- method @Deprecated public void writePackedUInt64(long, long[]);
- method @Deprecated public void writeRepeatedBool(long, boolean);
- method @Deprecated public void writeRepeatedBytes(long, byte[]);
- method @Deprecated public void writeRepeatedDouble(long, double);
- method @Deprecated public void writeRepeatedEnum(long, int);
- method @Deprecated public void writeRepeatedFixed32(long, int);
- method @Deprecated public void writeRepeatedFixed64(long, long);
- method @Deprecated public void writeRepeatedFloat(long, float);
- method @Deprecated public void writeRepeatedInt32(long, int);
- method @Deprecated public void writeRepeatedInt64(long, long);
- method @Deprecated public void writeRepeatedObject(long, byte[]);
- method @Deprecated public void writeRepeatedSFixed32(long, int);
- method @Deprecated public void writeRepeatedSFixed64(long, long);
- method @Deprecated public void writeRepeatedSInt32(long, int);
- method @Deprecated public void writeRepeatedSInt64(long, long);
- method @Deprecated public void writeRepeatedString(long, String);
- method @Deprecated public void writeRepeatedUInt32(long, int);
- method @Deprecated public void writeRepeatedUInt64(long, long);
- method @Deprecated public void writeSFixed32(long, int);
- method @Deprecated public void writeSFixed64(long, long);
- method @Deprecated public void writeSInt32(long, int);
- method @Deprecated public void writeSInt64(long, long);
- method @Deprecated public void writeString(long, String);
- method public void writeTag(int, int);
- method @Deprecated public void writeUInt32(long, int);
- method @Deprecated public void writeUInt64(long, long);
- }
-
public class ProtoParseException extends java.lang.RuntimeException {
ctor public ProtoParseException(String);
}
- public abstract class ProtoStream {
- ctor public ProtoStream();
- method public static int convertObjectIdToOrdinal(int);
- method public static int getDepthFromToken(long);
- method public static String getFieldCountString(long);
- method public static String getFieldIdString(long);
- method public static String getFieldTypeString(long);
- method public static int getObjectIdFromToken(long);
- method public static int getOffsetFromToken(long);
- method public static boolean getRepeatedFromToken(long);
- method public static int getTagSizeFromToken(long);
- method public static String getWireTypeString(int);
- method public static long makeFieldId(int, long);
- method public static long makeToken(int, boolean, int, int, int);
- method public static String token2String(long);
- field public static final long FIELD_COUNT_MASK = 16492674416640L; // 0xf0000000000L
- field public static final long FIELD_COUNT_PACKED = 5497558138880L; // 0x50000000000L
- field public static final long FIELD_COUNT_REPEATED = 2199023255552L; // 0x20000000000L
- field public static final int FIELD_COUNT_SHIFT = 40; // 0x28
- field public static final long FIELD_COUNT_SINGLE = 1099511627776L; // 0x10000000000L
- field public static final long FIELD_COUNT_UNKNOWN = 0L; // 0x0L
- field public static final int FIELD_ID_MASK = -8; // 0xfffffff8
- field public static final int FIELD_ID_SHIFT = 3; // 0x3
- field public static final long FIELD_TYPE_BOOL = 34359738368L; // 0x800000000L
- field public static final long FIELD_TYPE_BYTES = 51539607552L; // 0xc00000000L
- field public static final long FIELD_TYPE_DOUBLE = 4294967296L; // 0x100000000L
- field public static final long FIELD_TYPE_ENUM = 60129542144L; // 0xe00000000L
- field public static final long FIELD_TYPE_FIXED32 = 30064771072L; // 0x700000000L
- field public static final long FIELD_TYPE_FIXED64 = 25769803776L; // 0x600000000L
- field public static final long FIELD_TYPE_FLOAT = 8589934592L; // 0x200000000L
- field public static final long FIELD_TYPE_INT32 = 21474836480L; // 0x500000000L
- field public static final long FIELD_TYPE_INT64 = 12884901888L; // 0x300000000L
- field public static final long FIELD_TYPE_MASK = 1095216660480L; // 0xff00000000L
- field public static final long FIELD_TYPE_MESSAGE = 47244640256L; // 0xb00000000L
- field protected static final String[] FIELD_TYPE_NAMES;
- field public static final long FIELD_TYPE_SFIXED32 = 64424509440L; // 0xf00000000L
- field public static final long FIELD_TYPE_SFIXED64 = 68719476736L; // 0x1000000000L
- field public static final int FIELD_TYPE_SHIFT = 32; // 0x20
- field public static final long FIELD_TYPE_SINT32 = 73014444032L; // 0x1100000000L
- field public static final long FIELD_TYPE_SINT64 = 77309411328L; // 0x1200000000L
- field public static final long FIELD_TYPE_STRING = 38654705664L; // 0x900000000L
- field public static final long FIELD_TYPE_UINT32 = 55834574848L; // 0xd00000000L
- field public static final long FIELD_TYPE_UINT64 = 17179869184L; // 0x400000000L
- field public static final long FIELD_TYPE_UNKNOWN = 0L; // 0x0L
- field public static final int WIRE_TYPE_END_GROUP = 4; // 0x4
- field public static final int WIRE_TYPE_FIXED32 = 5; // 0x5
- field public static final int WIRE_TYPE_FIXED64 = 1; // 0x1
- field public static final int WIRE_TYPE_LENGTH_DELIMITED = 2; // 0x2
- field public static final int WIRE_TYPE_MASK = 7; // 0x7
- field public static final int WIRE_TYPE_START_GROUP = 3; // 0x3
- field public static final int WIRE_TYPE_VARINT = 0; // 0x0
- }
-
public class WireTypeMismatchException extends android.util.proto.ProtoParseException {
ctor public WireTypeMismatchException(String);
}
diff --git a/cmds/idmap2/CPPLINT.cfg b/cmds/idmap2/CPPLINT.cfg
index 9dc6b4a..20ed43c 100644
--- a/cmds/idmap2/CPPLINT.cfg
+++ b/cmds/idmap2/CPPLINT.cfg
@@ -15,4 +15,4 @@
set noparent
linelength=100
root=..
-filter=+build/include_alpha
+filter=+build/include_alpha,-runtime/references,-build/c++
diff --git a/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h b/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h
index 924efe5..ff45b14 100644
--- a/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h
+++ b/cmds/idmap2/include/idmap2/BinaryStreamVisitor.h
@@ -40,7 +40,8 @@
void Write8(uint8_t value);
void Write16(uint16_t value);
void Write32(uint32_t value);
- void WriteString(const StringPiece& value);
+ void WriteString256(const StringPiece& value);
+ void WriteString(const std::string& value);
std::ostream& stream_;
};
diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h
index 2639c6f..d4a0c322 100644
--- a/cmds/idmap2/include/idmap2/Idmap.h
+++ b/cmds/idmap2/include/idmap2/Idmap.h
@@ -18,19 +18,21 @@
* # idmap file format (current version)
*
* idmap := header data*
- * header := magic version target_crc overlay_crc target_path overlay_path
+ * header := magic version target_crc overlay_crc target_path overlay_path debug_info
* data := data_header data_block*
* data_header := target_package_id types_count
* data_block := target_type overlay_type entry_count entry_offset entry*
- * overlay_path := string
- * target_path := string
+ * overlay_path := string256
+ * target_path := string256
+ * debug_info := string
+ * string := <uint32_t> <uint8_t>+ '\0'+
* entry := <uint32_t>
* entry_count := <uint16_t>
* entry_offset := <uint16_t>
* magic := <uint32_t>
* overlay_crc := <uint32_t>
* overlay_type := <uint16_t>
- * string := <uint8_t>[256]
+ * string256 := <uint8_t>[256]
* target_crc := <uint32_t>
* target_package_id := <uint16_t>
* target_type := <uint16_t>
@@ -41,6 +43,7 @@
* # idmap file format changelog
* ## v1
* - Identical to idmap v1.
+ *
* ## v2
* - Entries are no longer separated by type into type specific data blocks.
* - Added overlay-indexed target resource id lookup capabilities.
@@ -53,6 +56,9 @@
* - Idmap can now encode a type and value to override a resource without needing a table entry.
* - A string pool block is included to retrieve the value of strings that do not have a resource
* table entry.
+ *
+ * ## v3
+ * - Add 'debug' block to IdmapHeader.
*/
#ifndef IDMAP2_INCLUDE_IDMAP2_IDMAP_H_
@@ -116,6 +122,10 @@
return StringPiece(overlay_path_);
}
+ inline const std::string& GetDebugInfo() const {
+ return debug_info_;
+ }
+
// Invariant: anytime the idmap data encoding is changed, the idmap version
// field *must* be incremented. Because of this, we know that if the idmap
// header is up-to-date the entire file is up-to-date.
@@ -133,6 +143,7 @@
uint32_t overlay_crc_;
char target_path_[kIdmapStringLength];
char overlay_path_[kIdmapStringLength];
+ std::string debug_info_;
friend Idmap;
DISALLOW_COPY_AND_ASSIGN(IdmapHeader);
diff --git a/cmds/idmap2/include/idmap2/LogInfo.h b/cmds/idmap2/include/idmap2/LogInfo.h
new file mode 100644
index 0000000..a6237e6
--- /dev/null
+++ b/cmds/idmap2/include/idmap2/LogInfo.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef IDMAP2_INCLUDE_IDMAP2_LOGINFO_H_
+#define IDMAP2_INCLUDE_IDMAP2_LOGINFO_H_
+
+#include <algorithm>
+#include <iterator>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#if __ANDROID__
+#include "android-base/logging.h"
+#else
+#include <iostream>
+#endif
+
+namespace android::idmap2 {
+
+class LogMessage {
+ public:
+ LogMessage() = default;
+
+ template <typename T>
+ LogMessage& operator<<(const T& value) {
+ stream_ << value;
+ return *this;
+ }
+
+ std::string GetString() const {
+ return stream_.str();
+ }
+
+ private:
+ std::stringstream stream_;
+};
+
+class LogInfo {
+ public:
+ LogInfo() = default;
+
+ inline void Info(const LogMessage& msg) {
+ lines_.push_back("I " + msg.GetString());
+ }
+
+ inline void Warning(const LogMessage& msg) {
+#ifdef __ANDROID__
+ LOG(WARNING) << msg.GetString();
+#else
+ std::cerr << "W " << msg.GetString() << std::endl;
+#endif
+ lines_.push_back("W " + msg.GetString());
+ }
+
+ inline std::string GetString() const {
+ std::ostringstream stream;
+ std::copy(lines_.begin(), lines_.end(), std::ostream_iterator<std::string>(stream, "\n"));
+ return stream.str();
+ }
+
+ private:
+ std::vector<std::string> lines_;
+};
+
+} // namespace android::idmap2
+
+#endif // IDMAP2_INCLUDE_IDMAP2_LOGINFO_H_
diff --git a/cmds/idmap2/include/idmap2/RawPrintVisitor.h b/cmds/idmap2/include/idmap2/RawPrintVisitor.h
index 76475ab..92c1864 100644
--- a/cmds/idmap2/include/idmap2/RawPrintVisitor.h
+++ b/cmds/idmap2/include/idmap2/RawPrintVisitor.h
@@ -44,7 +44,7 @@
void print(uint8_t value, const char* fmt, ...);
void print(uint16_t value, const char* fmt, ...);
void print(uint32_t value, const char* fmt, ...);
- void print(const std::string& value, const char* fmt, ...);
+ void print(const std::string& value, size_t encoded_size, const char* fmt, ...);
void print_raw(uint32_t length, const char* fmt, ...);
std::ostream& stream_;
diff --git a/cmds/idmap2/include/idmap2/ResourceMapping.h b/cmds/idmap2/include/idmap2/ResourceMapping.h
index c3e1ef0..86dfab2 100644
--- a/cmds/idmap2/include/idmap2/ResourceMapping.h
+++ b/cmds/idmap2/include/idmap2/ResourceMapping.h
@@ -22,6 +22,7 @@
#include <utility>
#include "androidfw/ApkAssets.h"
+#include "idmap2/LogInfo.h"
#include "idmap2/Policies.h"
#include "idmap2/ResourceUtils.h"
#include "idmap2/Result.h"
@@ -50,7 +51,7 @@
const ApkAssets& overlay_apk_assets,
const OverlayManifestInfo& overlay_info,
const PolicyBitmask& fulfilled_policies,
- bool enforce_overlayable);
+ bool enforce_overlayable, LogInfo& log_info);
// Retrieves the mapping of target resource id to overlay value.
inline TargetResourceMap GetTargetToOverlayMap() const {
@@ -100,7 +101,8 @@
const LoadedPackage* target_package,
const LoadedPackage* overlay_package,
size_t string_pool_offset,
- const XmlParser& overlay_parser);
+ const XmlParser& overlay_parser,
+ LogInfo& log_info);
// Generates a ResourceMapping that maps target resources to overlay resources by name. To overlay
// a target resource, a resource must exist in the overlay with the same type and entry name as
@@ -115,7 +117,7 @@
const LoadedPackage* target_package,
const LoadedPackage* overlay_package,
const OverlayManifestInfo& overlay_info,
- const PolicyBitmask& fulfilled_policies);
+ const PolicyBitmask& fulfilled_policies, LogInfo& log_info);
TargetResourceMap target_map_;
std::multimap<ResourceId, ResourceId> overlay_map_;
diff --git a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp
index 3b0940a..362dcb3 100644
--- a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp
+++ b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp
@@ -42,13 +42,21 @@
stream_.write(reinterpret_cast<char*>(&x), sizeof(uint32_t));
}
-void BinaryStreamVisitor::WriteString(const StringPiece& value) {
+void BinaryStreamVisitor::WriteString256(const StringPiece& value) {
char buf[kIdmapStringLength];
memset(buf, 0, sizeof(buf));
memcpy(buf, value.data(), std::min(value.size(), sizeof(buf)));
stream_.write(buf, sizeof(buf));
}
+void BinaryStreamVisitor::WriteString(const std::string& value) {
+ // pad with null to nearest word boundary; include at least one terminating null
+ size_t padding_size = 4 - (value.size() % 4);
+ Write32(value.size() + padding_size);
+ stream_.write(value.c_str(), value.size());
+ stream_.write("\0\0\0\0", padding_size);
+}
+
void BinaryStreamVisitor::visit(const Idmap& idmap ATTRIBUTE_UNUSED) {
// nothing to do
}
@@ -58,8 +66,9 @@
Write32(header.GetVersion());
Write32(header.GetTargetCrc());
Write32(header.GetOverlayCrc());
- WriteString(header.GetTargetPath());
- WriteString(header.GetOverlayPath());
+ WriteString256(header.GetTargetPath());
+ WriteString256(header.GetOverlayPath());
+ WriteString(header.GetDebugInfo());
}
void BinaryStreamVisitor::visit(const IdmapData& data) {
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index 5cb91d7..7f2cd95 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -70,7 +70,7 @@
}
// a string is encoded as a kIdmapStringLength char array; the array is always null-terminated
-bool WARN_UNUSED ReadString(std::istream& stream, char out[kIdmapStringLength]) {
+bool WARN_UNUSED ReadString256(std::istream& stream, char out[kIdmapStringLength]) {
char buf[kIdmapStringLength];
memset(buf, 0, sizeof(buf));
if (!stream.read(buf, sizeof(buf))) {
@@ -83,6 +83,23 @@
return true;
}
+Result<std::string> ReadString(std::istream& stream) {
+ uint32_t size;
+ if (!Read32(stream, &size)) {
+ return Error("failed to read string size");
+ }
+ if (size == 0) {
+ return std::string("");
+ }
+ std::string buf(size, '\0');
+ if (!stream.read(buf.data(), size)) {
+ return Error("failed to read string of size %u", size);
+ }
+ // buf is guaranteed to be null terminated (with enough nulls to end on a word boundary)
+ buf.resize(strlen(buf.c_str()));
+ return buf;
+}
+
Result<uint32_t> GetCrc(const ZipFile& zip) {
const Result<uint32_t> a = zip.Crc("resources.arsc");
const Result<uint32_t> b = zip.Crc("AndroidManifest.xml");
@@ -98,11 +115,17 @@
if (!Read32(stream, &idmap_header->magic_) || !Read32(stream, &idmap_header->version_) ||
!Read32(stream, &idmap_header->target_crc_) || !Read32(stream, &idmap_header->overlay_crc_) ||
- !ReadString(stream, idmap_header->target_path_) ||
- !ReadString(stream, idmap_header->overlay_path_)) {
+ !ReadString256(stream, idmap_header->target_path_) ||
+ !ReadString256(stream, idmap_header->overlay_path_)) {
return nullptr;
}
+ auto debug_str = ReadString(stream);
+ if (!debug_str) {
+ return nullptr;
+ }
+ idmap_header->debug_info_ = std::move(*debug_str);
+
return std::move(idmap_header);
}
@@ -307,17 +330,15 @@
memset(header->overlay_path_, 0, sizeof(header->overlay_path_));
memcpy(header->overlay_path_, overlay_apk_path.data(), overlay_apk_path.size());
- std::unique_ptr<Idmap> idmap(new Idmap());
- idmap->header_ = std::move(header);
-
auto overlay_info = utils::ExtractOverlayManifestInfo(overlay_apk_path);
if (!overlay_info) {
return overlay_info.GetError();
}
+ LogInfo log_info;
auto resource_mapping =
ResourceMapping::FromApkAssets(target_apk_assets, overlay_apk_assets, *overlay_info,
- fulfilled_policies, enforce_overlayable);
+ fulfilled_policies, enforce_overlayable, log_info);
if (!resource_mapping) {
return resource_mapping.GetError();
}
@@ -327,7 +348,11 @@
return idmap_data.GetError();
}
+ std::unique_ptr<Idmap> idmap(new Idmap());
+ header->debug_info_ = log_info.GetString();
+ idmap->header_ = std::move(header);
idmap->data_.push_back(std::move(*idmap_data));
+
return {std::move(idmap)};
}
diff --git a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
index a662aa5..63ee8a6 100644
--- a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
+++ b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp
@@ -16,6 +16,7 @@
#include "idmap2/PrettyPrintVisitor.h"
+#include <istream>
#include <string>
#include "android-base/macros.h"
@@ -28,17 +29,30 @@
#define RESID(pkg, type, entry) (((pkg) << 24) | ((type) << 16) | (entry))
+#define TAB " "
+
void PrettyPrintVisitor::visit(const Idmap& idmap ATTRIBUTE_UNUSED) {
}
void PrettyPrintVisitor::visit(const IdmapHeader& header) {
- stream_ << "target apk path : " << header.GetTargetPath() << std::endl
- << "overlay apk path : " << header.GetOverlayPath() << std::endl;
+ stream_ << "Paths:" << std::endl
+ << TAB "target apk path : " << header.GetTargetPath() << std::endl
+ << TAB "overlay apk path : " << header.GetOverlayPath() << std::endl;
+ const std::string& debug = header.GetDebugInfo();
+ if (!debug.empty()) {
+ std::istringstream debug_stream(debug);
+ std::string line;
+ stream_ << "Debug info:" << std::endl;
+ while (std::getline(debug_stream, line)) {
+ stream_ << TAB << line << std::endl;
+ }
+ }
target_apk_ = ApkAssets::Load(header.GetTargetPath().to_string());
if (target_apk_) {
target_am_.SetApkAssets({target_apk_.get()});
}
+ stream_ << "Mapping:" << std::endl;
}
void PrettyPrintVisitor::visit(const IdmapData::Header& header ATTRIBUTE_UNUSED) {
@@ -51,7 +65,7 @@
const size_t string_pool_offset = data.GetHeader()->GetStringPoolIndexOffset();
for (auto& target_entry : data.GetTargetEntries()) {
- stream_ << base::StringPrintf("0x%08x ->", target_entry.target_id);
+ stream_ << TAB << base::StringPrintf("0x%08x ->", target_entry.target_id);
if (target_entry.data_type != Res_value::TYPE_REFERENCE &&
target_entry.data_type != Res_value::TYPE_DYNAMIC_REFERENCE) {
diff --git a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
index 13973d6..751c60c 100644
--- a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
+++ b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp
@@ -16,6 +16,7 @@
#include "idmap2/RawPrintVisitor.h"
+#include <algorithm>
#include <cstdarg>
#include <string>
@@ -27,6 +28,15 @@
using android::ApkAssets;
+namespace {
+
+size_t StringSizeWhenEncoded(const std::string& s) {
+ size_t null_bytes = 4 - (s.size() % 4);
+ return sizeof(uint32_t) + s.size() + null_bytes;
+}
+
+} // namespace
+
namespace android::idmap2 {
// verbatim copy fomr PrettyPrintVisitor.cpp, move to common utils
@@ -40,8 +50,9 @@
print(header.GetVersion(), "version");
print(header.GetTargetCrc(), "target crc");
print(header.GetOverlayCrc(), "overlay crc");
- print(header.GetTargetPath().to_string(), "target path");
- print(header.GetOverlayPath().to_string(), "overlay path");
+ print(header.GetTargetPath().to_string(), kIdmapStringLength, "target path");
+ print(header.GetOverlayPath().to_string(), kIdmapStringLength, "overlay path");
+ print("...", StringSizeWhenEncoded(header.GetDebugInfo()), "debug info");
target_apk_ = ApkAssets::Load(header.GetTargetPath().to_string());
if (target_apk_) {
@@ -164,7 +175,7 @@
}
// NOLINTNEXTLINE(cert-dcl50-cpp)
-void RawPrintVisitor::print(const std::string& value, const char* fmt, ...) {
+void RawPrintVisitor::print(const std::string& value, size_t encoded_size, const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
std::string comment;
@@ -174,7 +185,7 @@
stream_ << base::StringPrintf("%08zx: ", offset_) << "........ " << comment << ": " << value
<< std::endl;
- offset_ += kIdmapStringLength;
+ offset_ += encoded_size;
}
// NOLINTNEXTLINE(cert-dcl50-cpp)
diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp
index 651d20f..229628c 100644
--- a/cmds/idmap2/libidmap2/ResourceMapping.cpp
+++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp
@@ -146,7 +146,8 @@
const LoadedPackage* target_package,
const LoadedPackage* overlay_package,
size_t string_pool_offset,
- const XmlParser& overlay_parser) {
+ const XmlParser& overlay_parser,
+ LogInfo& log_info) {
ResourceMapping resource_mapping;
auto root_it = overlay_parser.tree_iterator();
if (root_it->event() != XmlParser::Event::START_TAG || root_it->name() != "overlay") {
@@ -181,7 +182,8 @@
ResourceId target_id =
target_am->GetResourceId(*target_resource, "", target_package->GetPackageName());
if (target_id == 0U) {
- LOG(WARNING) << "failed to find resource \"" << *target_resource << "\" in target resources";
+ log_info.Warning(LogMessage() << "failed to find resource \"" << *target_resource
+ << "\" in target resources");
continue;
}
@@ -196,7 +198,7 @@
overlay_resource->dataType == Res_value::TYPE_DYNAMIC_REFERENCE)
? overlay_package_id == EXTRACT_PACKAGE(overlay_resource->data)
: false;
-
+
if (rewrite_overlay_reference) {
overlay_resource->dataType = Res_value::TYPE_DYNAMIC_REFERENCE;
}
@@ -239,7 +241,8 @@
const LoadedPackage* target_package,
const LoadedPackage* overlay_package,
const OverlayManifestInfo& overlay_info,
- const PolicyBitmask& fulfilled_policies) {
+ const PolicyBitmask& fulfilled_policies,
+ LogInfo& log_info) {
std::set<ResourceId> remove_ids;
for (const auto& target_map : target_map_) {
const ResourceId target_resid = target_map.first;
@@ -256,9 +259,9 @@
name = StringPrintf("0x%08x", target_resid);
}
- LOG(WARNING) << "overlay \"" << overlay_package->GetPackageName()
- << "\" is not allowed to overlay resource \"" << *name
- << "\" in target: " << success.GetErrorMessage();
+ log_info.Warning(LogMessage() << "overlay \"" << overlay_package->GetPackageName()
+ << "\" is not allowed to overlay resource \"" << *name
+ << "\" in target: " << success.GetErrorMessage());
remove_ids.insert(target_resid);
}
@@ -272,7 +275,15 @@
const ApkAssets& overlay_apk_assets,
const OverlayManifestInfo& overlay_info,
const PolicyBitmask& fulfilled_policies,
- bool enforce_overlayable) {
+ bool enforce_overlayable,
+ LogInfo& log_info) {
+ if (enforce_overlayable) {
+ log_info.Info(LogMessage() << "fulfilled_policies="
+ << ConcatPolicies(BitmaskToPolicies(fulfilled_policies))
+ << " enforce_overlayable="
+ << (enforce_overlayable ? "true" : "false"));
+ }
+
AssetManager2 target_asset_manager;
if (!target_asset_manager.SetApkAssets({&target_apk_assets}, true /* invalidate_caches */,
false /* filter_incompatible_configs*/)) {
@@ -333,7 +344,7 @@
string_pool_offset = overlay_arsc->GetStringPool()->size();
resource_mapping = CreateResourceMapping(&target_asset_manager, target_pkg, overlay_pkg,
- string_pool_offset, *(*parser));
+ string_pool_offset, *(*parser), log_info);
} else {
// If no file is specified using android:resourcesMap, it is assumed that the overlay only
// defines resources intended to override target resources of the same type and name.
@@ -349,7 +360,7 @@
// Filter out resources the overlay is not allowed to override.
(*resource_mapping)
.FilterOverlayableResources(&target_asset_manager, target_pkg, overlay_pkg, overlay_info,
- fulfilled_policies);
+ fulfilled_policies, log_info);
}
resource_mapping->target_package_id_ = target_pkg->GetPackageId();
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index cd816dd..4bc6255 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -30,6 +30,7 @@
#include "idmap2/BinaryStreamVisitor.h"
#include "idmap2/CommandLineOptions.h"
#include "idmap2/Idmap.h"
+#include "idmap2/LogInfo.h"
using android::Res_value;
using ::testing::IsNull;
@@ -57,11 +58,12 @@
std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
ASSERT_THAT(header, NotNull());
ASSERT_EQ(header->GetMagic(), 0x504d4449U);
- ASSERT_EQ(header->GetVersion(), 0x02U);
+ ASSERT_EQ(header->GetVersion(), 0x03U);
ASSERT_EQ(header->GetTargetCrc(), 0x1234U);
ASSERT_EQ(header->GetOverlayCrc(), 0x5678U);
ASSERT_EQ(header->GetTargetPath().to_string(), "targetX.apk");
ASSERT_EQ(header->GetOverlayPath().to_string(), "overlayX.apk");
+ ASSERT_EQ(header->GetDebugInfo(), "debug");
}
TEST(IdmapTests, FailToCreateIdmapHeaderFromBinaryStreamIfPathTooLong) {
@@ -76,7 +78,7 @@
}
TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) {
- const size_t offset = 0x210;
+ const size_t offset = 0x21c;
std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
idmap_raw_data_len - offset);
std::istringstream stream(raw);
@@ -88,7 +90,7 @@
}
TEST(IdmapTests, CreateIdmapDataFromBinaryStream) {
- const size_t offset = 0x210;
+ const size_t offset = 0x21c;
std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
idmap_raw_data_len - offset);
std::istringstream stream(raw);
@@ -122,7 +124,7 @@
ASSERT_THAT(idmap->GetHeader(), NotNull());
ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
- ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x02U);
+ ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x03U);
ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x1234U);
ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x5678U);
ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), "targetX.apk");
@@ -174,7 +176,7 @@
ASSERT_THAT(idmap->GetHeader(), NotNull());
ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
- ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x02U);
+ ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x03U);
ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x76a20829);
ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0xc054fb26);
ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path);
@@ -197,8 +199,9 @@
return Error(R"(Failed to load overlay apk "%s")", overlay_apk_path.data());
}
+ LogInfo log_info;
auto mapping = ResourceMapping::FromApkAssets(*target_apk, *overlay_apk, overlay_info,
- fulfilled_policies, enforce_overlayable);
+ fulfilled_policies, enforce_overlayable, log_info);
if (!mapping) {
return mapping.GetError();
diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
index d387880..b22fdaf 100644
--- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp
+++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
@@ -16,6 +16,7 @@
#include <cstdio> // fclose
#include <memory>
+#include <regex>
#include <sstream>
#include <string>
@@ -29,7 +30,16 @@
namespace android::idmap2 {
+#define ASSERT_CONTAINS_REGEX(pattern, str) \
+ do { \
+ ASSERT_TRUE(std::regex_search(str, std::regex(pattern))) \
+ << "pattern '" << pattern << "' not found in\n--------\n" \
+ << str << "--------"; \
+ } while (0)
+
TEST(RawPrintVisitorTests, CreateRawPrintVisitor) {
+ fclose(stderr); // silence expected warnings
+
const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
ASSERT_THAT(target_apk, NotNull());
@@ -46,22 +56,24 @@
RawPrintVisitor visitor(stream);
(*idmap)->accept(&visitor);
- ASSERT_NE(stream.str().find("00000000: 504d4449 magic\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000004: 00000002 version\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000008: 76a20829 target crc\n"), std::string::npos);
- ASSERT_NE(stream.str().find("0000000c: c054fb26 overlay crc\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000210: 7f target package id\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000211: 7f overlay package id\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000212: 00000004 target entry count\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000216: 00000004 overlay entry count\n"), std::string::npos);
- ASSERT_NE(stream.str().find("0000021a: 00000008 string pool index offset\n"), std::string::npos);
- ASSERT_NE(stream.str().find("0000021e: 000000b4 string pool byte length\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000222: 7f010000 target id: integer/int1\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000226: 07 type: reference (dynamic)\n"),
- std::string::npos);
- ASSERT_NE(stream.str().find("00000227: 7f010000 value: integer/int1\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000246: 7f010000 overlay id: integer/int1\n"), std::string::npos);
- ASSERT_NE(stream.str().find("0000024a: 7f010000 target id: integer/int1\n"), std::string::npos);
+#define ADDRESS "[0-9a-f]{8}: "
+ ASSERT_CONTAINS_REGEX(ADDRESS "504d4449 magic\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "00000003 version\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "76a20829 target crc\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "c054fb26 overlay crc\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS " 7f target package id\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS " 7f overlay package id\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "00000004 target entry count\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "00000004 overlay entry count\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "00000004 overlay entry count\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "00000008 string pool index offset\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "000000b4 string pool byte length\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 target id: integer/int1\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS " 07 type: reference \\(dynamic\\)\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 value: integer/int1\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 overlay id: integer/int1\n", stream.str());
+ ASSERT_CONTAINS_REGEX(ADDRESS "7f010000 target id: integer/int1\n", stream.str());
+#undef ADDRESS
}
TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) {
@@ -78,21 +90,21 @@
(*idmap)->accept(&visitor);
ASSERT_NE(stream.str().find("00000000: 504d4449 magic\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000004: 00000002 version\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("00000004: 00000003 version\n"), std::string::npos);
ASSERT_NE(stream.str().find("00000008: 00001234 target crc\n"), std::string::npos);
ASSERT_NE(stream.str().find("0000000c: 00005678 overlay crc\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000210: 7f target package id\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000211: 7f overlay package id\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000212: 00000003 target entry count\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000216: 00000003 overlay entry count\n"), std::string::npos);
- ASSERT_NE(stream.str().find("0000021a: 00000000 string pool index offset\n"), std::string::npos);
- ASSERT_NE(stream.str().find("0000021e: 00000000 string pool byte length\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000222: 7f020000 target id\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000226: 01 type: reference\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000227: 7f020000 value\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("0000021c: 7f target package id\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("0000021d: 7f overlay package id\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("0000021e: 00000003 target entry count\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("00000222: 00000003 overlay entry count\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("00000226: 00000000 string pool index offset\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("0000022a: 00000000 string pool byte length\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("0000022e: 7f020000 target id\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("00000232: 01 type: reference\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("00000233: 7f020000 value\n"), std::string::npos);
- ASSERT_NE(stream.str().find("0000023d: 7f020000 overlay id\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000241: 7f020000 target id\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("00000249: 7f020000 overlay id\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("0000024d: 7f020000 target id\n"), std::string::npos);
}
} // namespace android::idmap2
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index 64304f6..39c4937 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -25,6 +25,7 @@
#include "TestHelpers.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "idmap2/LogInfo.h"
#include "idmap2/ResourceMapping.h"
using android::Res_value;
@@ -55,8 +56,9 @@
return Error(R"(Failed to load overlay apk "%s")", overlay_apk_path.data());
}
+ LogInfo log_info;
return ResourceMapping::FromApkAssets(*target_apk, *overlay_apk, overlay_info, fulfilled_policies,
- enforce_overlayable);
+ enforce_overlayable, log_info);
}
Result<ResourceMapping> TestGetResourceMapping(const android::StringPiece& local_target_apk_path,
diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h
index 8868b53..e899589 100644
--- a/cmds/idmap2/tests/TestHelpers.h
+++ b/cmds/idmap2/tests/TestHelpers.h
@@ -30,7 +30,7 @@
0x49, 0x44, 0x4d, 0x50,
// 0x4: version
- 0x02, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00,
// 0x8: target crc
0x34, 0x12, 0x00, 0x00,
@@ -74,64 +74,71 @@
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // 0x210: debug string
+ // string length, including terminating null
+ 0x08, 0x00, 0x00, 0x00,
+
+ // string contents "debug\0\0\0" (padded to word alignment)
+ 0x64, 0x65, 0x62, 0x75, 0x67, 0x00, 0x00, 0x00,
+
// DATA HEADER
- // 0x210: target_package_id
+ // 0x21c: target_package_id
0x7f,
- // 0x211: overlay_package_id
+ // 0x21d: overlay_package_id
0x7f,
- // 0x212: target_entry_count
+ // 0x21e: target_entry_count
0x03, 0x00, 0x00, 0x00,
- // 0x216: overlay_entry_count
+ // 0x222: overlay_entry_count
0x03, 0x00, 0x00, 0x00,
- // 0x21a: string_pool_offset
+ // 0x226: string_pool_offset
0x00, 0x00, 0x00, 0x00,
- // 0x21e: string_pool_byte_length
+ // 0x22a: string_pool_byte_length
0x00, 0x00, 0x00, 0x00,
// TARGET ENTRIES
- // 0x222: 0x7f020000
+ // 0x22e: 0x7f020000
0x00, 0x00, 0x02, 0x7f,
- // 0x226: TYPE_REFERENCE
+ // 0x232: TYPE_REFERENCE
0x01,
- // 0x227: 0x7f020000
+ // 0x233: 0x7f020000
0x00, 0x00, 0x02, 0x7f,
- // 0x22b: 0x7f030000
+ // 0x237: 0x7f030000
0x00, 0x00, 0x03, 0x7f,
- // 0x22f: TYPE_REFERENCE
+ // 0x23b: TYPE_REFERENCE
0x01,
- // 0x230: 0x7f030000
+ // 0x23c: 0x7f030000
0x00, 0x00, 0x03, 0x7f,
- // 0x234: 0x7f030002
+ // 0x240: 0x7f030002
0x02, 0x00, 0x03, 0x7f,
- // 0x238: TYPE_REFERENCE
+ // 0x244: TYPE_REFERENCE
0x01,
- // 0x239: 0x7f030001
+ // 0x245: 0x7f030001
0x01, 0x00, 0x03, 0x7f,
// OVERLAY ENTRIES
- // 0x23d: 0x7f020000 -> 0x7f020000
+ // 0x249: 0x7f020000 -> 0x7f020000
0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x02, 0x7f,
- // 0x245: 0x7f030000 -> 0x7f030000
+ // 0x251: 0x7f030000 -> 0x7f030000
0x00, 0x00, 0x03, 0x7f, 0x00, 0x00, 0x03, 0x7f,
- // 0x24d: 0x7f030001 -> 0x7f030002
+ // 0x259: 0x7f030001 -> 0x7f030002
0x01, 0x00, 0x03, 0x7f, 0x02, 0x00, 0x03, 0x7f};
-const unsigned int idmap_raw_data_len = 0x255;
+const unsigned int idmap_raw_data_len = 0x261;
std::string GetTestDataPath();
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
index a545fc5..4385964 100644
--- a/cmds/statsd/src/FieldValue.cpp
+++ b/cmds/statsd/src/FieldValue.cpp
@@ -435,6 +435,25 @@
return eq;
}
+bool subsetDimensions(const std::vector<Matcher>& dimension_a,
+ const std::vector<Matcher>& dimension_b) {
+ if (dimension_a.size() > dimension_b.size()) {
+ return false;
+ }
+ for (size_t i = 0; i < dimension_a.size(); ++i) {
+ bool found = false;
+ for (size_t j = 0; j < dimension_b.size(); ++j) {
+ if (dimension_a[i] == dimension_b[j]) {
+ found = true;
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool HasPositionANY(const FieldMatcher& matcher) {
if (matcher.has_position() && matcher.position() == Position::ANY) {
return true;
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
index 0e033e0..6fc1e23 100644
--- a/cmds/statsd/src/FieldValue.h
+++ b/cmds/statsd/src/FieldValue.h
@@ -396,6 +396,10 @@
bool equalDimensions(const std::vector<Matcher>& dimension_a,
const std::vector<Matcher>& dimension_b);
+
+// Returns true if dimension_a is a subset of dimension_b.
+bool subsetDimensions(const std::vector<Matcher>& dimension_a,
+ const std::vector<Matcher>& dimension_b);
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index a2cfff2..2270974 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -5995,6 +5995,14 @@
USER_GRANTED_ONE_TIME = 10;
// user ignored request by leaving the request screen without choosing any option
USER_IGNORED = 11;
+ // user granted the permission after being linked to settings
+ USER_GRANTED_IN_SETTINGS = 12;
+ // user denied the permission after being linked to settings
+ USER_DENIED_IN_SETTINGS = 13;
+ // user denied the permission with prejudice after being linked to settings
+ USER_DENIED_WITH_PREJUDICE_IN_SETTINGS = 14;
+ // permission was automatically revoked after one-time permission expired
+ AUTO_ONE_TIME_PERMISSION_REVOKED = 15;
}
// The result of the permission grant
optional Result result = 6;
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
index f1cad92..f4a59ed 100644
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ b/cmds/statsd/tests/FieldValue_test.cpp
@@ -480,6 +480,137 @@
EXPECT_EQ(999, atom.num_results());
}
+/*
+ * Test two Matchers is not a subset of one Matcher.
+ * Test one Matcher is subset of two Matchers.
+ */
+TEST(AtomMatcherTest, TestSubsetDimensions1) {
+ // Initialize first set of matchers
+ FieldMatcher matcher1;
+ matcher1.set_field(10);
+
+ FieldMatcher* child = matcher1.add_child();
+ child->set_field(1);
+ child->set_position(Position::ALL);
+ child->add_child()->set_field(1);
+ child->add_child()->set_field(2);
+
+ vector<Matcher> matchers1;
+ translateFieldMatcher(matcher1, &matchers1);
+ EXPECT_EQ(2, matchers1.size());
+
+ // Initialize second set of matchers
+ FieldMatcher matcher2;
+ matcher2.set_field(10);
+
+ child = matcher2.add_child();
+ child->set_field(1);
+ child->set_position(Position::ALL);
+ child->add_child()->set_field(1);
+
+ vector<Matcher> matchers2;
+ translateFieldMatcher(matcher2, &matchers2);
+ EXPECT_EQ(1, matchers2.size());
+
+ EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
+ EXPECT_TRUE(subsetDimensions(matchers2, matchers1));
+}
+/*
+ * Test not a subset with one matching Matcher, one non-matching Matcher.
+ */
+TEST(AtomMatcherTest, TestSubsetDimensions2) {
+ // Initialize first set of matchers
+ FieldMatcher matcher1;
+ matcher1.set_field(10);
+
+ FieldMatcher* child = matcher1.add_child();
+ child->set_field(1);
+
+ child = matcher1.add_child();
+ child->set_field(2);
+
+ vector<Matcher> matchers1;
+ translateFieldMatcher(matcher1, &matchers1);
+
+ // Initialize second set of matchers
+ FieldMatcher matcher2;
+ matcher2.set_field(10);
+
+ child = matcher2.add_child();
+ child->set_field(1);
+
+ child = matcher2.add_child();
+ child->set_field(3);
+
+ vector<Matcher> matchers2;
+ translateFieldMatcher(matcher2, &matchers2);
+
+ EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
+}
+
+/*
+ * Test not a subset if parent field is not equal.
+ */
+TEST(AtomMatcherTest, TestSubsetDimensions3) {
+ // Initialize first set of matchers
+ FieldMatcher matcher1;
+ matcher1.set_field(10);
+
+ FieldMatcher* child = matcher1.add_child();
+ child->set_field(1);
+
+ vector<Matcher> matchers1;
+ translateFieldMatcher(matcher1, &matchers1);
+
+ // Initialize second set of matchers
+ FieldMatcher matcher2;
+ matcher2.set_field(5);
+
+ child = matcher2.add_child();
+ child->set_field(1);
+
+ vector<Matcher> matchers2;
+ translateFieldMatcher(matcher2, &matchers2);
+
+ EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
+}
+
+/*
+ * Test is subset with two matching Matchers.
+ */
+TEST(AtomMatcherTest, TestSubsetDimensions4) {
+ // Initialize first set of matchers
+ FieldMatcher matcher1;
+ matcher1.set_field(10);
+
+ FieldMatcher* child = matcher1.add_child();
+ child->set_field(1);
+
+ child = matcher1.add_child();
+ child->set_field(2);
+
+ vector<Matcher> matchers1;
+ translateFieldMatcher(matcher1, &matchers1);
+
+ // Initialize second set of matchers
+ FieldMatcher matcher2;
+ matcher2.set_field(10);
+
+ child = matcher2.add_child();
+ child->set_field(1);
+
+ child = matcher2.add_child();
+ child->set_field(2);
+
+ child = matcher2.add_child();
+ child->set_field(3);
+
+ vector<Matcher> matchers2;
+ translateFieldMatcher(matcher2, &matchers2);
+
+ EXPECT_TRUE(subsetDimensions(matchers1, matchers2));
+ EXPECT_FALSE(subsetDimensions(matchers2, matchers1));
+}
} // namespace statsd
} // namespace os
diff --git a/core/java/android/app/AppOpsManager.aidl b/core/java/android/app/AppOpsManager.aidl
index 2240302..b4dee2e 100644
--- a/core/java/android/app/AppOpsManager.aidl
+++ b/core/java/android/app/AppOpsManager.aidl
@@ -17,6 +17,9 @@
package android.app;
parcelable AppOpsManager.PackageOps;
+parcelable AppOpsManager.NoteOpEventProxyInfo;
+parcelable AppOpsManager.NoteOpEvent;
+parcelable AppOpsManager.OpFeatureEntry;
parcelable AppOpsManager.OpEntry;
parcelable AppOpsManager.HistoricalOp;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 4ce91a6..86a5c76 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -48,9 +48,9 @@
import android.os.RemoteException;
import android.os.UserManager;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.LongSparseArray;
import android.util.LongSparseLongArray;
-import android.util.Pair;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
@@ -63,6 +63,8 @@
import com.android.internal.os.RuntimeInit;
import com.android.internal.os.ZygoteInit;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DataClass;
+import com.android.internal.util.Parcelling;
import com.android.internal.util.Preconditions;
import java.lang.annotation.ElementType;
@@ -83,7 +85,6 @@
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Supplier;
-import java.util.function.ToLongFunction;
/**
* API for interacting with "application operation" tracking.
@@ -138,7 +139,7 @@
@GuardedBy("sLock")
private static @Nullable AppOpsCollector sNotedAppOpsCollector;
- static IBinder sToken;
+ static IBinder sClientId;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -846,10 +847,12 @@
public static final int OP_ACCESS_MEDIA_LOCATION = 90;
/** @hide Query all apps on device, regardless of declarations in the calling app manifest */
public static final int OP_QUERY_ALL_PACKAGES = 91;
+ /** @hide Access all external storage */
+ public static final int OP_MANAGE_EXTERNAL_STORAGE = 92;
/** @hide */
@UnsupportedAppUsage
- public static final int _NUM_OP = 92;
+ public static final int _NUM_OP = 93;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -1135,6 +1138,10 @@
public static final String OPSTR_READ_DEVICE_IDENTIFIERS = "android:read_device_identifiers";
/** @hide Query all packages on device */
public static final String OPSTR_QUERY_ALL_PACKAGES = "android:query_all_packages";
+ /** @hide Access all external storage */
+ @SystemApi
+ public static final String OPSTR_MANAGE_EXTERNAL_STORAGE =
+ "android:manage_external_storage";
/** {@link #sAppOpsToNote} not initialized yet for this op */
@@ -1317,6 +1324,7 @@
OP_READ_DEVICE_IDENTIFIERS, // READ_DEVICE_IDENTIFIERS
OP_ACCESS_MEDIA_LOCATION, // ACCESS_MEDIA_LOCATION
OP_QUERY_ALL_PACKAGES, // QUERY_ALL_PACKAGES
+ OP_MANAGE_EXTERNAL_STORAGE, // MANAGE_EXTERNAL_STORAGE
};
/**
@@ -1415,6 +1423,7 @@
OPSTR_READ_DEVICE_IDENTIFIERS,
OPSTR_ACCESS_MEDIA_LOCATION,
OPSTR_QUERY_ALL_PACKAGES,
+ OPSTR_MANAGE_EXTERNAL_STORAGE,
};
/**
@@ -1514,6 +1523,7 @@
"READ_DEVICE_IDENTIFIERS",
"ACCESS_MEDIA_LOCATION",
"QUERY_ALL_PACKAGES",
+ "MANAGE_EXTERNAL_STORAGE"
};
/**
@@ -1614,6 +1624,7 @@
null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS
Manifest.permission.ACCESS_MEDIA_LOCATION,
null, // no permission for OP_QUERY_ALL_PACKAGES
+ null, // no permission for OP_MANAGE_EXTERNAL_STORAGE
};
/**
@@ -1714,6 +1725,7 @@
null, // READ_DEVICE_IDENTIFIERS
null, // ACCESS_MEDIA_LOCATION
null, // QUERY_ALL_PACKAGES
+ null, // MANAGE_EXTERNAL_STORAGE
};
/**
@@ -1813,6 +1825,7 @@
false, // READ_DEVICE_IDENTIFIERS
false, // ACCESS_MEDIA_LOCATION
false, // QUERY_ALL_PACKAGES
+ false, // MANAGE_EXTERNAL_STORAGE
};
/**
@@ -1911,6 +1924,7 @@
AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS
AppOpsManager.MODE_ALLOWED, // ALLOW_MEDIA_LOCATION
AppOpsManager.MODE_DEFAULT, // QUERY_ALL_PACKAGES
+ AppOpsManager.MODE_DEFAULT, // MANAGE_EXTERNAL_STORAGE
};
/**
@@ -2013,6 +2027,7 @@
false, // READ_DEVICE_IDENTIFIERS
false, // ACCESS_MEDIA_LOCATION
false, // QUERY_ALL_PACKAGES
+ false, // MANAGE_EXTERNAL_STORAGE
};
/**
@@ -2245,6 +2260,7 @@
* Class holding all of the operation information associated with an app.
* @hide
*/
+ @TestApi
@SystemApi
public static final class PackageOps implements Parcelable {
private final String mPackageName;
@@ -2288,7 +2304,7 @@
}
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(mPackageName);
dest.writeInt(mUid);
dest.writeInt(mEntries.size());
@@ -2319,537 +2335,878 @@
}
/**
- * Class holding the information about one unique operation of a
- * {@link Context#createFeatureContext(String) feature}.
+ * Proxy information for a {@link #noteOp} event
+ *
+ * @hide
+ */
+ @TestApi
+ @SystemApi
+ @Immutable
+ @DataClass(genHiddenConstructor = true)
+ public static final class OpEventProxyInfo implements Parcelable {
+ /** UID of the proxy app that noted the op */
+ private final @IntRange(from = 0) int mUid;
+ /** Package of the proxy that noted the op */
+ private final @Nullable String mPackageName;
+ /** ID of the feature of the proxy that noted the op */
+ private final @Nullable String mFeatureId;
+
+
+
+ // Code below generated by codegen v1.0.14.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
+
+ /**
+ * Creates a new OpEventProxyInfo.
+ *
+ * @param uid
+ * UID of the proxy app that noted the op
+ * @param packageName
+ * Package of the proxy that noted the op
+ * @param featureId
+ * ID of the feature of the proxy that noted the op
+ * @hide
+ */
+ @DataClass.Generated.Member
+ public OpEventProxyInfo(
+ @IntRange(from = 0) int uid,
+ @Nullable String packageName,
+ @Nullable String featureId) {
+ this.mUid = uid;
+ com.android.internal.util.AnnotationValidations.validate(
+ IntRange.class, null, mUid,
+ "from", 0);
+ this.mPackageName = packageName;
+ this.mFeatureId = featureId;
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ /**
+ * UID of the proxy app that noted the op
+ */
+ @DataClass.Generated.Member
+ public @IntRange(from = 0) int getUid() {
+ return mUid;
+ }
+
+ /**
+ * Package of the proxy that noted the op
+ */
+ @DataClass.Generated.Member
+ public @Nullable String getPackageName() {
+ return mPackageName;
+ }
+
+ /**
+ * ID of the feature of the proxy that noted the op
+ */
+ @DataClass.Generated.Member
+ public @Nullable String getFeatureId() {
+ return mFeatureId;
+ }
+
+ @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) { ... }
+
+ byte flg = 0;
+ if (mPackageName != null) flg |= 0x2;
+ if (mFeatureId != null) flg |= 0x4;
+ dest.writeByte(flg);
+ dest.writeInt(mUid);
+ if (mPackageName != null) dest.writeString(mPackageName);
+ if (mFeatureId != null) dest.writeString(mFeatureId);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ /* package-private */ OpEventProxyInfo(@NonNull Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ byte flg = in.readByte();
+ int uid = in.readInt();
+ String packageName = (flg & 0x2) == 0 ? null : in.readString();
+ String featureId = (flg & 0x4) == 0 ? null : in.readString();
+
+ this.mUid = uid;
+ com.android.internal.util.AnnotationValidations.validate(
+ IntRange.class, null, mUid,
+ "from", 0);
+ this.mPackageName = packageName;
+ this.mFeatureId = featureId;
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<OpEventProxyInfo> CREATOR
+ = new Parcelable.Creator<OpEventProxyInfo>() {
+ @Override
+ public OpEventProxyInfo[] newArray(int size) {
+ return new OpEventProxyInfo[size];
+ }
+
+ @Override
+ public OpEventProxyInfo createFromParcel(@NonNull Parcel in) {
+ return new OpEventProxyInfo(in);
+ }
+ };
+
+ @DataClass.Generated(
+ time = 1576194071700L,
+ codegenVersion = "1.0.14",
+ sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
+ inputSignatures = "private final @android.annotation.IntRange(from=0L) int mUid\nprivate final @android.annotation.Nullable java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mFeatureId\nclass OpEventProxyInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
+ @Deprecated
+ private void __metadata() {}
+
+
+ //@formatter:on
+ // End of generated code
+
+ }
+
+ /**
+ * Description of a {@link #noteOp} or {@link #startOp} event
+ *
+ * @hide
+ */
+ @Immutable
+ //@DataClass codegen verifier is broken
+ public static final class NoteOpEvent implements Parcelable {
+ /** Time of noteOp event */
+ public final @IntRange(from = 0) long noteTime;
+ /** The duration of this event (in case this is a startOp event, -1 otherwise). */
+ public final @IntRange(from = -1) long duration;
+ /** Proxy information of the noteOp event */
+ public final @Nullable OpEventProxyInfo proxy;
+
+
+ // Code below generated by codegen v1.0.14.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
+
+ /**
+ * Creates a new NoteOpEvent.
+ *
+ * @param noteTime
+ * Time of noteOp event
+ * @param duration
+ * The duration of this event (in case this is a startOp event, -1 otherwise).
+ * @param proxy
+ * Proxy information of the noteOp event
+ */
+ @DataClass.Generated.Member
+ public NoteOpEvent(
+ @IntRange(from = 0) long noteTime,
+ @IntRange(from = -1) long duration,
+ @Nullable OpEventProxyInfo proxy) {
+ this.noteTime = noteTime;
+ com.android.internal.util.AnnotationValidations.validate(
+ IntRange.class, null, noteTime,
+ "from", 0);
+ this.duration = duration;
+ com.android.internal.util.AnnotationValidations.validate(
+ IntRange.class, null, duration,
+ "from", -1);
+ this.proxy = proxy;
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @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) { ... }
+
+ byte flg = 0;
+ if (proxy != null) flg |= 0x4;
+ dest.writeByte(flg);
+ dest.writeLong(noteTime);
+ dest.writeLong(duration);
+ if (proxy != null) dest.writeTypedObject(proxy, flags);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ /* package-private */ NoteOpEvent(@NonNull Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ byte flg = in.readByte();
+ long _noteTime = in.readLong();
+ long _duration = in.readLong();
+ OpEventProxyInfo _proxy = (flg & 0x4) == 0 ? null : (OpEventProxyInfo) in.readTypedObject(
+ OpEventProxyInfo.CREATOR);
+
+ this.noteTime = _noteTime;
+ com.android.internal.util.AnnotationValidations.validate(
+ IntRange.class, null, noteTime,
+ "from", 0);
+ this.duration = _duration;
+ com.android.internal.util.AnnotationValidations.validate(
+ IntRange.class, null, duration,
+ "from", -1);
+ this.proxy = _proxy;
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<NoteOpEvent> CREATOR
+ = new Parcelable.Creator<NoteOpEvent>() {
+ @Override
+ public NoteOpEvent[] newArray(int size) {
+ return new NoteOpEvent[size];
+ }
+
+ @Override
+ public NoteOpEvent createFromParcel(@NonNull Parcel in) {
+ return new NoteOpEvent(in);
+ }
+ };
+
+ /*
+ @DataClass.Generated(
+ time = 1574809856220L,
+ codegenVersion = "1.0.14",
+ sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
+ inputSignatures = "public final @android.annotation.IntRange(from=0L) long noteTime\npublic final @android.annotation.IntRange(from=-1) long duration\npublic final @android.annotation.Nullable android.app.NoteOpEventProxyInfo proxy\nclass NoteOpEvent extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass")
+ @Deprecated
+ private void __metadata() {}
+ */
+
+
+ //@formatter:on
+ // End of generated code
+
+ }
+
+ /**
+ * Last {@link #noteOp} and {@link #startOp} events performed for a single op and a specific
+ * {@link Context#createFeatureContext(String) feature} for all uidModes and opFlags.
+ *
+ * @hide
+ */
+ @TestApi
+ @SystemApi
+ @Immutable
+ // @DataClass(genHiddenConstructor = true) codegen verifier is broken
+ @DataClass.Suppress({"getAccessEvents", "getRejectEvents", "getOp"})
+ public static final class OpFeatureEntry implements Parcelable {
+ /** The code of the op */
+ private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp;
+ /** Whether the op is running */
+ private final boolean mRunning;
+ /** The access events */
+ @DataClass.ParcelWith(LongSparseArrayParceling.class)
+ private final @Nullable LongSparseArray<NoteOpEvent> mAccessEvents;
+ /** The rejection events */
+ @DataClass.ParcelWith(LongSparseArrayParceling.class)
+ private final @Nullable LongSparseArray<NoteOpEvent> mRejectEvents;
+
+ /**
+ * Returns all keys for which we have events.
+ *
+ * @hide
+ */
+ public @NonNull ArraySet<Long> collectKeys() {
+ ArraySet<Long> keys = new ArraySet<>();
+
+ if (mAccessEvents != null) {
+ int numEvents = mAccessEvents.size();
+ for (int i = 0; i < numEvents; i++) {
+ keys.add(mAccessEvents.keyAt(i));
+ }
+ }
+
+ if (mRejectEvents != null) {
+ int numEvents = mRejectEvents.size();
+ for (int i = 0; i < numEvents; i++) {
+ keys.add(mRejectEvents.keyAt(i));
+ }
+ }
+
+ return keys;
+ }
+
+ /**
+ * Return the last access time.
+ *
+ * @param flags The op flags
+ *
+ * @return the last access time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastAccessForegroundTime(int)
+ * @see #getLastAccessBackgroundTime(int)
+ * @see #getLastAccessTime(int, int, int)
+ * @see OpEntry#getLastAccessTime(int)
+ */
+ public long getLastAccessTime(@OpFlags int flags) {
+ return getLastAccessTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
+ }
+
+ /**
+ * Return the last foreground access time.
+ *
+ * @param flags The op flags
+ *
+ * @return the last access time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastAccessTime(int)
+ * @see #getLastAccessBackgroundTime(int)
+ * @see #getLastAccessTime(int, int, int)
+ * @see OpEntry#getLastAccessForegroundTime(int)
+ */
+ public long getLastAccessForegroundTime(@OpFlags int flags) {
+ return getLastAccessTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
+ flags);
+ }
+
+ /**
+ * Return the last background access time.
+ *
+ * @param flags The op flags
+ *
+ * @return the last access time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastAccessTime(int)
+ * @see #getLastAccessForegroundTime(int)
+ * @see #getLastAccessTime(int, int, int)
+ * @see OpEntry#getLastAccessBackgroundTime(int)
+ */
+ public long getLastAccessBackgroundTime(@OpFlags int flags) {
+ return getLastAccessTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
+ flags);
+ }
+
+ /**
+ * Return the last access event.
+ *
+ * @param flags The op flags
+ *
+ * @return the last access event of {@code null}
+ */
+ private @Nullable NoteOpEvent getLastAccessEvent(@UidState int fromUidState,
+ @UidState int toUidState, @OpFlags int flags) {
+ return getLastEvent(mAccessEvents, fromUidState, toUidState, flags);
+ }
+
+ /**
+ * Return the last access time.
+ *
+ * @param fromUidState The lowest UID state for which to query
+ * @param toUidState The highest UID state for which to query (inclusive)
+ * @param flags The op flags
+ *
+ * @return the last access time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastAccessTime(int)
+ * @see #getLastAccessForegroundTime(int)
+ * @see #getLastAccessBackgroundTime(int)
+ * @see OpEntry#getLastAccessTime(int, int, int)
+ */
+ public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
+ @OpFlags int flags) {
+ NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
+ if (lastEvent == null) {
+ return -1;
+ }
+
+ return lastEvent.noteTime;
+ }
+
+ /**
+ * Return the last rejection time.
+ *
+ * @param flags The op flags
+ *
+ * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastRejectForegroundTime(int)
+ * @see #getLastRejectBackgroundTime(int)
+ * @see #getLastRejectTime(int, int, int)
+ * @see OpEntry#getLastRejectTime(int)
+ */
+ public long getLastRejectTime(@OpFlags int flags) {
+ return getLastRejectTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
+ }
+
+ /**
+ * Return the last foreground rejection time.
+ *
+ * @param flags The op flags
+ *
+ * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastRejectTime(int)
+ * @see #getLastRejectBackgroundTime(int)
+ * @see #getLastRejectTime(int, int, int)
+ * @see OpEntry#getLastRejectForegroundTime(int)
+ */
+ public long getLastRejectForegroundTime(@OpFlags int flags) {
+ return getLastRejectTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
+ flags);
+ }
+
+ /**
+ * Return the last background rejection time.
+ *
+ * @param flags The op flags
+ *
+ * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastRejectTime(int)
+ * @see #getLastRejectForegroundTime(int)
+ * @see #getLastRejectTime(int, int, int)
+ * @see OpEntry#getLastRejectBackgroundTime(int)
+ */
+ public long getLastRejectBackgroundTime(@OpFlags int flags) {
+ return getLastRejectTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
+ flags);
+ }
+
+ /**
+ * Return the last background rejection event.
+ *
+ * @param flags The op flags
+ *
+ * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastRejectTime(int)
+ * @see #getLastRejectForegroundTime(int)
+ * @see #getLastRejectBackgroundTime(int)
+ * @see OpEntry#getLastRejectTime(int, int, int)
+ */
+ private @Nullable NoteOpEvent getLastRejectEvent(@UidState int fromUidState,
+ @UidState int toUidState, @OpFlags int flags) {
+ return getLastEvent(mRejectEvents, fromUidState, toUidState, flags);
+ }
+
+ /**
+ * Return the last rejection time.
+ *
+ * @param fromUidState The lowest UID state for which to query
+ * @param toUidState The highest UID state for which to query (inclusive)
+ * @param flags The op flags
+ *
+ * @return the last access time (in milliseconds since epoch) or {@code -1}
+ *
+ * @see #getLastRejectTime(int)
+ * @see #getLastRejectForegroundTime(int)
+ * @see #getLastRejectForegroundTime(int)
+ * @see #getLastRejectTime(int, int, int)
+ * @see OpEntry#getLastRejectTime(int, int, int)
+ */
+ public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
+ @OpFlags int flags) {
+ NoteOpEvent lastEvent = getLastRejectEvent(fromUidState, toUidState, flags);
+ if (lastEvent == null) {
+ return -1;
+ }
+
+ return lastEvent.noteTime;
+ }
+
+ /**
+ * Return the duration in milliseconds of the last the access.
+ *
+ * @param flags The op flags
+ *
+ * @return the duration in milliseconds or {@code -1}
+ *
+ * @see #getLastForegroundDuration(int)
+ * @see #getLastBackgroundDuration(int)
+ * @see #getLastDuration(int, int, int)
+ * @see OpEntry#getLastDuration(int)
+ */
+ public long getLastDuration(@OpFlags int flags) {
+ return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
+ }
+
+ /**
+ * Return the duration in milliseconds of the last foreground access.
+ *
+ * @param flags The op flags
+ *
+ * @return the duration in milliseconds or {@code -1}
+ *
+ * @see #getLastDuration(int)
+ * @see #getLastBackgroundDuration(int)
+ * @see #getLastDuration(int, int, int)
+ * @see OpEntry#getLastForegroundDuration(int)
+ */
+ public long getLastForegroundDuration(@OpFlags int flags) {
+ return getLastDuration(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
+ flags);
+ }
+
+ /**
+ * Return the duration in milliseconds of the last background access.
+ *
+ * @param flags The op flags
+ *
+ * @return the duration in milliseconds or {@code -1}
+ *
+ * @see #getLastDuration(int)
+ * @see #getLastForegroundDuration(int)
+ * @see #getLastDuration(int, int, int)
+ * @see OpEntry#getLastBackgroundDuration(int)
+ */
+ public long getLastBackgroundDuration(@OpFlags int flags) {
+ return getLastDuration(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
+ flags);
+ }
+
+ /**
+ * Return the duration in milliseconds of the last access.
+ *
+ * @param fromUidState The lowest UID state for which to query
+ * @param toUidState The highest UID state for which to query (inclusive)
+ * @param flags The op flags
+ *
+ * @return the duration in milliseconds or {@code -1}
+ *
+ * @see #getLastDuration(int)
+ * @see #getLastForegroundDuration(int)
+ * @see #getLastBackgroundDuration(int)
+ * @see #getLastDuration(int, int, int)
+ * @see OpEntry#getLastDuration(int, int, int)
+ */
+ public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
+ @OpFlags int flags) {
+ NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);;
+ if (lastEvent == null) {
+ return -1;
+ }
+
+ return lastEvent.duration;
+ }
+
+ /**
+ * Gets the proxy info of the app that performed the last access on behalf of this feature
+ * and as a result blamed the op on this app.
+ *
+ * @param flags The op flags
+ *
+ * @return The proxy name or {@code null}
+ *
+ * @see #getLastForegroundProxyInfo(int)
+ * @see #getLastBackgroundProxyInfo(int)
+ * @see #getLastProxyInfo(int, int, int)
+ * @see OpEntry#getLastProxyInfo(int)
+ */
+ public @Nullable OpEventProxyInfo getLastProxyInfo(@OpFlags int flags) {
+ return getLastProxyInfo(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
+ }
+
+ /**
+ * Gets the proxy info of the app that performed the last foreground access on behalf of
+ * this feature and as a result blamed the op on this app.
+ *
+ * @param flags The op flags
+ *
+ * @return The proxy name or {@code null}
+ *
+ * @see #getLastProxyInfo(int)
+ * @see #getLastBackgroundProxyInfo(int)
+ * @see #getLastProxyInfo(int, int, int)
+ * @see OpEntry#getLastForegroundProxyInfo(int)
+ */
+ public @Nullable OpEventProxyInfo getLastForegroundProxyInfo(@OpFlags int flags) {
+ return getLastProxyInfo(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
+ flags);
+ }
+
+ /**
+ * Gets the proxy info of the app that performed the last background access on behalf of
+ * this feature and as a result blamed the op on this app.
+ *
+ * @param flags The op flags
+ *
+ * @return The proxy name or {@code null}
+ *
+ * @see #getLastProxyInfo(int)
+ * @see #getLastForegroundProxyInfo(int)
+ * @see #getLastProxyInfo(int, int, int)
+ * @see OpEntry#getLastBackgroundProxyInfo(int)
+ */
+ public @Nullable OpEventProxyInfo getLastBackgroundProxyInfo(@OpFlags int flags) {
+ return getLastProxyInfo(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
+ flags);
+ }
+
+ /**
+ * Gets the proxy info of the app that performed the last access on behalf of this feature
+ * and as a result blamed the op on this app.
+ *
+ * @param fromUidState The lowest UID state for which to query
+ * @param toUidState The highest UID state for which to query (inclusive)
+ * @param flags The op flags
+ *
+ * @return The proxy name or {@code null}
+ *
+ * @see #getLastProxyInfo(int)
+ * @see #getLastForegroundProxyInfo(int)
+ * @see #getLastBackgroundProxyInfo(int)
+ * @see OpEntry#getLastProxyInfo(int, int, int)
+ */
+ public @Nullable OpEventProxyInfo getLastProxyInfo(@UidState int fromUidState,
+ @UidState int toUidState, @OpFlags int flags) {
+ NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
+ if (lastEvent == null) {
+ return null;
+ }
+
+ return lastEvent.proxy;
+ }
+
+ private static class LongSparseArrayParceling implements
+ Parcelling<LongSparseArray<NoteOpEvent>> {
+ @Override
+ public void parcel(@Nullable LongSparseArray<NoteOpEvent> array, @NonNull Parcel dest,
+ int parcelFlags) {
+ if (array == null) {
+ dest.writeInt(-1);
+ return;
+ }
+
+ int numEntries = array.size();
+ dest.writeInt(numEntries);
+
+ for (int i = 0; i < numEntries; i++) {
+ dest.writeLong(array.keyAt(i));
+ dest.writeParcelable(array.valueAt(i), parcelFlags);
+ }
+ }
+
+ @Override
+ public @Nullable LongSparseArray<NoteOpEvent> unparcel(@NonNull Parcel source) {
+ int numEntries = source.readInt();
+ if (numEntries == -1) {
+ return null;
+ }
+
+ LongSparseArray<NoteOpEvent> array = new LongSparseArray<>(numEntries);
+
+ for (int i = 0; i < numEntries; i++) {
+ array.put(source.readLong(), source.readParcelable(null));
+ }
+
+ return array;
+ }
+ }
+
+
+
+ // Code below generated by codegen v1.0.14.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
+
+ /**
+ * Creates a new OpFeatureEntry.
+ *
+ * @param op
+ * The code of the op
+ * @param running
+ * Whether the op is running
+ * @param accessEvents
+ * The access events
+ * @param rejectEvents
+ * The rejection events
+ * @hide
+ */
+ @DataClass.Generated.Member
+ public OpFeatureEntry(
+ @IntRange(from = 0, to = _NUM_OP - 1) int op,
+ boolean running,
+ @Nullable LongSparseArray<NoteOpEvent> accessEvents,
+ @Nullable LongSparseArray<NoteOpEvent> rejectEvents) {
+ this.mOp = op;
+ com.android.internal.util.AnnotationValidations.validate(
+ IntRange.class, null, mOp,
+ "from", 0,
+ "to", _NUM_OP - 1);
+ this.mRunning = running;
+ this.mAccessEvents = accessEvents;
+ this.mRejectEvents = rejectEvents;
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ /**
+ * Whether the op is running
+ */
+ @DataClass.Generated.Member
+ public boolean isRunning() {
+ return mRunning;
+ }
+
+ @DataClass.Generated.Member
+ static Parcelling<LongSparseArray<NoteOpEvent>> sParcellingForAccessEvents =
+ Parcelling.Cache.get(
+ LongSparseArrayParceling.class);
+ static {
+ if (sParcellingForAccessEvents == null) {
+ sParcellingForAccessEvents = Parcelling.Cache.put(
+ new LongSparseArrayParceling());
+ }
+ }
+
+ @DataClass.Generated.Member
+ static Parcelling<LongSparseArray<NoteOpEvent>> sParcellingForRejectEvents =
+ Parcelling.Cache.get(
+ LongSparseArrayParceling.class);
+ static {
+ if (sParcellingForRejectEvents == null) {
+ sParcellingForRejectEvents = Parcelling.Cache.put(
+ new LongSparseArrayParceling());
+ }
+ }
+
+ @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) { ... }
+
+ byte flg = 0;
+ if (mRunning) flg |= 0x2;
+ if (mAccessEvents != null) flg |= 0x4;
+ if (mRejectEvents != null) flg |= 0x8;
+ dest.writeByte(flg);
+ dest.writeInt(mOp);
+ sParcellingForAccessEvents.parcel(mAccessEvents, dest, flags);
+ sParcellingForRejectEvents.parcel(mRejectEvents, dest, flags);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ /* package-private */ OpFeatureEntry(@NonNull Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ byte flg = in.readByte();
+ boolean running = (flg & 0x2) != 0;
+ int op = in.readInt();
+ LongSparseArray<NoteOpEvent> accessEvents = sParcellingForAccessEvents.unparcel(in);
+ LongSparseArray<NoteOpEvent> rejectEvents = sParcellingForRejectEvents.unparcel(in);
+
+ this.mOp = op;
+ com.android.internal.util.AnnotationValidations.validate(
+ IntRange.class, null, mOp,
+ "from", 0,
+ "to", _NUM_OP - 1);
+ this.mRunning = running;
+ this.mAccessEvents = accessEvents;
+ this.mRejectEvents = rejectEvents;
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<OpFeatureEntry> CREATOR
+ = new Parcelable.Creator<OpFeatureEntry>() {
+ @Override
+ public OpFeatureEntry[] newArray(int size) {
+ return new OpFeatureEntry[size];
+ }
+
+ @Override
+ public OpFeatureEntry createFromParcel(@NonNull Parcel in) {
+ return new OpFeatureEntry(in);
+ }
+ };
+
+ /*
+ @DataClass.Generated(
+ time = 1574809856239L,
+ codegenVersion = "1.0.14",
+ sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
+ inputSignatures = "private final @android.annotation.IntRange(from=0L, to=_NUM_OP - 1) int mOp\nprivate final boolean mRunning\nprivate final @com.android.internal.util.DataClass.ParcelWith(android.app.OpFeatureEntry.LongSparseArrayParceling.class) @android.annotation.Nullable android.util.LongSparseArray<android.app.NoteOpEvent> mAccessEvents\nprivate final @com.android.internal.util.DataClass.ParcelWith(android.app.OpFeatureEntry.LongSparseArrayParceling.class) @android.annotation.Nullable android.util.LongSparseArray<android.app.NoteOpEvent> mRejectEvents\npublic @android.annotation.NonNull android.util.ArraySet<java.lang.Long> collectKeys()\npublic @android.app.UidState int getLastAccessUidState(int)\npublic @android.app.UidState int getLastForegroundAccessUidState(int)\npublic @android.app.UidState int getLastBackgroundAccessUidState(int)\npublic @android.app.UidState int getLastRejectUidState(int)\npublic @android.app.UidState int getLastForegroundRejectUidState(int)\npublic @android.app.UidState int getLastBackgroundRejectUidState(int)\npublic long getAccessTime(int,int)\npublic long getRejectTime(int,int)\npublic long getDuration(int,int)\npublic int getProxyUid(int,int)\npublic @android.annotation.Nullable java.lang.String getProxyPackageName(int,int)\npublic @android.annotation.Nullable java.lang.String getProxyFeatureId(int,int)\nclass OpFeatureEntry extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
+ @Deprecated
+ private void __metadata() {}
+ */
+
+
+ //@formatter:on
+ // End of generated code
+
+ }
+
+ /**
+ * Last {@link #noteOp} and {@link #startOp} events performed for a single op for all uidModes
+ * and opFlags.
*
* @hide
*/
@TestApi
@Immutable
@SystemApi
- public static final class OpFeatureEntry {
- private final @NonNull OpEntry mParent;
- private final boolean mRunning;
-
- private final @Nullable LongSparseLongArray mAccessTimes;
- private final @Nullable LongSparseLongArray mRejectTimes;
- private final @Nullable LongSparseLongArray mDurations;
- private final @Nullable LongSparseLongArray mProxyUids;
- private final @Nullable LongSparseArray<String> mProxyPackageNames;
- private final @Nullable LongSparseArray<String> mProxyFeatureIds;
-
- /**
- * @hide
- */
- public OpFeatureEntry(@NonNull OpEntry parent, boolean running,
- @Nullable LongSparseLongArray accessTimes,
- @Nullable LongSparseLongArray rejectTimes,
- @Nullable LongSparseLongArray durations, @Nullable LongSparseLongArray proxyUids,
- @Nullable LongSparseArray<String> proxyPackageNames,
- @Nullable LongSparseArray<String> proxyFeatureIds) {
- mParent = Preconditions.checkNotNull(parent);
- mRunning = running;
- mAccessTimes = accessTimes;
- mRejectTimes = rejectTimes;
- mDurations = durations;
- mProxyUids = proxyUids;
- mProxyPackageNames = proxyPackageNames;
- mProxyFeatureIds = proxyFeatureIds;
- }
-
- /**
- * Returns all keys for which we have mapped state in any of the data buckets -
- * access time, reject time, duration.
- * @hide */
- public @Nullable LongSparseArray<Object> collectKeys() {
- LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessTimes, null);
- result = AppOpsManager.collectKeys(mRejectTimes, result);
- result = AppOpsManager.collectKeys(mDurations, result);
- return result;
- }
-
- /**
- * @hide
- */
- public long getTime() {
- return getLastAccessTime(OP_FLAGS_ALL);
- }
-
- /**
- * Return the last wall clock time in milliseconds this op was accessed.
- *
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last access time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
- *
- * @see #getLastAccessForegroundTime(int)
- * @see #getLastAccessBackgroundTime(int)
- * @see #getLastAccessTime(int, int, int)
- */
- public long getLastAccessTime(@OpFlags int flags) {
- return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
- MIN_PRIORITY_UID_STATE, flags);
- }
-
- /**
- * Return the last wall clock time in milliseconds this op was accessed
- * by the app while in the foreground.
- *
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last foreground access time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
- *
- * @see #getLastAccessBackgroundTime(int)
- * @see #getLastAccessTime(int)
- * @see #getLastAccessTime(int, int, int)
- */
- public long getLastAccessForegroundTime(@OpFlags int flags) {
- return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
- resolveFirstUnrestrictedUidState(mParent.mOp), flags);
- }
-
- /**
- * Return the last wall clock time in milliseconds this op was accessed
- * by the app while in the background.
- *
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last foreground access time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
- *
- * @see #getLastAccessForegroundTime(int)
- * @see #getLastAccessTime(int)
- * @see #getLastAccessTime(int, int, int)
- */
- public long getLastAccessBackgroundTime(@OpFlags int flags) {
- return maxForFlagsInStates(mAccessTimes, resolveLastRestrictedUidState(mParent.mOp),
- MIN_PRIORITY_UID_STATE, flags);
- }
-
- /**
- * Return the last wall clock time in milliseconds this op was accessed
- * by the app for a given range of UID states.
- *
- * @param fromUidState The UID state for which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param toUidState The UID state for which to query.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- *
- * @return the last foreground access time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
- *
- * @see #getLastAccessForegroundTime(int)
- * @see #getLastAccessBackgroundTime(int)
- * @see #getLastAccessTime(int)
- */
- public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
- @OpFlags int flags) {
- return maxForFlagsInStates(mAccessTimes, fromUidState, toUidState, flags);
- }
-
- /**
- * @hide
- */
- public long getRejectTime() {
- return getLastRejectTime(OP_FLAGS_ALL);
- }
-
- /**
- * Return the last wall clock time in milliseconds the app made an attempt
- * to access this op but was rejected.
- *
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last reject time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
- *
- * @see #getLastRejectBackgroundTime(int)
- * @see #getLastRejectForegroundTime(int)
- * @see #getLastRejectTime(int, int, int)
- */
- public long getLastRejectTime(@OpFlags int flags) {
- return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
- MIN_PRIORITY_UID_STATE, flags);
- }
-
- /**
- * Return the last wall clock time in milliseconds the app made an attempt
- * to access this op while in the foreground but was rejected.
- *
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last foreground reject time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
- *
- * @see #getLastRejectBackgroundTime(int)
- * @see #getLastRejectTime(int, int, int)
- * @see #getLastRejectTime(int)
- */
- public long getLastRejectForegroundTime(@OpFlags int flags) {
- return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
- resolveFirstUnrestrictedUidState(mParent.mOp), flags);
- }
-
- /**
- * Return the last wall clock time in milliseconds the app made an attempt
- * to access this op while in the background but was rejected.
- *
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last background reject time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
- *
- * @see #getLastRejectForegroundTime(int)
- * @see #getLastRejectTime(int, int, int)
- * @see #getLastRejectTime(int)
- */
- public long getLastRejectBackgroundTime(@OpFlags int flags) {
- return maxForFlagsInStates(mRejectTimes, resolveLastRestrictedUidState(mParent.mOp),
- MIN_PRIORITY_UID_STATE, flags);
- }
-
- /**
- * Return the last wall clock time state in milliseconds the app made an
- * attempt to access this op for a given range of UID states.
- *
- * @param fromUidState The UID state from which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param toUidState The UID state to which to query.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last foreground access time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
- *
- * @see #getLastRejectForegroundTime(int)
- * @see #getLastRejectBackgroundTime(int)
- * @see #getLastRejectTime(int)
- */
- public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
- @OpFlags int flags) {
- return maxForFlagsInStates(mRejectTimes, fromUidState, toUidState, flags);
- }
-
- /**
- * @return Whether the operation is running.
- */
- public boolean isRunning() {
- return mRunning;
- }
-
- /**
- * @return The duration of the operation in milliseconds. The duration is in wall time.
- */
- public long getDuration() {
- return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
- }
-
- /**
- * Return the duration in milliseconds the app accessed this op while
- * in the foreground. The duration is in wall time.
- *
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the foreground access duration in milliseconds.
- *
- * @see #getLastBackgroundDuration(int)
- * @see #getLastDuration(int, int, int)
- */
- public long getLastForegroundDuration(@OpFlags int flags) {
- return sumForFlagsInStates(mDurations, MAX_PRIORITY_UID_STATE,
- resolveFirstUnrestrictedUidState(mParent.mOp), flags);
- }
-
- /**
- * Return the duration in milliseconds the app accessed this op while
- * in the background. The duration is in wall time.
- *
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the background access duration in milliseconds.
- *
- * @see #getLastForegroundDuration(int)
- * @see #getLastDuration(int, int, int)
- */
- public long getLastBackgroundDuration(@OpFlags int flags) {
- return sumForFlagsInStates(mDurations, resolveLastRestrictedUidState(mParent.mOp),
- MIN_PRIORITY_UID_STATE, flags);
- }
-
- /**
- * Return the duration in milliseconds the app accessed this op for
- * a given range of UID states. The duration is in wall time.
- *
- * @param fromUidState The UID state for which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param toUidState The UID state for which to query.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the access duration in milliseconds.
- */
- public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
- @OpFlags int flags) {
- return sumForFlagsInStates(mDurations, fromUidState, toUidState, flags);
- }
-
- /**
- * Gets the UID of the app that performed the op on behalf of this app and
- * as a result blamed the op on this app or {@link Process#INVALID_UID} if
- * there is no proxy.
- *
- * @return The proxy UID.
- */
- public int getProxyUid() {
- return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
- MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
- }
-
- /**
- * Gets the UID of the app that performed the op on behalf of this app and
- * as a result blamed the op on this app or {@link Process#INVALID_UID} if
- * there is no proxy.
- *
- * @param uidState The UID state for which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- *
- * @return The proxy UID.
- */
- public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
- return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
- uidState, uidState, flags);
- }
-
- /**
- * Gets the package name of the app that performed the op on behalf of this
- * app and as a result blamed the op on this app or {@code null}
- * if there is no proxy.
- *
- * @return The proxy package name.
- */
- public @Nullable String getProxyPackageName() {
- return findFirstNonNullForFlagsInStates(mProxyPackageNames, MAX_PRIORITY_UID_STATE,
- MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
- }
-
- /**
- * Gets the package name of the app that performed the op on behalf of this
- * app and as a result blamed the op on this app for a UID state or
- * {@code null} if there is no proxy.
- *
- * @param uidState The UID state for which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return The feature id.
- */
- public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
- return findFirstNonNullForFlagsInStates(mProxyPackageNames, uidState, uidState, flags);
- }
-
- /**
- * Gets the feature of the app that performed the op on behalf of this
- * app and as a result blamed the op on this app or {@code null}
- * if there is no proxy.
- *
- * @return The proxy package name.
- */
- public @Nullable String getProxyFeatureId() {
- return findFirstNonNullForFlagsInStates(mProxyFeatureIds, MAX_PRIORITY_UID_STATE,
- MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
- }
-
- /**
- * Gets the feature of the app that performed the op on behalf of this
- * app and as a result blamed the op on this app for a UID state or
- * {@code null} if there is no proxy.
- *
- * @param uidState The UID state for which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return The feature id.
- */
- public @Nullable String getProxyFeatureId(@UidState int uidState, @OpFlags int flags) {
- return findFirstNonNullForFlagsInStates(mProxyFeatureIds, uidState, uidState, flags);
- }
-
- /**
- * @hide
- */
- public static class Builder {
- private final boolean mRunning;
-
- private final @Nullable LongSparseLongArray mAccessTimes;
- private final @Nullable LongSparseLongArray mRejectTimes;
- private final @Nullable LongSparseLongArray mDurations;
- private final @Nullable LongSparseLongArray mProxyUids;
- private final @Nullable LongSparseArray<String> mProxyPackageNames;
- private final @Nullable LongSparseArray<String> mProxyFeatureIds;
- private @NonNull OpEntry mParent;
-
- public Builder(boolean running, @Nullable LongSparseLongArray accessTimes,
- @Nullable LongSparseLongArray rejectTimes,
- @Nullable LongSparseLongArray durations,
- @Nullable LongSparseLongArray proxyUids,
- @Nullable LongSparseArray<String> proxyPackageNames,
- @Nullable LongSparseArray<String> proxyFeatureIds) {
- mRunning = running;
- mAccessTimes = accessTimes;
- mRejectTimes = rejectTimes;
- mDurations = durations;
- mProxyUids = proxyUids;
- mProxyPackageNames = proxyPackageNames;
- mProxyFeatureIds = proxyFeatureIds;
- }
-
- public Builder setParent(@NonNull OpEntry parent) {
- mParent = parent;
-
- return this;
- }
-
- /**
- * Create OpFeatureEntry from builder
- */
- public OpFeatureEntry build() {
- Preconditions.checkNotNull(mParent);
-
- return new OpFeatureEntry(mParent, mRunning, mAccessTimes, mRejectTimes,
- mDurations, mProxyUids, mProxyPackageNames, mProxyFeatureIds);
- }
- }
-
- /**
- * @hide
- */
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- LongSparseLongArray.Parcelling longSparseLongArrayParcelling =
- LongSparseLongArray.Parcelling.Cache.getOrCreate(
- LongSparseLongArray.Parcelling.class);
- LongSparseArray.StringParcelling longSparseStringArrayParcelling =
- LongSparseArray.StringParcelling.Cache.getOrCreate(
- LongSparseArray.StringParcelling.class);
-
- dest.writeBoolean(mRunning);
- longSparseLongArrayParcelling.parcel(mAccessTimes, dest, flags);
- longSparseLongArrayParcelling.parcel(mRejectTimes, dest, flags);
- longSparseLongArrayParcelling.parcel(mDurations, dest, flags);
- longSparseLongArrayParcelling.parcel(mProxyUids, dest, flags);
- longSparseStringArrayParcelling.parcel(mProxyPackageNames, dest, flags);
- longSparseStringArrayParcelling.parcel(mProxyFeatureIds, dest, flags);
- }
-
- /**
- * @hide
- */
- public static OpFeatureEntry.Builder createFromParcel(@NonNull Parcel source) {
- LongSparseLongArray.Parcelling longSparseLongArrayParcelling =
- LongSparseLongArray.Parcelling.Cache.getOrCreate(
- LongSparseLongArray.Parcelling.class);
- LongSparseArray.StringParcelling longSparseStringArrayParcelling =
- LongSparseArray.StringParcelling.Cache.getOrCreate(
- LongSparseArray.StringParcelling.class);
-
- return new OpFeatureEntry.Builder(source.readBoolean(),
- longSparseLongArrayParcelling.unparcel(source),
- longSparseLongArrayParcelling.unparcel(source),
- longSparseLongArrayParcelling.unparcel(source),
- longSparseLongArrayParcelling.unparcel(source),
- longSparseStringArrayParcelling.unparcel(source),
- longSparseStringArrayParcelling.unparcel(source));
- }
- }
-
- /**
- * Class holding the information about one unique operation of an application.
- * @hide
- */
- @TestApi
- @Immutable
- @SystemApi
+ // @DataClass(genHiddenConstructor = true) codegen verifier is broken
public static final class OpEntry implements Parcelable {
+ /** The code of the op */
private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp;
+ /** The mode of the op */
private final @Mode int mMode;
- private final @NonNull ArrayMap<String, OpFeatureEntry> mFeatures;
-
- /**
- * @hide
- */
- public OpEntry(@IntRange(from = 0, to = _NUM_OP - 1) int op, @Mode int mode,
- @NonNull Pair<String, OpFeatureEntry.Builder>[] featureBuilders) {
- mOp = Preconditions.checkArgumentInRange(op, 0, _NUM_OP - 1, "op");
- mMode = Preconditions.checkArgumentInRange(mode, 0, MODE_FOREGROUND, "mode");
-
- mFeatures = new ArrayMap<>(featureBuilders.length);
- for (Pair<String, OpFeatureEntry.Builder> feature : featureBuilders) {
- mFeatures.put(feature.first, feature.second.setParent(this).build());
- }
- }
-
- /**
- * @return The mapping from the feature ids to the feature state
- */
- public @NonNull Map<String, OpFeatureEntry> getFeatures() {
- return mFeatures;
- }
+ /** The features that have been used when checking the op */
+ private final @NonNull Map<String, OpFeatureEntry> mFeatures;
/**
* @hide
@@ -2868,16 +3225,9 @@
}
/**
- * @return this entry's current mode, such as {@link #MODE_ALLOWED}.
- */
- public @Mode int getMode() {
- return mMode;
- }
-
- /**
- * @deprecated Use {@link OpEntry#getLastAccessTime(int)} instead
- *
* @hide
+ *
+ * @deprecated Use {@link #getLastAccessTime(int)} instead
*/
@Deprecated
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
@@ -2886,130 +3236,112 @@
return getLastAccessTime(OP_FLAGS_ALL);
}
- private long getMaxOfFeatures(@NonNull ToLongFunction<OpFeatureEntry> timeGetter) {
- long max = 0;
-
- int numFeatures = mFeatures.size();
- for (int i = 0; i < numFeatures; i++) {
- max = Math.max(max, timeGetter.applyAsLong(mFeatures.valueAt(i)));
- }
-
- return max;
- }
-
- private long getSumOfFeatures(@NonNull ToLongFunction<OpFeatureEntry> getter) {
- long sum = 0;
-
- int numFeatures = mFeatures.size();
- for (int i = 0; i < numFeatures; i++) {
- sum += getter.applyAsLong(mFeatures.valueAt(i));
- }
-
- return sum;
- }
-
/**
- * Return the last wall clock time in milliseconds this op was accessed
- * by the app for a given range of UID states.
+ * Return the last access time.
*
- * @param fromUidState The UID state for which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param toUidState The UID state for which to query.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
+ * @param flags The op flags
*
- * @return the last foreground access time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ * @return the last access time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
*
* @see #getLastAccessForegroundTime(int)
* @see #getLastAccessBackgroundTime(int)
- * @see #getLastAccessTime(int)
+ * @see #getLastAccessTime(int, int, int)
+ * @see OpFeatureEntry#getLastAccessTime(int)
*/
public long getLastAccessTime(@OpFlags int flags) {
- return getMaxOfFeatures(
- (featureEntry -> featureEntry.getLastAccessTime(flags)));
+ return getLastAccessTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
}
/**
- * Return the last wall clock time in milliseconds this op was accessed
- * by the app while in the foreground.
+ * Return the last foreground access time.
*
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last foreground access time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ * @param flags The op flags
*
- * @see #getLastAccessBackgroundTime(int)
+ * @return the last access time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
* @see #getLastAccessTime(int)
+ * @see #getLastAccessBackgroundTime(int)
* @see #getLastAccessTime(int, int, int)
+ * @see OpFeatureEntry#getLastAccessForegroundTime(int)
*/
public long getLastAccessForegroundTime(@OpFlags int flags) {
- return getMaxOfFeatures(
- (featureEntry -> featureEntry.getLastAccessForegroundTime(flags)));
+ return getLastAccessTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
+ flags);
}
/**
- * Return the last wall clock time in milliseconds this op was accessed
- * by the app while in the background.
+ * Return the last background access time.
*
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last foreground access time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ * @param flags The op flags
*
- * @see #getLastAccessForegroundTime(int)
+ * @return the last access time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
* @see #getLastAccessTime(int)
+ * @see #getLastAccessForegroundTime(int)
* @see #getLastAccessTime(int, int, int)
+ * @see OpFeatureEntry#getLastAccessBackgroundTime(int)
*/
public long getLastAccessBackgroundTime(@OpFlags int flags) {
- return getMaxOfFeatures(
- (featureEntry -> featureEntry.getLastAccessBackgroundTime(flags)));
+ return getLastAccessTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
+ flags);
}
/**
- * Return the last wall clock time in milliseconds this op was accessed
- * by the app for a given range of UID states.
+ * Return the last access event.
*
- * @param fromUidState The UID state for which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param toUidState The UID state for which to query.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
+ * @param flags The op flags
*
- * @return the last foreground access time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ * @return the last access event of {@code null}
+ */
+ private @Nullable NoteOpEvent getLastAccessEvent(@UidState int fromUidState,
+ @UidState int toUidState, @OpFlags int flags) {
+ NoteOpEvent lastAccessEvent = null;
+ for (OpFeatureEntry featureEntry : mFeatures.values()) {
+ NoteOpEvent lastFeatureAccessEvent = featureEntry.getLastAccessEvent(fromUidState,
+ toUidState, flags);
+
+ if (lastAccessEvent == null || (lastFeatureAccessEvent != null
+ && lastFeatureAccessEvent.noteTime > lastAccessEvent.noteTime)) {
+ lastAccessEvent = lastFeatureAccessEvent;
+ }
+ }
+
+ return lastAccessEvent;
+ }
+
+ /**
+ * Return the last access time.
*
+ * @param fromUidState the lowest uid state to query
+ * @param toUidState the highest uid state to query (inclusive)
+ * @param flags The op flags
+ *
+ * @return the last access time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastAccessTime(int)
* @see #getLastAccessForegroundTime(int)
* @see #getLastAccessBackgroundTime(int)
- * @see #getLastAccessTime(int)
+ * @see OpFeatureEntry#getLastAccessTime(int, int, int)
*/
public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
@OpFlags int flags) {
- return getMaxOfFeatures(
- (featureEntry -> featureEntry.getLastAccessTime(fromUidState,
- toUidState, flags)));
+ NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);;
+
+ if (lastEvent == null) {
+ return -1;
+ }
+
+ return lastEvent.noteTime;
}
/**
- * @deprecated Use {@link OpEntry#getLastRejectTime(int)} instead
- *
* @hide
+ *
+ * @deprecated Use {@link #getLastRejectTime(int)} instead
*/
@Deprecated
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
@@ -3019,107 +3351,113 @@
}
/**
- * Return the last wall clock time in milliseconds the app made an attempt
- * to access this op but was rejected.
+ * Return the last rejection time.
*
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last reject time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ * @param flags The op flags
*
- * @see #getLastRejectBackgroundTime(int)
+ * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
* @see #getLastRejectForegroundTime(int)
+ * @see #getLastRejectBackgroundTime(int)
* @see #getLastRejectTime(int, int, int)
+ * @see OpFeatureEntry#getLastRejectTime(int)
*/
public long getLastRejectTime(@OpFlags int flags) {
- return getMaxOfFeatures(
- (featureEntry -> featureEntry.getLastRejectTime(flags)));
+ return getLastRejectTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
}
/**
- * Return the last wall clock time in milliseconds the app made an attempt
- * to access this op while in the foreground but was rejected.
+ * Return the last foreground rejection time.
*
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last foreground reject time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ * @param flags The op flags
*
+ * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastRejectTime(int)
* @see #getLastRejectBackgroundTime(int)
* @see #getLastRejectTime(int, int, int)
- * @see #getLastRejectTime(int)
+ * @see OpFeatureEntry#getLastRejectForegroundTime(int)
*/
public long getLastRejectForegroundTime(@OpFlags int flags) {
- return getMaxOfFeatures(
- (featureEntry -> featureEntry.getLastRejectForegroundTime(flags)));
+ return getLastRejectTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
+ flags);
}
/**
- * Return the last wall clock time in milliseconds the app made an attempt
- * to access this op while in the background but was rejected.
+ * Return the last background rejection time.
*
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last background reject time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ * @param flags The op flags
*
+ * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastRejectTime(int)
* @see #getLastRejectForegroundTime(int)
* @see #getLastRejectTime(int, int, int)
- * @see #getLastRejectTime(int)
+ * @see OpFeatureEntry#getLastRejectBackgroundTime(int)
*/
public long getLastRejectBackgroundTime(@OpFlags int flags) {
- return getMaxOfFeatures(
- (featureEntry -> featureEntry.getLastRejectBackgroundTime(flags)));
+ return getLastRejectTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
+ flags);
}
/**
- * Return the last wall clock time state in milliseconds the app made an
- * attempt to access this op for a given range of UID states.
+ * Return the last rejection event.
*
- * @param fromUidState The UID state from which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param toUidState The UID state to which to query.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the last foreground access time in milliseconds since
- * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ * @param flags The op flags
*
+ * @return the last reject event of {@code null}
+ */
+ private @Nullable NoteOpEvent getLastRejectEvent(@UidState int fromUidState,
+ @UidState int toUidState, @OpFlags int flags) {
+ NoteOpEvent lastAccessEvent = null;
+ for (OpFeatureEntry featureEntry : mFeatures.values()) {
+ NoteOpEvent lastFeatureAccessEvent = featureEntry.getLastRejectEvent(fromUidState,
+ toUidState, flags);
+
+ if (lastAccessEvent == null || (lastFeatureAccessEvent != null
+ && lastFeatureAccessEvent.noteTime > lastAccessEvent.noteTime)) {
+ lastAccessEvent = lastFeatureAccessEvent;
+ }
+ }
+
+ return lastAccessEvent;
+ }
+
+ /**
+ * Return the last rejection time.
+ *
+ * @param fromUidState the lowest uid state to query
+ * @param toUidState the highest uid state to query (inclusive)
+ * @param flags The op flags
+ *
+ * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
+ * 00:00:00.000 GMT - Gregorian)) or {@code -1}
+ *
+ * @see #getLastRejectTime(int)
* @see #getLastRejectForegroundTime(int)
* @see #getLastRejectBackgroundTime(int)
- * @see #getLastRejectTime(int)
+ * @see #getLastRejectTime(int, int, int)
+ * @see OpFeatureEntry#getLastRejectTime(int, int, int)
*/
public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
@OpFlags int flags) {
- return getMaxOfFeatures(
- (featureEntry -> featureEntry.getLastRejectTime(fromUidState,
- toUidState, flags)));
+ NoteOpEvent lastEvent = getLastRejectEvent(fromUidState, toUidState, flags);
+ if (lastEvent == null) {
+ return -1;
+ }
+
+ return lastEvent.noteTime;
}
/**
* @return Whether the operation is running.
*/
public boolean isRunning() {
- int numFeatures = mFeatures.size();
- if (mFeatures.isEmpty()) {
- return false;
- }
-
- for (int i = 0; i < numFeatures; i++) {
- if (mFeatures.valueAt(i).mRunning) {
+ for (OpFeatureEntry opFeatureEntry : mFeatures.values()) {
+ if (opFeatureEntry.isRunning()) {
return true;
}
}
@@ -3128,257 +3466,349 @@
}
/**
- * @return The duration of the operation in milliseconds. The duration is in wall time.
+ * @deprecated Use {@link #getLastDuration(int)} instead
*/
+ @Deprecated
public long getDuration() {
- return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
+ return getLastDuration(OP_FLAGS_ALL);
}
/**
- * Return the duration in milliseconds the app accessed this op while
- * in the foreground. The duration is in wall time.
+ * Return the duration in milliseconds of the last the access.
*
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the foreground access duration in milliseconds.
+ * @param flags The op flags
*
- * @see #getLastBackgroundDuration(int)
- * @see #getLastDuration(int, int, int)
- */
- public long getLastForegroundDuration(@OpFlags int flags) {
- return getSumOfFeatures((featureEntry) ->
- featureEntry.getLastForegroundDuration(flags));
- }
-
- /**
- * Return the duration in milliseconds the app accessed this op while
- * in the background. The duration is in wall time.
- *
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the background access duration in milliseconds.
+ * @return the duration in milliseconds or {@code -1}
*
* @see #getLastForegroundDuration(int)
+ * @see #getLastBackgroundDuration(int)
* @see #getLastDuration(int, int, int)
+ * @see OpFeatureEntry#getLastDuration(int)
*/
- public long getLastBackgroundDuration(@OpFlags int flags) {
- return getSumOfFeatures((featureEntry) ->
- featureEntry.getLastBackgroundDuration(flags));
+ public long getLastDuration(@OpFlags int flags) {
+ return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
}
/**
- * Return the duration in milliseconds the app accessed this op for
- * a given range of UID states. The duration is in wall time.
+ * Return the duration in milliseconds of the last foreground access.
*
- * @param fromUidState The UID state for which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param toUidState The UID state for which to query.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return the access duration in milliseconds.
+ * @param flags The op flags
+ *
+ * @return the duration in milliseconds or {@code -1}
+ *
+ * @see #getLastDuration(int)
+ * @see #getLastBackgroundDuration(int)
+ * @see #getLastDuration(int, int, int)
+ * @see OpFeatureEntry#getLastForegroundDuration(int)
+ */
+ public long getLastForegroundDuration(@OpFlags int flags) {
+ return getLastDuration(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
+ flags);
+ }
+
+ /**
+ * Return the duration in milliseconds of the last background access.
+ *
+ * @param flags The op flags
+ *
+ * @return the duration in milliseconds or {@code -1}
+ *
+ * @see #getLastDuration(int)
+ * @see #getLastForegroundDuration(int)
+ * @see #getLastDuration(int, int, int)
+ * @see OpFeatureEntry#getLastBackgroundDuration(int)
+ */
+ public long getLastBackgroundDuration(@OpFlags int flags) {
+ return getLastDuration(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
+ flags);
+ }
+
+ /**
+ * Return the duration in milliseconds of the last access.
+ *
+ * @param fromUidState The lowest UID state for which to query
+ * @param toUidState The highest UID state for which to query (inclusive)
+ * @param flags The op flags
+ *
+ * @return the duration in milliseconds or {@code -1}
+ *
+ * @see #getLastDuration(int)
+ * @see #getLastForegroundDuration(int)
+ * @see #getLastBackgroundDuration(int)
+ * @see OpFeatureEntry#getLastDuration(int, int, int)
*/
public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
@OpFlags int flags) {
- return getSumOfFeatures((featureEntry) ->
- featureEntry.getLastDuration(fromUidState, toUidState, flags));
- }
-
- /**
- * Like {@link #findFirstNonNegativeForFlagsInStates(LongSparseLongArray, int, int, int)}
- * but for all proxy uid in all features.
- */
- private long findFirstNonNegativeProxyUidInFeatureStates(@UidState int beginUidState,
- @UidState int endUidState, @OpFlags int flags) {
- int numFeatures = mFeatures.size();
-
- if (numFeatures == 0) {
+ NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
+ if (lastEvent == null) {
return -1;
}
- while (flags != 0) {
- final int flag = 1 << Integer.numberOfTrailingZeros(flags);
- flags &= ~flag;
- for (int uidState : UID_STATES) {
- if (uidState < beginUidState || uidState > endUidState) {
- continue;
- }
-
- final long key = makeKey(uidState, flag);
-
- for (int i = 0; i < numFeatures; i++) {
- OpFeatureEntry featureEntry = mFeatures.valueAt(i);
-
- if (featureEntry.mProxyUids == null) {
- continue;
- }
-
- final long proxyUid = featureEntry.mProxyUids.get(key);
- if (proxyUid >= 0) {
- return proxyUid;
- }
- }
- }
- }
-
- return -1;
+ return lastEvent.duration;
}
/**
- * Like {@link #findFirstNonNullForFlagsInStates(LongSparseArray, int, int, int)} but
- * for all proxyPackageNames in all features.
- */
- private @Nullable String findFirstNonNullProxyPackageNameInFeatureStates(
- @OpFlags int flags, @UidState int beginUidState, @UidState int endUidState) {
- int numFeatures = mFeatures.size();
-
- if (numFeatures == 0) {
- return null;
- }
-
- while (flags != 0) {
- final int flag = 1 << Integer.numberOfTrailingZeros(flags);
- flags &= ~flag;
- for (int uidState : UID_STATES) {
- if (uidState < beginUidState || uidState > endUidState) {
- continue;
- }
- final long key = makeKey(uidState, flag);
-
- for (int i = 0; i < numFeatures; i++) {
- OpFeatureEntry featureEntry = mFeatures.valueAt(i);
-
- if (featureEntry.mProxyPackageNames == null) {
- continue;
- }
-
- final String proxyName = featureEntry.mProxyPackageNames.get(key);
- if (proxyName != null) {
- return proxyName;
- }
- }
- }
- }
- return null;
- }
-
- /**
- * @deprecated Use {@link #getProxyUid(int, int)} instead
+ * @deprecated Use {@link #getLastProxyInfo(int)} instead
*/
@Deprecated
public int getProxyUid() {
- return (int) findFirstNonNegativeProxyUidInFeatureStates(MAX_PRIORITY_UID_STATE,
- MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
+ OpEventProxyInfo proxy = getLastProxyInfo(OP_FLAGS_ALL);
+ if (proxy == null) {
+ return Process.INVALID_UID;
+ }
+
+ return proxy.getUid();
}
/**
- * Gets the UID of the app that performed the op on behalf of this app and
- * as a result blamed the op on this app or {@link Process#INVALID_UID} if
- * there is no proxy.
- *
- * @param uidState The UID state for which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- *
- * @return The proxy UID.
+ * @deprecated Use {@link #getLastProxyInfo(int)} instead
*/
+ @Deprecated
public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
- return (int) findFirstNonNegativeProxyUidInFeatureStates(uidState, uidState, flags);
+ OpEventProxyInfo proxy = getLastProxyInfo(uidState, uidState, flags);
+ if (proxy == null) {
+ return Process.INVALID_UID;
+ }
+
+ return proxy.getUid();
}
/**
- * @deprecated Use {@link #getProxyPackageName(int, int)} instead
+ * @deprecated Use {@link #getLastProxyInfo(int)} instead
*/
@Deprecated
public @Nullable String getProxyPackageName() {
- return findFirstNonNullProxyPackageNameInFeatureStates(MAX_PRIORITY_UID_STATE,
- MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
+ OpEventProxyInfo proxy = getLastProxyInfo(OP_FLAGS_ALL);
+ if (proxy == null) {
+ return null;
+ }
+
+ return proxy.getPackageName();
}
/**
- * Gets the package name of the app that performed the op on behalf of this
- * app and as a result blamed the op on this app for a UID state or
- * {@code null} if there is no proxy.
- *
- * @param uidState The UID state for which to query. Could be one of
- * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
- * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
- * @param flags The flags which are any combination of
- * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
- * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
- * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
- * for any flag.
- * @return The proxy package name.
+ * @deprecated Use {@link #getLastProxyInfo(int)} instead
*/
+ @Deprecated
public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
- return findFirstNonNullProxyPackageNameInFeatureStates(uidState, uidState, flags);
+ OpEventProxyInfo proxy = getLastProxyInfo(uidState, uidState, flags);
+ if (proxy == null) {
+ return null;
+ }
+
+ return proxy.getPackageName();
}
/**
- * Create OpEntry from parcel.
+ * Gets the proxy info of the app that performed the last access on behalf of this app and
+ * as a result blamed the op on this app.
*
+ * @param flags The op flags
+ *
+ * @return The proxy name or {@code null}
+ *
+ * @see #getLastForegroundProxyInfo(int)
+ * @see #getLastBackgroundProxyInfo(int)
+ * @see #getLastProxyInfo(int, int, int)
+ * @see OpFeatureEntry#getLastProxyInfo(int)
+ */
+ public @Nullable OpEventProxyInfo getLastProxyInfo(@OpFlags int flags) {
+ return getLastProxyInfo(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
+ }
+
+ /**
+ * Gets the proxy info of the app that performed the last foreground access on behalf of
+ * this app and as a result blamed the op on this app.
+ *
+ * @param flags The op flags
+ *
+ * @return The proxy name or {@code null}
+ *
+ * @see #getLastProxyInfo(int)
+ * @see #getLastBackgroundProxyInfo(int)
+ * @see #getLastProxyInfo(int, int, int)
+ * @see OpFeatureEntry#getLastForegroundProxyInfo(int)
+ */
+ public @Nullable OpEventProxyInfo getLastForegroundProxyInfo(@OpFlags int flags) {
+ return getLastProxyInfo(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
+ flags);
+ }
+
+ /**
+ * Gets the proxy info of the app that performed the last background access on behalf of
+ * this app and as a result blamed the op on this app.
+ *
+ * @param flags The op flags
+ *
+ * @return The proxy name or {@code null}
+ *
+ * @see #getLastProxyInfo(int)
+ * @see #getLastForegroundProxyInfo(int)
+ * @see #getLastProxyInfo(int, int, int)
+ * @see OpFeatureEntry#getLastBackgroundProxyInfo(int)
+ */
+ public @Nullable OpEventProxyInfo getLastBackgroundProxyInfo(@OpFlags int flags) {
+ return getLastProxyInfo(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
+ flags);
+ }
+
+ /**
+ * Gets the proxy info of the app that performed the last access on behalf of this app and
+ * as a result blamed the op on this app.
+ *
+ * @param fromUidState The lowest UID state for which to query
+ * @param toUidState The highest UID state for which to query (inclusive)
+ * @param flags The op flags
+ *
+ * @return The proxy name or {@code null}
+ *
+ * @see #getLastProxyInfo(int)
+ * @see #getLastForegroundProxyInfo(int)
+ * @see #getLastBackgroundProxyInfo(int)
+ * @see OpFeatureEntry#getLastProxyInfo(int, int, int)
+ */
+ public @Nullable OpEventProxyInfo getLastProxyInfo(@UidState int fromUidState,
+ @UidState int toUidState, @OpFlags int flags) {
+ NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
+ if (lastEvent == null) {
+ return null;
+ }
+
+ return lastEvent.proxy;
+ }
+
+
+
+ // Code below generated by codegen v1.0.14.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
+
+ /**
+ * Creates a new OpEntry.
+ *
+ * @param op
+ * The code of the op
+ * @param mode
+ * The mode of the op
+ * @param features
+ * The features that have been used when checking the op
* @hide
*/
- public static OpEntry createFromParcel(@NonNull Parcel source) {
- int op = source.readInt();
- int mode = source.readInt();
+ @DataClass.Generated.Member
+ public OpEntry(
+ @IntRange(from = 0, to = _NUM_OP - 1) int op,
+ @Mode int mode,
+ @NonNull Map<String,OpFeatureEntry> features) {
+ this.mOp = op;
+ com.android.internal.util.AnnotationValidations.validate(
+ IntRange.class, null, mOp,
+ "from", 0,
+ "to", _NUM_OP - 1);
+ this.mMode = mode;
+ com.android.internal.util.AnnotationValidations.validate(
+ Mode.class, null, mMode);
+ this.mFeatures = features;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mFeatures);
- int numFeatures = source.readInt();
- Pair<String, OpFeatureEntry.Builder>[] features = new Pair[numFeatures];
- for (int i = 0; i < numFeatures; i++) {
- features[i] = new Pair<>(source.readString(),
- OpFeatureEntry.createFromParcel(source));
- }
+ // onConstructed(); // You can define this method to get a callback
+ }
- return new OpEntry(op, mode, features);
+ /**
+ * The mode of the op
+ */
+ @DataClass.Generated.Member
+ public @Mode int getMode() {
+ return mMode;
+ }
+
+ /**
+ * The features that have been used when checking the op
+ */
+ @DataClass.Generated.Member
+ public @NonNull Map<String,OpFeatureEntry> getFeatures() {
+ return mFeatures;
}
@Override
- public int describeContents() {
- return 0;
- }
-
- @Override
+ @DataClass.Generated.Member
public void writeToParcel(Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
dest.writeInt(mOp);
dest.writeInt(mMode);
-
- int numFeatures = mFeatures.size();
- dest.writeInt(numFeatures);
- for (int i = 0; i < numFeatures; i++) {
- dest.writeString(mFeatures.keyAt(i));
- mFeatures.valueAt(i).writeToParcel(dest, flags);
- }
+ dest.writeMap(mFeatures);
}
- public static final @NonNull Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ /* package-private */ OpEntry(@NonNull Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ int op = in.readInt();
+ int mode = in.readInt();
+ Map<String,OpFeatureEntry> features = new java.util.LinkedHashMap<>();
+ in.readMap(features, OpFeatureEntry.class.getClassLoader());
+
+ this.mOp = op;
+ com.android.internal.util.AnnotationValidations.validate(
+ IntRange.class, null, mOp,
+ "from", 0,
+ "to", _NUM_OP - 1);
+ this.mMode = mode;
+ com.android.internal.util.AnnotationValidations.validate(
+ Mode.class, null, mMode);
+ this.mFeatures = features;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mFeatures);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<OpEntry> CREATOR
+ = new Parcelable.Creator<OpEntry>() {
@Override
- public @NonNull OpEntry createFromParcel(@NonNull Parcel parcel) {
- return OpEntry.createFromParcel(parcel);
+ public OpEntry[] newArray(int size) {
+ return new OpEntry[size];
}
@Override
- public @NonNull OpEntry[] newArray(int size) {
- return new OpEntry[size];
+ public OpEntry createFromParcel(@NonNull Parcel in) {
+ return new OpEntry(in);
}
};
+
+ /*
+ @DataClass.Generated(
+ time = 1574809856259L,
+ codegenVersion = "1.0.14",
+ sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
+ inputSignatures = "private final @android.annotation.IntRange(from=0L, to=_NUM_OP - 1) int mOp\nprivate final @android.app.Mode int mMode\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,android.app.OpFeatureEntry> mFeatures\npublic @android.annotation.UnsupportedAppUsage(maxTargetSdk=Build.VERSION_CODES.Q, publicAlternatives=\"{@code \" + \"#getOpStr()}\") int getOp()\npublic @android.annotation.NonNull java.lang.String getOpStr()\npublic @java.lang.Deprecated @android.annotation.UnsupportedAppUsage(maxTargetSdk=Build.VERSION_CODES.Q, publicAlternatives=\"{@code \" + \"#getAccessTime(int, int)}\") long getTime()\npublic @java.lang.Deprecated long getLastAccessTime(int)\npublic @java.lang.Deprecated long getLastAccessForegroundTime(int)\npublic @java.lang.Deprecated long getLastAccessBackgroundTime(int)\npublic @java.lang.Deprecated long getLastAccessTime(int,int,int)\npublic @java.lang.Deprecated @android.annotation.UnsupportedAppUsage(maxTargetSdk=Build.VERSION_CODES.Q, publicAlternatives=\"{@code \" + \"#getLastRejectTime(int, int, int)}\") long getRejectTime()\npublic @java.lang.Deprecated long getLastRejectTime(int)\npublic @java.lang.Deprecated long getLastRejectForegroundTime(int)\npublic @java.lang.Deprecated long getLastRejectBackgroundTime(int)\npublic @java.lang.Deprecated long getLastRejectTime(int,int,int)\npublic long getAccessTime(int,int)\npublic long getRejectTime(int,int)\npublic boolean isRunning()\nprivate android.app.NoteOpEvent getLastAccessEvent(int,int,int)\npublic @java.lang.Deprecated long getDuration()\npublic @java.lang.Deprecated long getLastForegroundDuration(int)\npublic @java.lang.Deprecated long getLastBackgroundDuration(int)\npublic @java.lang.Deprecated long getLastDuration(int,int,int)\npublic @java.lang.Deprecated int getProxyUid()\npublic @java.lang.Deprecated @android.annotation.Nullable java.lang.String getProxyPackageName()\nprivate @android.app.UidState int getLastAccessUidStateForFlagsInStatesOfAllFeatures(int,int,int)\npublic @android.app.UidState int getLastAccessUidState(int)\npublic @android.app.UidState int getLastForegroundAccessUidState(int)\npublic @android.app.UidState int getLastBackgroundAccessUidState(int)\nprivate @android.app.UidState int getLastRejectUidStateForFlagsInStatesOfAllFeatures(int,int,int)\npublic @android.app.UidState int getLastRejectUidState(int)\npublic @android.app.UidState int getLastForegroundRejectUidState(int)\npublic @android.app.UidState int getLastBackgroundRejectUidState(int)\npublic long getDuration(int,int)\npublic int getProxyUid(int,int)\nprivate int getProxyUid(int,int,int)\npublic @android.annotation.Nullable java.lang.String getProxyPackageName(int,int)\nprivate @android.annotation.Nullable java.lang.String getProxyPackageName(int,int,int)\nclass OpEntry extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
+ @Deprecated
+ private void __metadata() {}
+ */
+
+
+ //@formatter:on
+ // End of generated code
+
}
/** @hide */
@@ -4890,71 +5320,6 @@
}
/**
- * Finds the first non-negative value for the given flags in between the begin and
- * end UID states.
- *
- * @param counts The data array.
- * @param beginUidState The beginning UID state (inclusive).
- * @param endUidState The end UID state (inclusive).
- * @param flags The UID flags.
- * @return The non-negative value or -1.
- */
- private static long findFirstNonNegativeForFlagsInStates(@Nullable LongSparseLongArray counts,
- @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
- if (counts == null) {
- return -1;
- }
- while (flags != 0) {
- final int flag = 1 << Integer.numberOfTrailingZeros(flags);
- flags &= ~flag;
- for (int uidState : UID_STATES) {
- if (uidState < beginUidState || uidState > endUidState) {
- continue;
- }
- final long key = makeKey(uidState, flag);
- final long value = counts.get(key);
- if (value >= 0) {
- return value;
- }
- }
- }
- return -1;
- }
-
- /**
- * Finds the first non-null value for the given flags in between the begin and
- * end UID states.
- *
- * @param counts The data array.
- * @param beginUidState The beginning UID state (inclusive).
- * @param endUidState The end UID state (inclusive).
- * @param flags The UID flags.
- * @return The non-negative value or -1.
- */
- private static @Nullable String findFirstNonNullForFlagsInStates(
- @Nullable LongSparseArray<String> counts, @UidState int beginUidState,
- @UidState int endUidState, @OpFlags int flags) {
- if (counts == null) {
- return null;
- }
- while (flags != 0) {
- final int flag = 1 << Integer.numberOfTrailingZeros(flags);
- flags &= ~flag;
- for (int uidState : UID_STATES) {
- if (uidState < beginUidState || uidState > endUidState) {
- continue;
- }
- final long key = makeKey(uidState, flag);
- final String value = counts.get(key);
- if (value != null) {
- return value;
- }
- }
- }
- return null;
- }
-
- /**
* Callback for notification of changes to operation state.
*/
public interface OnOpChangedListener {
@@ -5112,6 +5477,7 @@
*
* @hide
*/
+ @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid,
@@ -6135,22 +6501,28 @@
}
}
- /** @hide */
- @UnsupportedAppUsage
+ /**
+ * @deprecated Use own local {@link android.os.Binder#Binder()}
+ *
+ * @hide
+ */
+ @Deprecated
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Create own "
+ + "local {@link android.os.Binder}")
public static IBinder getToken(IAppOpsService service) {
- synchronized (AppOpsManager.class) {
- if (sToken != null) {
- return sToken;
- }
- try {
- sToken = service.getToken(new Binder());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- return sToken;
- }
+ return getClientId();
}
+ /** @hide */
+ public static IBinder getClientId() {
+ synchronized (AppOpsManager.class) {
+ if (sClientId == null) {
+ sClientId = new Binder();
+ }
+
+ return sClientId;
+ }
+ }
/**
* @deprecated use {@link #startOp(String, int, String, String, String)} instead
@@ -6207,7 +6579,7 @@
* the package is not in the passed in UID.
*/
public int startOp(@NonNull String op, int uid, @Nullable String packageName,
- @NonNull String featureId, @Nullable String message) {
+ @Nullable String featureId, @Nullable String message) {
return startOp(strOpToOp(op), uid, packageName, false, featureId, message);
}
@@ -6231,7 +6603,7 @@
* @hide
*/
public int startOp(int op, int uid, @Nullable String packageName, boolean startIfModeDefault,
- @NonNull String featureId, @Nullable String message) {
+ @Nullable String featureId, @Nullable String message) {
final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault, featureId,
message);
if (mode == MODE_ERRORED) {
@@ -6307,7 +6679,7 @@
public int startOpNoThrow(int op, int uid, @NonNull String packageName,
boolean startIfModeDefault, @Nullable String featureId, @Nullable String message) {
try {
- int mode = mService.startOperation(getToken(mService), op, uid, packageName,
+ int mode = mService.startOperation(getClientId(), op, uid, packageName,
featureId, startIfModeDefault);
if (mode == MODE_ALLOWED) {
markAppOpNoted(uid, packageName, op, featureId, message);
@@ -6367,7 +6739,7 @@
public void finishOp(int op, int uid, @NonNull String packageName,
@Nullable String featureId) {
try {
- mService.finishOperation(getToken(mService), op, uid, packageName, featureId);
+ mService.finishOperation(getClientId(), op, uid, packageName, featureId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -6932,22 +7304,23 @@
}
/**
- * Computes the max for the given flags in between the begin and
- * end UID states.
+ * Gets the last of the event.
*
- * @param counts The data array.
- * @param flags The UID flags.
- * @param beginUidState The beginning UID state (exclusive).
- * @param endUidState The end UID state.
- * @return The sum.
+ * @param events The events
+ * @param flags The UID flags
+ * @param beginUidState The maximum UID state (inclusive)
+ * @param endUidState The minimum UID state (inclusive)
+ *
+ * @return The last event of {@code null}
*/
- private static long maxForFlagsInStates(@Nullable LongSparseLongArray counts,
- @UidState int beginUidState, @UidState int endUidState,
- @OpFlags int flags) {
- if (counts == null) {
- return 0;
+ private static @Nullable NoteOpEvent getLastEvent(
+ @Nullable LongSparseArray<NoteOpEvent> events, @UidState int beginUidState,
+ @UidState int endUidState, @OpFlags int flags) {
+ if (events == null) {
+ return null;
}
- long max = 0;
+
+ NoteOpEvent lastEvent = null;
while (flags != 0) {
final int flag = 1 << Integer.numberOfTrailingZeros(flags);
flags &= ~flag;
@@ -6956,12 +7329,16 @@
continue;
}
final long key = makeKey(uidState, flag);
- max = Math.max(max, counts.get(key));
+
+ NoteOpEvent event = events.get(key);
+ if (lastEvent == null || event != null && event.noteTime > lastEvent.noteTime) {
+ lastEvent = event;
+ }
}
}
- return max;
- }
+ return lastEvent;
+ }
private static void writeLongSparseLongArrayToParcel(
@Nullable LongSparseLongArray array, @NonNull Parcel parcel) {
@@ -6990,33 +7367,6 @@
return array;
}
- private static void writeLongSparseStringArrayToParcel(
- @Nullable LongSparseArray<String> array, @NonNull Parcel parcel) {
- if (array != null) {
- final int size = array.size();
- parcel.writeInt(size);
- for (int i = 0; i < size; i++) {
- parcel.writeLong(array.keyAt(i));
- parcel.writeString(array.valueAt(i));
- }
- } else {
- parcel.writeInt(-1);
- }
- }
-
- private static @Nullable LongSparseArray<String> readLongSparseStringArrayFromParcel(
- @NonNull Parcel parcel) {
- final int size = parcel.readInt();
- if (size < 0) {
- return null;
- }
- final LongSparseArray<String> array = new LongSparseArray<>(size);
- for (int i = 0; i < size; i++) {
- array.append(parcel.readLong(), parcel.readString());
- }
- return array;
- }
-
/**
* Collects the keys from an array to the result creating the result if needed.
*
diff --git a/core/java/android/app/AsyncNotedAppOp.java b/core/java/android/app/AsyncNotedAppOp.java
index 958ebae..0e1f921 100644
--- a/core/java/android/app/AsyncNotedAppOp.java
+++ b/core/java/android/app/AsyncNotedAppOp.java
@@ -285,7 +285,7 @@
time = 1571327470155L,
codegenVersion = "1.0.9",
sourceFile = "frameworks/base/core/java/android/app/AsyncNotedAppOp.java",
- inputSignatures = "private final @android.annotation.IntRange(from=0L, to=91L) int mOpCode\nprivate final @android.annotation.IntRange(from=0L) int mNotingUid\nprivate final @android.annotation.Nullable java.lang.String mNotingPackageName\nprivate final @android.annotation.Nullable java.lang.String mFeatureId\nprivate final @android.annotation.NonNull java.lang.String mMessage\nprivate final @android.annotation.IntRange(from=0L) long mTime\npublic @android.annotation.NonNull java.lang.String getOp()\nclass AsyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genHiddenConstructor=true)")
+ inputSignatures = "private final @android.annotation.IntRange(from=0L, to=92L) int mOpCode\nprivate final @android.annotation.IntRange(from=0L) int mNotingUid\nprivate final @android.annotation.Nullable java.lang.String mNotingPackageName\nprivate final @android.annotation.Nullable java.lang.String mFeatureId\nprivate final @android.annotation.NonNull java.lang.String mMessage\nprivate final @android.annotation.IntRange(from=0L) long mTime\npublic @android.annotation.NonNull java.lang.String getOp()\nclass AsyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genHiddenConstructor=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index ce21db3..69c37ec 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -116,12 +116,13 @@
import android.net.NetworkScoreManager;
import android.net.NetworkWatchlistManager;
import android.net.TestNetworkManager;
+import android.net.TetheringManager;
import android.net.lowpan.ILowpanManager;
import android.net.lowpan.LowpanManager;
import android.net.nsd.INsdManager;
import android.net.nsd.NsdManager;
-import android.net.wifi.WifiCondManager;
import android.net.wifi.WifiFrameworkInitializer;
+import android.net.wifi.wificond.WifiCondManager;
import android.nfc.NfcManager;
import android.os.BatteryManager;
import android.os.BatteryStats;
@@ -339,6 +340,17 @@
}
});
+ registerService(Context.TETHERING_SERVICE, TetheringManager.class,
+ new CachedServiceFetcher<TetheringManager>() {
+ @Override
+ public TetheringManager createService(ContextImpl ctx) throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getService(Context.TETHERING_SERVICE);
+ if (b == null) return null;
+
+ return new TetheringManager(ctx, b);
+ }});
+
+
registerService(Context.IPSEC_SERVICE, IpSecManager.class,
new CachedServiceFetcher<IpSecManager>() {
@Override
@@ -1147,14 +1159,6 @@
return new TimeZoneDetector();
}});
- registerService(Context.TELEPHONY_IMS_SERVICE, android.telephony.ims.ImsManager.class,
- new CachedServiceFetcher<android.telephony.ims.ImsManager>() {
- @Override
- public android.telephony.ims.ImsManager createService(ContextImpl ctx) {
- return new android.telephony.ims.ImsManager(ctx.getOuterContext());
- }
- });
-
registerService(Context.PERMISSION_SERVICE, PermissionManager.class,
new CachedServiceFetcher<PermissionManager>() {
@Override
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index ac8b40c..2507991 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -33,6 +33,7 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
@@ -40,6 +41,8 @@
import android.graphics.BitmapRegionDecoder;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.ColorSpace;
+import android.graphics.ImageDecoder;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
@@ -63,11 +66,15 @@
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
+import android.view.Display;
import android.view.WindowManagerGlobal;
+import com.android.internal.R;
+
import libcore.io.IoUtils;
import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -76,7 +83,10 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -193,7 +203,13 @@
*/
public static final int FLAG_LOCK = 1 << 1;
+ private static final Object sSync = new Object[0];
+ @UnsupportedAppUsage
+ private static Globals sGlobals;
+
private final Context mContext;
+ private final boolean mWcgEnabled;
+ private final ColorManagementProxy mCmProxy;
/**
* Special drawable that draws a wallpaper as fast as possible. Assumes
@@ -388,13 +404,14 @@
}
public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault,
- @SetWallpaperFlags int which) {
+ @SetWallpaperFlags int which, ColorManagementProxy cmProxy) {
return peekWallpaperBitmap(context, returnDefault, which, context.getUserId(),
- false /* hardware */);
+ false /* hardware */, cmProxy);
}
public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault,
- @SetWallpaperFlags int which, int userId, boolean hardware) {
+ @SetWallpaperFlags int which, int userId, boolean hardware,
+ ColorManagementProxy cmProxy) {
if (mService != null) {
try {
if (!mService.isWallpaperSupported(context.getOpPackageName())) {
@@ -412,7 +429,8 @@
mCachedWallpaper = null;
mCachedWallpaperUserId = 0;
try {
- mCachedWallpaper = getCurrentWallpaperLocked(context, userId, hardware);
+ mCachedWallpaper = getCurrentWallpaperLocked(
+ context, userId, hardware, cmProxy);
mCachedWallpaperUserId = userId;
} catch (OutOfMemoryError e) {
Log.w(TAG, "Out of memory loading the current wallpaper: " + e);
@@ -450,7 +468,8 @@
}
}
- private Bitmap getCurrentWallpaperLocked(Context context, int userId, boolean hardware) {
+ private Bitmap getCurrentWallpaperLocked(Context context, int userId, boolean hardware,
+ ColorManagementProxy cmProxy) {
if (mService == null) {
Log.w(TAG, "WallpaperService not running");
return null;
@@ -458,21 +477,29 @@
try {
Bundle params = new Bundle();
- ParcelFileDescriptor fd = mService.getWallpaperWithFeature(
+ ParcelFileDescriptor pfd = mService.getWallpaperWithFeature(
context.getOpPackageName(), context.getFeatureId(), this, FLAG_SYSTEM,
params, userId);
- if (fd != null) {
- try {
- BitmapFactory.Options options = new BitmapFactory.Options();
- if (hardware) {
- options.inPreferredConfig = Bitmap.Config.HARDWARE;
+
+ if (pfd != null) {
+ try (BufferedInputStream bis = new BufferedInputStream(
+ new ParcelFileDescriptor.AutoCloseInputStream(pfd))) {
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int data;
+ while ((data = bis.read()) != -1) {
+ baos.write(data);
}
- return BitmapFactory.decodeFileDescriptor(
- fd.getFileDescriptor(), null, options);
- } catch (OutOfMemoryError e) {
+ ImageDecoder.Source src = ImageDecoder.createSource(baos.toByteArray());
+ return ImageDecoder.decodeBitmap(src, ((decoder, info, source) -> {
+ // Mutable and hardware config can't be set at the same time.
+ decoder.setMutableRequired(!hardware);
+ // Let's do color management
+ if (cmProxy != null) {
+ cmProxy.doColorManagement(decoder, info);
+ }
+ }));
+ } catch (OutOfMemoryError | IOException e) {
Log.w(TAG, "Can't decode file", e);
- } finally {
- IoUtils.closeQuietly(fd);
}
}
} catch (RemoteException e) {
@@ -497,10 +524,6 @@
}
}
- private static final Object sSync = new Object[0];
- @UnsupportedAppUsage
- private static Globals sGlobals;
-
static void initGlobals(IWallpaperManager service, Looper looper) {
synchronized (sSync) {
if (sGlobals == null) {
@@ -514,6 +537,10 @@
if (service != null) {
initGlobals(service, context.getMainLooper());
}
+ // Check if supports mixed color spaces composition in hardware.
+ mWcgEnabled = context.getResources().getConfiguration().isScreenWideColorGamut()
+ && context.getResources().getBoolean(R.bool.config_enableWcgMode);
+ mCmProxy = new ColorManagementProxy(context);
}
/**
@@ -531,6 +558,22 @@
}
/**
+ * Indicate whether wcg (Wide Color Gamut) should be enabled.
+ * <p>
+ * Some devices lack of capability of mixed color spaces composition,
+ * enable wcg on such devices might cause memory or battery concern.
+ * <p>
+ * Therefore, in addition to {@link Configuration#isScreenWideColorGamut()},
+ * we also take mixed color spaces composition (config_enableWcgMode) into account.
+ *
+ * @see Configuration#isScreenWideColorGamut()
+ * @return True if wcg should be enabled for this device.
+ */
+ private boolean shouldEnableWideColorGamut() {
+ return mWcgEnabled;
+ }
+
+ /**
* Retrieve the current system wallpaper; if
* no wallpaper is set, the system built-in static wallpaper is returned.
* This is returned as an
@@ -546,7 +589,7 @@
* is not able to access the wallpaper.
*/
public Drawable getDrawable() {
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM);
+ Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM, mCmProxy);
if (bm != null) {
Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
dr.setDither(false);
@@ -777,7 +820,7 @@
* null pointer if these is none.
*/
public Drawable peekDrawable() {
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM);
+ Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM, mCmProxy);
if (bm != null) {
Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
dr.setDither(false);
@@ -801,7 +844,7 @@
*/
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
public Drawable getFastDrawable() {
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM);
+ Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM, mCmProxy);
if (bm != null) {
return new FastBitmapDrawable(bm);
}
@@ -817,7 +860,7 @@
*/
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
public Drawable peekFastDrawable() {
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM);
+ Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM, mCmProxy);
if (bm != null) {
return new FastBitmapDrawable(bm);
}
@@ -825,6 +868,27 @@
}
/**
+ * Whether the wallpaper supports Wide Color Gamut or not.
+ * @param which The wallpaper whose image file is to be retrieved. Must be a single
+ * defined kind of wallpaper, either {@link #FLAG_SYSTEM} or {@link #FLAG_LOCK}.
+ * @return true when supported.
+ *
+ * @see #FLAG_LOCK
+ * @see #FLAG_SYSTEM
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
+ public boolean wallpaperSupportsWcg(int which) {
+ if (!shouldEnableWideColorGamut()) {
+ return false;
+ }
+ Bitmap bitmap = sGlobals.peekWallpaperBitmap(mContext, false, which, mCmProxy);
+ return bitmap != null && bitmap.getColorSpace() != null
+ && bitmap.getColorSpace() != ColorSpace.get(ColorSpace.Named.SRGB)
+ && mCmProxy.isSupportedColorSpace(bitmap.getColorSpace());
+ }
+
+ /**
* Like {@link #getDrawable()} but returns a Bitmap with default {@link Bitmap.Config}.
*
* @hide
@@ -852,7 +916,8 @@
* @hide
*/
public Bitmap getBitmapAsUser(int userId, boolean hardware) {
- return sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM, userId, hardware);
+ return sGlobals.peekWallpaperBitmap(
+ mContext, true, FLAG_SYSTEM, userId, hardware, mCmProxy);
}
/**
@@ -1975,6 +2040,33 @@
return false;
}
+ /**
+ * A private class to help Globals#getCurrentWallpaperLocked handle color management.
+ */
+ private static class ColorManagementProxy {
+ private final Set<ColorSpace> mSupportedColorSpaces = new HashSet<>();
+
+ ColorManagementProxy(Context context) {
+ // Get a list of supported wide gamut color spaces.
+ Display display = context.getDisplay();
+ if (display != null) {
+ mSupportedColorSpaces.addAll(Arrays.asList(display.getSupportedWideColorGamut()));
+ }
+ }
+
+ boolean isSupportedColorSpace(ColorSpace colorSpace) {
+ return colorSpace != null && (colorSpace == ColorSpace.get(ColorSpace.Named.SRGB)
+ || mSupportedColorSpaces.contains(colorSpace));
+ }
+
+ void doColorManagement(ImageDecoder decoder, ImageDecoder.ImageInfo info) {
+ if (!isSupportedColorSpace(info.getColorSpace())) {
+ decoder.setTargetColorSpace(ColorSpace.get(ColorSpace.Named.SRGB));
+ Log.w(TAG, "Not supported color space: " + info.getColorSpace());
+ }
+ }
+ }
+
// Private completion callback for setWallpaper() synchronization
private class WallpaperSetCompletion extends IWallpaperManagerCallback.Stub {
final CountDownLatch mLatch;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 66abf5d..483bf3f 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3932,6 +3932,15 @@
public static final String NETWORK_STACK_SERVICE = "network_stack";
/**
+ * Use with {@link android.os.ServiceManager.getService()} to retrieve a
+ * {@link ITetheringConnector} IBinder for communicating with the tethering service
+ * @hide
+ * @see TetheringClient
+ */
+ @SystemApi
+ public static final String TETHERING_SERVICE = "tethering";
+
+ /**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.net.IpSecManager} for encrypting Sockets or Networks with
* IPSec.
diff --git a/core/java/android/content/pm/DataLoaderParams.java b/core/java/android/content/pm/DataLoaderParams.java
index b163861..af4b99a 100644
--- a/core/java/android/content/pm/DataLoaderParams.java
+++ b/core/java/android/content/pm/DataLoaderParams.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.ParcelFileDescriptor;
import java.util.Arrays;
@@ -26,9 +27,12 @@
/**
* This class represents the parameters used to configure an Incremental Data Loader.
- * Hide for now.
+ *
+ * WARNING: This is a system API to aid internal development.
+ * Use at your own risk. It will change or be removed without warning.
* @hide
*/
+@SystemApi
public class DataLoaderParams {
@NonNull private final DataLoaderParamsParcel mData;
@@ -52,6 +56,9 @@
mData = data;
}
+ /**
+ * @hide
+ */
public DataLoaderParams(@NonNull DataLoaderParamsParcel data) {
mData = data;
}
@@ -70,6 +77,9 @@
return mData.packageName;
}
+ /**
+ * @hide
+ */
public final @NonNull DataLoaderParamsParcel getData() {
return mData;
}
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 5386422..3d6d849 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1082,8 +1082,12 @@
* @throws SecurityException if called after the session has been
* sealed or abandoned
* @throws IllegalStateException if called for non-callback session
+ *
+ * WARNING: This is a system API to aid internal development.
+ * Use at your own risk. It will change or be removed without warning.
* {@hide}
*/
+ @SystemApi
public void addFile(@NonNull String name, long lengthBytes, @NonNull byte[] metadata) {
try {
mSession.addFile(name, lengthBytes, metadata);
@@ -1461,6 +1465,8 @@
/** TODO(b/146080380): add a class name to make it fully compatible with ComponentName.
* {@hide} */
public String dataLoaderPackageName;
+ /** {@hide} */
+ public int rollbackDataPolicy = PackageManager.RollbackDataPolicy.RESTORE;
/**
* Construct parameters for a new package install session.
@@ -1501,6 +1507,7 @@
dataLoaderParamsParcel);
}
dataLoaderPackageName = source.readString();
+ rollbackDataPolicy = source.readInt();
}
/** {@hide} */
@@ -1526,6 +1533,7 @@
ret.requiredInstalledVersionCode = requiredInstalledVersionCode;
ret.incrementalParams = incrementalParams;
ret.dataLoaderPackageName = dataLoaderPackageName;
+ ret.rollbackDataPolicy = rollbackDataPolicy;
return ret;
}
@@ -1682,12 +1690,14 @@
}
/**
- * Request that rollbacks be enabled or disabled for the given upgrade.
+ * Request that rollbacks be enabled or disabled for the given upgrade with rollback data
+ * policy set to RESTORE.
*
* <p>If the parent session is staged or has rollback enabled, all children sessions
* must have the same properties.
*
* @param enable set to {@code true} to enable, {@code false} to disable
+ * @see SessionParams#setEnableRollback(boolean, int)
* @hide
*/
@SystemApi @TestApi
@@ -1697,9 +1707,36 @@
} else {
installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
}
+ rollbackDataPolicy = PackageManager.RollbackDataPolicy.RESTORE;
}
/**
+ * Request that rollbacks be enabled or disabled for the given upgrade.
+ *
+ * <p>If the parent session is staged or has rollback enabled, all children sessions
+ * must have the same properties.
+ *
+ * <p> For a multi-package install, this method must be called on each child session to
+ * specify rollback data policies explicitly. Note each child session is allowed to have
+ * different policies.
+ *
+ * @param enable set to {@code true} to enable, {@code false} to disable
+ * @param dataPolicy the rollback data policy for this session
+ * @hide
+ */
+ @SystemApi @TestApi
+ public void setEnableRollback(boolean enable,
+ @PackageManager.RollbackDataPolicy int dataPolicy) {
+ if (enable) {
+ installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
+ } else {
+ installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
+ }
+ rollbackDataPolicy = dataPolicy;
+ }
+
+
+ /**
* @deprecated use {@link #setRequestDowngrade(boolean)}.
* {@hide}
*/
@@ -1857,9 +1894,11 @@
/**
* Set Incremental data loader params.
- *
+ * WARNING: This is a system API to aid internal development.
+ * Use at your own risk. It will change or be removed without warning.
* {@hide}
*/
+ @SystemApi
@RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
public void setIncrementalParams(@NonNull DataLoaderParams incrementalParams) {
this.incrementalParams = incrementalParams;
@@ -1900,6 +1939,7 @@
pw.printPair("isStaged", isStaged);
pw.printPair("requiredInstalledVersionCode", requiredInstalledVersionCode);
pw.printPair("dataLoaderPackageName", dataLoaderPackageName);
+ pw.printPair("rollbackDataPolicy", rollbackDataPolicy);
pw.println();
}
@@ -1935,6 +1975,7 @@
dest.writeParcelable(null, flags);
}
dest.writeString(dataLoaderPackageName);
+ dest.writeInt(rollbackDataPolicy);
}
public static final Parcelable.Creator<SessionParams>
@@ -2072,6 +2113,9 @@
public long updatedMillis;
/** {@hide} */
+ public int rollbackDataPolicy;
+
+ /** {@hide} */
@UnsupportedAppUsage
public SessionInfo() {
}
@@ -2114,6 +2158,7 @@
mStagedSessionErrorCode = source.readInt();
mStagedSessionErrorMessage = source.readString();
isCommitted = source.readBoolean();
+ rollbackDataPolicy = source.readInt();
}
/**
@@ -2431,6 +2476,17 @@
}
/**
+ * Return the data policy associated with the rollback for the given upgrade.
+ *
+ * @hide
+ */
+ @SystemApi @TestApi
+ @PackageManager.RollbackDataPolicy
+ public int getRollbackDataPolicy() {
+ return rollbackDataPolicy;
+ }
+
+ /**
* Returns {@code true} if this session is an active staged session.
*
* We consider a session active if it has been committed and it is either pending
@@ -2592,6 +2648,7 @@
dest.writeInt(mStagedSessionErrorCode);
dest.writeString(mStagedSessionErrorMessage);
dest.writeBoolean(isCommitted);
+ dest.writeInt(rollbackDataPolicy);
}
public static final Parcelable.Creator<SessionInfo>
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 21c9739..f792127 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -710,6 +710,29 @@
public static final int COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED = 4;
/** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {
+ RollbackDataPolicy.RESTORE,
+ RollbackDataPolicy.WIPE,
+ RollbackDataPolicy.RETAIN
+ })
+ public @interface RollbackDataPolicy {
+ /**
+ * User data will be backed up during install and restored during rollback.
+ */
+ int RESTORE = 0;
+ /**
+ * User data won't be backed up during install but will be wiped out during rollback.
+ */
+ int WIPE = 1;
+ /**
+ * User data won't be backed up during install and won't be restored during rollback.
+ * TODO: Not implemented yet.
+ */
+ int RETAIN = 2;
+ }
+
+ /** @hide */
@IntDef(flag = true, prefix = { "INSTALL_" }, value = {
INSTALL_REPLACE_EXISTING,
INSTALL_ALLOW_TEST,
@@ -3243,6 +3266,15 @@
public static final int FLAG_PERMISSION_REVOKED_COMPAT = FLAG_PERMISSION_REVOKE_ON_UPGRADE;
/**
+ * Permission flag: The permission is one-time and should be revoked automatically on app
+ * inactivity
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int FLAG_PERMISSION_ONE_TIME = 1 << 16;
+
+ /**
* Permission flags: Bitwise or of all permission flags allowing an
* exemption for a restricted permission.
* @hide
@@ -3283,7 +3315,8 @@
| FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT
| FLAG_PERMISSION_APPLY_RESTRICTION
| FLAG_PERMISSION_GRANTED_BY_ROLE
- | FLAG_PERMISSION_REVOKED_COMPAT;
+ | FLAG_PERMISSION_REVOKED_COMPAT
+ | FLAG_PERMISSION_ONE_TIME;
/**
* Injected activity in app that forwards user to setting activity of that app.
@@ -4063,7 +4096,8 @@
FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT,
FLAG_PERMISSION_APPLY_RESTRICTION,
FLAG_PERMISSION_GRANTED_BY_ROLE,
- FLAG_PERMISSION_REVOKED_COMPAT
+ FLAG_PERMISSION_REVOKED_COMPAT,
+ FLAG_PERMISSION_ONE_TIME
})
@Retention(RetentionPolicy.SOURCE)
public @interface PermissionFlags {}
@@ -7164,6 +7198,7 @@
case FLAG_PERMISSION_APPLY_RESTRICTION: return "APPLY_RESTRICTION";
case FLAG_PERMISSION_GRANTED_BY_ROLE: return "GRANTED_BY_ROLE";
case FLAG_PERMISSION_REVOKED_COMPAT: return "REVOKED_COMPAT";
+ case FLAG_PERMISSION_ONE_TIME: return "ONE_TIME";
default: return Integer.toString(flag);
}
}
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 89a1c6a..a0f089b 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -248,6 +248,17 @@
@TestApi
public static final int PROTECTION_FLAG_TELEPHONY = 0x400000;
+ /**
+ * Additional flag for {@link #protectionLevel}, corresponding
+ * to the <code>companion</code> value of
+ * {@link android.R.attr#protectionLevel}.
+ *
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ public static final int PROTECTION_FLAG_COMPANION = 0x800000;
+
/** @hide */
@IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = {
PROTECTION_FLAG_PRIVILEGED,
@@ -270,6 +281,7 @@
PROTECTION_FLAG_INCIDENT_REPORT_APPROVER,
PROTECTION_FLAG_APP_PREDICTOR,
PROTECTION_FLAG_TELEPHONY,
+ PROTECTION_FLAG_COMPANION,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ProtectionFlags {}
diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
index 39c1dac..f7137705 100644
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
@@ -782,59 +782,42 @@
private void enforceStrictGrammar(@Nullable String selection, @Nullable String groupBy,
@Nullable String having, @Nullable String sortOrder, @Nullable String limit) {
SQLiteTokenizer.tokenize(selection, SQLiteTokenizer.OPTION_NONE,
- this::enforceStrictGrammarWhereHaving);
+ this::enforceStrictToken);
SQLiteTokenizer.tokenize(groupBy, SQLiteTokenizer.OPTION_NONE,
- this::enforceStrictGrammarGroupBy);
+ this::enforceStrictToken);
SQLiteTokenizer.tokenize(having, SQLiteTokenizer.OPTION_NONE,
- this::enforceStrictGrammarWhereHaving);
+ this::enforceStrictToken);
SQLiteTokenizer.tokenize(sortOrder, SQLiteTokenizer.OPTION_NONE,
- this::enforceStrictGrammarOrderBy);
+ this::enforceStrictToken);
SQLiteTokenizer.tokenize(limit, SQLiteTokenizer.OPTION_NONE,
- this::enforceStrictGrammarLimit);
+ this::enforceStrictToken);
}
- private void enforceStrictGrammarWhereHaving(@NonNull String token) {
+ private void enforceStrictToken(@NonNull String token) {
if (isTableOrColumn(token)) return;
if (SQLiteTokenizer.isFunction(token)) return;
if (SQLiteTokenizer.isType(token)) return;
- // NOTE: we explicitly don't allow SELECT subqueries, since they could
- // leak data that should have been filtered by the trusted where clause
+ // Carefully block any tokens that are attempting to jump across query
+ // clauses or create subqueries, since they could leak data that should
+ // have been filtered by the trusted where clause
+ boolean isAllowedKeyword = SQLiteTokenizer.isKeyword(token);
switch (token.toUpperCase(Locale.US)) {
- case "AND": case "AS": case "BETWEEN": case "BINARY":
- case "CASE": case "CAST": case "COLLATE": case "DISTINCT":
- case "ELSE": case "END": case "ESCAPE": case "EXISTS":
- case "GLOB": case "IN": case "IS": case "ISNULL":
- case "LIKE": case "MATCH": case "NOCASE": case "NOT":
- case "NOTNULL": case "NULL": case "OR": case "REGEXP":
- case "RTRIM": case "THEN": case "WHEN":
- return;
+ case "SELECT":
+ case "FROM":
+ case "WHERE":
+ case "GROUP":
+ case "HAVING":
+ case "WINDOW":
+ case "VALUES":
+ case "ORDER":
+ case "LIMIT":
+ isAllowedKeyword = false;
+ break;
}
- throw new IllegalArgumentException("Invalid token " + token);
- }
-
- private void enforceStrictGrammarGroupBy(@NonNull String token) {
- if (isTableOrColumn(token)) return;
- throw new IllegalArgumentException("Invalid token " + token);
- }
-
- private void enforceStrictGrammarOrderBy(@NonNull String token) {
- if (isTableOrColumn(token)) return;
- switch (token.toUpperCase(Locale.US)) {
- case "COLLATE": case "ASC": case "DESC":
- case "BINARY": case "RTRIM": case "NOCASE":
- case "LOCALIZED": case "UNICODE":
- return;
+ if (!isAllowedKeyword) {
+ throw new IllegalArgumentException("Invalid token " + token);
}
- throw new IllegalArgumentException("Invalid token " + token);
- }
-
- private void enforceStrictGrammarLimit(@NonNull String token) {
- switch (token.toUpperCase(Locale.US)) {
- case "OFFSET":
- return;
- }
- throw new IllegalArgumentException("Invalid token " + token);
}
/**
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index d95da91..3ed51d7 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -50,6 +50,7 @@
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
+import android.os.SystemClock;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -57,7 +58,6 @@
import android.util.Log;
import android.util.SparseIntArray;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import com.android.internal.util.Protocol;
@@ -802,6 +802,7 @@
private INetworkManagementService mNMService;
private INetworkPolicyManager mNPManager;
+ private TetheringManager mTetheringManager;
/**
* Tests if a given integer represents a valid network type.
@@ -2339,6 +2340,28 @@
return getInstanceOrNull();
}
+ private static final int TETHERING_TIMEOUT_MS = 60_000;
+ private final Object mTetheringLock = new Object();
+
+ private TetheringManager getTetheringManager() {
+ synchronized (mTetheringLock) {
+ if (mTetheringManager != null) {
+ return mTetheringManager;
+ }
+ final long before = System.currentTimeMillis();
+ while ((mTetheringManager = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE)) == null) {
+ if (System.currentTimeMillis() - before > TETHERING_TIMEOUT_MS) {
+ Log.e(TAG, "Timeout waiting tethering service not ready yet");
+ throw new IllegalStateException("No tethering service yet");
+ }
+ SystemClock.sleep(100);
+ }
+
+ return mTetheringManager;
+ }
+ }
+
/**
* Get the set of tetherable, available interfaces. This list is limited by
* device configuration and current interface existence.
@@ -2350,11 +2373,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetherableIfaces() {
- try {
- return mService.getTetherableIfaces();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetherableIfaces();
}
/**
@@ -2367,11 +2386,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetheredIfaces() {
- try {
- return mService.getTetheredIfaces();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetheredIfaces();
}
/**
@@ -2390,11 +2405,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetheringErroredIfaces() {
- try {
- return mService.getTetheringErroredIfaces();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetheringErroredIfaces();
}
/**
@@ -2405,11 +2416,7 @@
*/
@RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
public String[] getTetheredDhcpRanges() {
- try {
- return mService.getTetheredDhcpRanges();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetheredDhcpRanges();
}
/**
@@ -2438,13 +2445,7 @@
*/
@UnsupportedAppUsage
public int tether(String iface) {
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "tether caller:" + pkgName);
- return mService.tether(iface, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().tether(iface);
}
/**
@@ -2467,13 +2468,7 @@
*/
@UnsupportedAppUsage
public int untether(String iface) {
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "untether caller:" + pkgName);
- return mService.untether(iface, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().untether(iface);
}
/**
@@ -2498,16 +2493,7 @@
@RequiresPermission(anyOf = {android.Manifest.permission.TETHER_PRIVILEGED,
android.Manifest.permission.WRITE_SETTINGS})
public boolean isTetheringSupported() {
- String pkgName = mContext.getOpPackageName();
- try {
- return mService.isTetheringSupported(pkgName);
- } catch (SecurityException e) {
- // This API is not available to this caller, but for backward-compatibility
- // this will just return false instead of throwing.
- return false;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().isTetheringSupported();
}
/**
@@ -2576,14 +2562,7 @@
}
};
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "startTethering caller:" + pkgName);
- mService.startTethering(type, wrappedCallback, showProvisioningUi, pkgName);
- } catch (RemoteException e) {
- Log.e(TAG, "Exception trying to start tethering.", e);
- wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);
- }
+ getTetheringManager().startTethering(type, wrappedCallback, showProvisioningUi);
}
/**
@@ -2599,13 +2578,7 @@
@SystemApi
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
public void stopTethering(int type) {
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "stopTethering caller:" + pkgName);
- mService.stopTethering(type, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ getTetheringManager().stopTethering(type);
}
/**
@@ -2627,10 +2600,6 @@
public void onUpstreamChanged(@Nullable Network network) {}
}
- @GuardedBy("mTetheringEventCallbacks")
- private final ArrayMap<OnTetheringEventCallback, ITetheringEventCallback>
- mTetheringEventCallbacks = new ArrayMap<>();
-
/**
* Start listening to tethering change events. Any new added callback will receive the last
* tethering status right away. If callback is registered when tethering has no upstream or
@@ -2648,27 +2617,7 @@
@NonNull final OnTetheringEventCallback callback) {
Preconditions.checkNotNull(callback, "OnTetheringEventCallback cannot be null.");
- synchronized (mTetheringEventCallbacks) {
- Preconditions.checkArgument(!mTetheringEventCallbacks.containsKey(callback),
- "callback was already registered.");
- ITetheringEventCallback remoteCallback = new ITetheringEventCallback.Stub() {
- @Override
- public void onUpstreamChanged(Network network) throws RemoteException {
- Binder.withCleanCallingIdentity(() ->
- executor.execute(() -> {
- callback.onUpstreamChanged(network);
- }));
- }
- };
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "registerTetheringUpstreamCallback:" + pkgName);
- mService.registerTetheringEventCallback(remoteCallback, pkgName);
- mTetheringEventCallbacks.put(callback, remoteCallback);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
+ getTetheringManager().registerTetheringEventCallback(executor, callback);
}
/**
@@ -2682,17 +2631,7 @@
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
public void unregisterTetheringEventCallback(
@NonNull final OnTetheringEventCallback callback) {
- synchronized (mTetheringEventCallbacks) {
- ITetheringEventCallback remoteCallback = mTetheringEventCallbacks.remove(callback);
- Preconditions.checkNotNull(remoteCallback, "callback was not registered.");
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "unregisterTetheringEventCallback:" + pkgName);
- mService.unregisterTetheringEventCallback(remoteCallback, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
+ getTetheringManager().unregisterTetheringEventCallback(callback);
}
@@ -2709,11 +2648,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetherableUsbRegexs() {
- try {
- return mService.getTetherableUsbRegexs();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetherableUsbRegexs();
}
/**
@@ -2729,11 +2664,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetherableWifiRegexs() {
- try {
- return mService.getTetherableWifiRegexs();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetherableWifiRegexs();
}
/**
@@ -2749,11 +2680,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetherableBluetoothRegexs() {
- try {
- return mService.getTetherableBluetoothRegexs();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetherableBluetoothRegexs();
}
/**
@@ -2775,13 +2702,7 @@
*/
@UnsupportedAppUsage
public int setUsbTethering(boolean enable) {
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "setUsbTethering caller:" + pkgName);
- return mService.setUsbTethering(enable, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().setUsbTethering(enable);
}
/** {@hide} */
@@ -2829,11 +2750,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public int getLastTetherError(String iface) {
- try {
- return mService.getLastTetherError(iface);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getLastTetherError(iface);
}
/** @hide */
@@ -2899,14 +2816,8 @@
}
};
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "getLatestTetheringEntitlementResult:" + pkgName);
- mService.getLatestTetheringEntitlementResult(type, wrappedListener,
- showEntitlementUi, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ getTetheringManager().requestLatestTetheringEntitlementResult(type, wrappedListener,
+ showEntitlementUi);
}
/**
@@ -4331,6 +4242,7 @@
public void factoryReset() {
try {
mService.factoryReset();
+ getTetheringManager().stopAllTethering();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 5f662f9..09c02ef 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -19,7 +19,6 @@
import android.app.PendingIntent;
import android.net.ConnectionInfo;
import android.net.LinkProperties;
-import android.net.ITetheringEventCallback;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
@@ -78,41 +77,31 @@
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
- int tether(String iface, String callerPkg);
-
- int untether(String iface, String callerPkg);
-
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getLastTetherError} as alternative")
int getLastTetherError(String iface);
- boolean isTetheringSupported(String callerPkg);
-
- void startTethering(int type, in ResultReceiver receiver, boolean showProvisioningUi,
- String callerPkg);
-
- void stopTethering(int type, String callerPkg);
-
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getTetherableIfaces} as alternative")
String[] getTetherableIfaces();
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getTetheredIfaces} as alternative")
String[] getTetheredIfaces();
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getTetheringErroredIfaces} "
+ + "as Alternative")
String[] getTetheringErroredIfaces();
- String[] getTetheredDhcpRanges();
-
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getTetherableUsbRegexs} as alternative")
String[] getTetherableUsbRegexs();
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getTetherableWifiRegexs} as alternative")
String[] getTetherableWifiRegexs();
- String[] getTetherableBluetoothRegexs();
-
- int setUsbTethering(boolean enable, String callerPkg);
-
@UnsupportedAppUsage(maxTargetSdk = 28)
void reportInetCondition(int networkType, int percentage);
@@ -217,11 +206,5 @@
boolean isCallerCurrentAlwaysOnVpnApp();
boolean isCallerCurrentAlwaysOnVpnLockdownApp();
- void getLatestTetheringEntitlementResult(int type, in ResultReceiver receiver,
- boolean showEntitlementUi, String callerPkg);
-
- void registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
- void unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
-
IBinder startOrGetTestNetworkService();
}
diff --git a/core/java/android/nfc/INfcCardEmulation.aidl b/core/java/android/nfc/INfcCardEmulation.aidl
index dd2c0d4..848b6d5 100644
--- a/core/java/android/nfc/INfcCardEmulation.aidl
+++ b/core/java/android/nfc/INfcCardEmulation.aidl
@@ -39,4 +39,5 @@
boolean setPreferredService(in ComponentName service);
boolean unsetPreferredService();
boolean supportsAidPrefixRegistration();
+ ApduServiceInfo getPreferredPaymentService(int userHandle);
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 5715c9a..d320f61 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -164,6 +164,18 @@
"android.nfc.action.TRANSACTION_DETECTED";
/**
+ * Broadcast Action: Intent to notify if the preferred payment service changed.
+ *
+ * <p>This intent will only be sent to the application has requested permission for
+ * {@link android.Manifest.permission#NFC_PREFERRED_PAYMENT_INFO} and if the application
+ * has the necessary access to Secure Element which witnessed the particular event.
+ */
+ @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_PREFERRED_PAYMENT_CHANGED =
+ "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
+
+ /**
* Broadcast to only the activity that handles ACTION_TAG_DISCOVERED
* @hide
*/
@@ -231,6 +243,17 @@
*/
public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME";
+ /**
+ * Mandatory String extra field in {@link #ACTION_PREFERRED_PAYMENT_CHANGED}
+ * Indicates the condition when trigger this event.
+ */
+ public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON =
+ "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
+
+ public static final int PREFERRED_PAYMENT_LOADED = 1;
+ public static final int PREFERRED_PAYMENT_CHANGED = 2;
+ public static final int PREFERRED_PAYMENT_UPDATED = 3;
+
public static final int STATE_OFF = 1;
public static final int STATE_TURNING_ON = 2;
public static final int STATE_ON = 3;
@@ -1410,7 +1433,7 @@
/**
* Enable foreground dispatch to the given Activity.
*
- * <p>This will give give priority to the foreground activity when
+ * <p>This will give priority to the foreground activity when
* dispatching a discovered {@link Tag} to an application.
*
* <p>If any IntentFilters are provided to this method they are used to match dispatch Intents
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index aa93611..f1c74a6 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -17,6 +17,7 @@
package android.nfc.cardemulation;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -657,6 +658,109 @@
}
/**
+ * Retrieves the registered AIDs for the preferred payment service.
+ *
+ * @return The list of AIDs registered for this category, or null if it couldn't be found.
+ */
+ @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
+ @Nullable
+ public List<String> getAidsForPreferredPaymentService() {
+ try {
+ ApduServiceInfo serviceInfo = sService.getPreferredPaymentService(mContext.getUserId());
+ return (serviceInfo != null ? serviceInfo.getAids() : null);
+ } catch (RemoteException e) {
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ try {
+ ApduServiceInfo serviceInfo =
+ sService.getPreferredPaymentService(mContext.getUserId());
+ return (serviceInfo != null ? serviceInfo.getAids() : null);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Retrieves the route destination for the preferred payment service.
+ *
+ * @return The route destination secure element name of the preferred payment service.
+ * HCE payment: "Host"
+ * OffHost payment: prefix SIM or prefix eSE string.
+ * "OffHost" if the payment service does not specify secure element
+ * name.
+ */
+ @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
+ @Nullable
+ public String getRouteDestinationForPreferredPaymentService() {
+ try {
+ ApduServiceInfo serviceInfo = sService.getPreferredPaymentService(mContext.getUserId());
+ if (serviceInfo != null) {
+ if (!serviceInfo.isOnHost()) {
+ return serviceInfo.getOffHostSecureElement() == null ?
+ "OffHost" : serviceInfo.getOffHostSecureElement();
+ }
+ return "Host";
+ }
+ return null;
+ } catch (RemoteException e) {
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ try {
+ ApduServiceInfo serviceInfo =
+ sService.getPreferredPaymentService(mContext.getUserId());
+ if (serviceInfo != null) {
+ if (!serviceInfo.isOnHost()) {
+ return serviceInfo.getOffHostSecureElement() == null ?
+ "Offhost" : serviceInfo.getOffHostSecureElement();
+ }
+ return "Host";
+ }
+ return null;
+
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Returns a user-visible description of the preferred payment service.
+ *
+ * @return the preferred payment service description
+ */
+ @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
+ @Nullable
+ public String getDescriptionForPreferredPaymentService() {
+ try {
+ ApduServiceInfo serviceInfo = sService.getPreferredPaymentService(mContext.getUserId());
+ return (serviceInfo != null ? serviceInfo.getDescription() : null);
+ } catch (RemoteException e) {
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ try {
+ ApduServiceInfo serviceInfo =
+ sService.getPreferredPaymentService(mContext.getUserId());
+ return (serviceInfo != null ? serviceInfo.getDescription() : null);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ }
+ }
+
+ /**
* @hide
*/
public boolean setDefaultServiceForCategory(ComponentName service, String category) {
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 2f8e30e..82b04a6 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -20,6 +20,7 @@
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
@@ -552,6 +553,13 @@
public static final String REBOOT_SAFE_MODE = "safemode";
/**
+ * The 'reason' value used for rebooting userspace.
+ * @hide
+ */
+ @SystemApi
+ public static final String REBOOT_USERSPACE = "userspace";
+
+ /**
* The 'reason' value used when rebooting the device without turning on the screen.
* @hide
*/
@@ -1326,6 +1334,14 @@
}
/**
+ * Returns {@code true} if this device supports rebooting userspace.
+ */
+ // TODO(b/138605180): add link to documentation once it's ready.
+ public boolean isRebootingUserspaceSupported() {
+ return SystemProperties.getBoolean("ro.init.userspace_reboot.is_supported", false);
+ }
+
+ /**
* Reboot the device. Will not return if the reboot is successful.
* <p>
* Requires the {@link android.Manifest.permission#REBOOT} permission.
@@ -1333,8 +1349,14 @@
*
* @param reason code to pass to the kernel (e.g., "recovery") to
* request special boot modes, or null.
+ * @throws UnsupportedOperationException if userspace reboot was requested on a device that
+ * doesn't support it.
*/
- public void reboot(String reason) {
+ public void reboot(@Nullable String reason) {
+ if (REBOOT_USERSPACE.equals(reason) && !isRebootingUserspaceSupported()) {
+ throw new UnsupportedOperationException(
+ "Attempted userspace reboot on a device that doesn't support it");
+ }
try {
mService.reboot(false, reason, true);
} catch (RemoteException e) {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7efe0b7..fa9569b 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1550,6 +1550,9 @@
* set by the user and is not a placeholder string provided by the system.
* @hide
*/
+ @SystemApi
+ @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
+ Manifest.permission.GET_ACCOUNTS_PRIVILEGED})
public boolean isUserNameSet() {
try {
return mService.isUserNameSet(getUserHandle());
diff --git a/core/java/android/os/incremental/IncrementalManager.java b/core/java/android/os/incremental/IncrementalManager.java
index c722287..9c6672d 100644
--- a/core/java/android/os/incremental/IncrementalManager.java
+++ b/core/java/android/os/incremental/IncrementalManager.java
@@ -328,7 +328,9 @@
* Checks if path is mounted on Incremental File System.
*/
public static boolean isIncrementalPath(@NonNull String path) {
- // TODO(b/136132412): add jni implementation
- return false;
+ return nativeIsIncrementalPath(path);
}
+
+ /* Native methods */
+ private static native boolean nativeIsIncrementalPath(@NonNull String path);
}
diff --git a/core/java/android/permission/IPermissionController.aidl b/core/java/android/permission/IPermissionController.aidl
index 26c1ec1..0483514 100644
--- a/core/java/android/permission/IPermissionController.aidl
+++ b/core/java/android/permission/IPermissionController.aidl
@@ -43,4 +43,5 @@
String permission, int grantState, in AndroidFuture callback);
void grantOrUpgradeDefaultRuntimePermissions(in AndroidFuture callback);
void updateUserSensitive(in AndroidFuture callback);
+ void notifyOneTimePermissionSessionTimeout(String packageName);
}
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index 60c8811..2615c98 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -20,6 +20,7 @@
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.permission.SplitPermissionInfoParcelable;
+import android.os.UserHandle;
import android.permission.IOnPermissionsChangeListener;
/**
@@ -100,4 +101,9 @@
boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId);
List<SplitPermissionInfoParcelable> getSplitPermissions();
+
+ void startOneTimePermissionSession(String packageName, int userId, long timeout,
+ int importanceToResetTimer, int importanceToKeepSessionAlive);
+
+ void stopOneTimePermissionSession(String packageName, int userId);
}
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index 421e29e..2a1857f 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -636,4 +636,18 @@
return future;
});
}
+
+ /**
+ * Called when a package that has permissions registered as "one-time" is considered
+ * inactive.
+ *
+ * @param packageName The package which became inactive
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
+ public void notifyOneTimePermissionSessionTimeout(@NonNull String packageName) {
+ mRemoteService.run(
+ service -> service.notifyOneTimePermissionSessionTimeout(packageName));
+ }
}
diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java
index f914663..5d4561c 100644
--- a/core/java/android/permission/PermissionControllerService.java
+++ b/core/java/android/permission/PermissionControllerService.java
@@ -240,6 +240,18 @@
@NonNull String permission, @PermissionGrantState int grantState,
@NonNull Consumer<Boolean> callback);
+ /**
+ * Called when a package is considered inactive based on the criteria given by
+ * {@link PermissionManager#startOneTimePermissionSession(String, long, int, int)}.
+ * This method is called at the end of a one-time permission session
+ *
+ * @param packageName The package that has been inactive
+ */
+ @BinderThread
+ public void onOneTimePermissionSessionTimeout(@NonNull String packageName) {
+ throw new AbstractMethodError("Must be overridden in implementing class");
+ }
+
@Override
public final @NonNull IBinder onBind(Intent intent) {
return new IPermissionController.Stub() {
@@ -452,6 +464,15 @@
onUpdateUserSensitivePermissionFlags();
callback.complete(null);
}
+
+ @Override
+ public void notifyOneTimePermissionSessionTimeout(String packageName) {
+ enforceSomePermissionsGrantedToCaller(
+ Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
+ packageName = Preconditions.checkNotNull(packageName,
+ "packageName cannot be null");
+ onOneTimePermissionSessionTimeout(packageName);
+ }
};
}
}
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 09286fe..a3215a4 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -25,6 +25,7 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.app.ActivityManager;
import android.app.ActivityThread;
import android.content.Context;
import android.content.pm.IPackageManager;
@@ -284,4 +285,69 @@
mSplitPermissionInfoParcelable = parcelable;
}
}
+
+ /**
+ * Starts a one-time permission session for a given package. A one-time permission session is
+ * ended if app becomes inactive. Inactivity is defined as the package's uid importance level
+ * staying > importanceToResetTimer for timeoutMillis milliseconds. If the package's uid
+ * importance level goes <= importanceToResetTimer then the timer is reset and doesn't start
+ * until going > importanceToResetTimer.
+ * <p>
+ * When this timeoutMillis is reached if the importance level is <= importanceToKeepSessionAlive
+ * then the session is extended until either the importance goes above
+ * importanceToKeepSessionAlive which will end the session or <= importanceToResetTimer which
+ * will continue the session and reset the timer.
+ * </p>
+ * <p>
+ * Importance levels are defined in {@link android.app.ActivityManager.RunningAppProcessInfo}.
+ * </p>
+ * <p>
+ * Once the session ends
+ * {@link PermissionControllerService#onOneTimePermissionSessionTimeout(String)} is invoked.
+ * </p>
+ * <p>
+ * Note that if there is currently an active session for a package a new one isn't created and
+ * the existing one isn't changed.
+ * </p>
+ * @param packageName The package to start a one-time permission session for
+ * @param timeoutMillis Number of milliseconds for an app to be in an inactive state
+ * @param importanceToResetTimer The least important level to uid must be to reset the timer
+ * @param importanceToKeepSessionAlive The least important level the uid must be to keep the
+ * session alive
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(allOf = {Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
+ Manifest.permission.PACKAGE_USAGE_STATS})
+ public void startOneTimePermissionSession(@NonNull String packageName, long timeoutMillis,
+ @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer,
+ @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive) {
+ try {
+ mPermissionManager.startOneTimePermissionSession(packageName, mContext.getUserId(),
+ timeoutMillis, importanceToResetTimer, importanceToKeepSessionAlive);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Stops the one-time permission session for the package. The callback to the end of session is
+ * not invoked. If there is no one-time session for the package then nothing happens.
+ *
+ * @param packageName Package to stop the one-time permission session for
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(allOf = {Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
+ Manifest.permission.PACKAGE_USAGE_STATS})
+ public void stopOneTimePermissionSession(@NonNull String packageName) {
+ try {
+ mPermissionManager.stopOneTimePermissionSession(packageName,
+ mContext.getUserId());
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/provider/Column.java b/core/java/android/provider/Column.java
deleted file mode 100644
index 1364fb8..0000000
--- a/core/java/android/provider/Column.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2019 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.provider;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that a field is a {@link ContentProvider} column. It can be used as a
- * key for {@link ContentValues} when inserting or updating data, or as a
- * projection when querying.
- *
- * @hide
- */
-@Documented
-@Retention(RUNTIME)
-@Target({FIELD})
-public @interface Column {
- /**
- * The {@link Cursor#getType(int)} of the data stored in this column.
- */
- int value();
-
- /**
- * This column is read-only and cannot be defined during insert or updates.
- */
- boolean readOnly() default false;
-}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
deleted file mode 100644
index 63204d3..0000000
--- a/core/java/android/provider/MediaStore.java
+++ /dev/null
@@ -1,3832 +0,0 @@
-/*
- * Copyright (C) 2007 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.provider;
-
-import android.annotation.BytesLong;
-import android.annotation.CurrentTimeMillisLong;
-import android.annotation.CurrentTimeSecondsLong;
-import android.annotation.DurationMillisLong;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
-import android.annotation.UnsupportedAppUsage;
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.content.ClipData;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.UriPermission;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.ImageDecoder;
-import android.graphics.PostProcessor;
-import android.media.ExifInterface;
-import android.media.MediaFormat;
-import android.media.MediaMetadataRetriever;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.CancellationSignal;
-import android.os.Environment;
-import android.os.OperationCanceledException;
-import android.os.RemoteException;
-import android.os.storage.StorageManager;
-import android.os.storage.StorageVolume;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Log;
-import android.util.Size;
-
-import libcore.util.HexEncoding;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.text.Collator;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-/**
- * The contract between the media provider and applications. Contains
- * definitions for the supported URIs and columns.
- * <p>
- * The media provider provides an indexed collection of common media types, such
- * as {@link Audio}, {@link Video}, and {@link Images}, from any attached
- * storage devices. Each collection is organized based on the primary MIME type
- * of the underlying content; for example, {@code image/*} content is indexed
- * under {@link Images}. The {@link Files} collection provides a broad view
- * across all collections, and does not filter by MIME type.
- */
-public final class MediaStore {
- private final static String TAG = "MediaStore";
-
- /** The authority for the media provider */
- public static final String AUTHORITY = "media";
- /** A content:// style uri to the authority for the media provider */
- public static final @NonNull Uri AUTHORITY_URI =
- Uri.parse("content://" + AUTHORITY);
-
- /** @hide */
- public static final String AUTHORITY_LEGACY = "media_legacy";
- /** @hide */
- public static final @NonNull Uri AUTHORITY_LEGACY_URI =
- Uri.parse("content://" + AUTHORITY_LEGACY);
-
- /**
- * Synthetic volume name that provides a view of all content across the
- * "internal" storage of the device.
- * <p>
- * This synthetic volume provides a merged view of all media distributed
- * with the device, such as built-in ringtones and wallpapers.
- * <p>
- * Because this is a synthetic volume, you can't insert new content into
- * this volume.
- */
- public static final String VOLUME_INTERNAL = "internal";
-
- /**
- * Synthetic volume name that provides a view of all content across the
- * "external" storage of the device.
- * <p>
- * This synthetic volume provides a merged view of all media across all
- * currently attached external storage devices.
- * <p>
- * Because this is a synthetic volume, you can't insert new content into
- * this volume. Instead, you can insert content into a specific storage
- * volume obtained from {@link #getExternalVolumeNames(Context)}.
- */
- public static final String VOLUME_EXTERNAL = "external";
-
- /**
- * Specific volume name that represents the primary external storage device
- * at {@link Environment#getExternalStorageDirectory()}.
- * <p>
- * This volume may not always be available, such as when the user has
- * ejected the device. You can find a list of all specific volume names
- * using {@link #getExternalVolumeNames(Context)}.
- */
- public static final String VOLUME_EXTERNAL_PRIMARY = "external_primary";
-
- /** {@hide} */
- public static final String WAIT_FOR_IDLE_CALL = "wait_for_idle";
- /** {@hide} */
- public static final String SCAN_FILE_CALL = "scan_file";
- /** {@hide} */
- public static final String SCAN_VOLUME_CALL = "scan_volume";
- /** {@hide} */
- public static final String CREATE_WRITE_REQUEST_CALL = "create_write_request";
- /** {@hide} */
- public static final String CREATE_TRASH_REQUEST_CALL = "create_trash_request";
- /** {@hide} */
- public static final String CREATE_FAVORITE_REQUEST_CALL = "create_favorite_request";
- /** {@hide} */
- public static final String CREATE_DELETE_REQUEST_CALL = "create_delete_request";
-
-
- /** {@hide} */
- public static final String GET_VERSION_CALL = "get_version";
-
- /** {@hide} */
- public static final String GET_DOCUMENT_URI_CALL = "get_document_uri";
- /** {@hide} */
- public static final String GET_MEDIA_URI_CALL = "get_media_uri";
-
- /** {@hide} */
- public static final String EXTRA_URI = "uri";
- /** {@hide} */
- public static final String EXTRA_URI_PERMISSIONS = "uriPermissions";
-
- /** {@hide} */
- public static final String EXTRA_CLIP_DATA = "clip_data";
- /** {@hide} */
- public static final String EXTRA_CONTENT_VALUES = "content_values";
- /** {@hide} */
- public static final String EXTRA_RESULT = "result";
-
- /**
- * This is for internal use by the media scanner only.
- * Name of the (optional) Uri parameter that determines whether to skip deleting
- * the file pointed to by the _data column, when deleting the database entry.
- * The only appropriate value for this parameter is "false", in which case the
- * delete will be skipped. Note especially that setting this to true, or omitting
- * the parameter altogether, will perform the default action, which is different
- * for different types of media.
- * @hide
- */
- public static final String PARAM_DELETE_DATA = "deletedata";
-
- /** {@hide} */
- @Deprecated
- public static final String PARAM_INCLUDE_PENDING = "includePending";
- /** {@hide} */
- @Deprecated
- public static final String PARAM_INCLUDE_TRASHED = "includeTrashed";
- /** {@hide} */
- public static final String PARAM_PROGRESS = "progress";
- /** {@hide} */
- public static final String PARAM_REQUIRE_ORIGINAL = "requireOriginal";
- /** {@hide} */
- public static final String PARAM_LIMIT = "limit";
-
- /**
- * Activity Action: Launch a music player.
- * The activity should be able to play, browse, or manipulate music files stored on the device.
- *
- * @deprecated Use {@link android.content.Intent#CATEGORY_APP_MUSIC} instead.
- */
- @Deprecated
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String INTENT_ACTION_MUSIC_PLAYER = "android.intent.action.MUSIC_PLAYER";
-
- /**
- * Activity Action: Perform a search for media.
- * Contains at least the {@link android.app.SearchManager#QUERY} extra.
- * May also contain any combination of the following extras:
- * EXTRA_MEDIA_ARTIST, EXTRA_MEDIA_ALBUM, EXTRA_MEDIA_TITLE, EXTRA_MEDIA_FOCUS
- *
- * @see android.provider.MediaStore#EXTRA_MEDIA_ARTIST
- * @see android.provider.MediaStore#EXTRA_MEDIA_ALBUM
- * @see android.provider.MediaStore#EXTRA_MEDIA_TITLE
- * @see android.provider.MediaStore#EXTRA_MEDIA_FOCUS
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String INTENT_ACTION_MEDIA_SEARCH = "android.intent.action.MEDIA_SEARCH";
-
- /**
- * An intent to perform a search for music media and automatically play content from the
- * result when possible. This can be fired, for example, by the result of a voice recognition
- * command to listen to music.
- * <p>This intent always includes the {@link android.provider.MediaStore#EXTRA_MEDIA_FOCUS}
- * and {@link android.app.SearchManager#QUERY} extras. The
- * {@link android.provider.MediaStore#EXTRA_MEDIA_FOCUS} extra determines the search mode, and
- * the value of the {@link android.app.SearchManager#QUERY} extra depends on the search mode.
- * For more information about the search modes for this intent, see
- * <a href="{@docRoot}guide/components/intents-common.html#PlaySearch">Play music based
- * on a search query</a> in <a href="{@docRoot}guide/components/intents-common.html">Common
- * Intents</a>.</p>
- *
- * <p>This intent makes the most sense for apps that can support large-scale search of music,
- * such as services connected to an online database of music which can be streamed and played
- * on the device.</p>
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH =
- "android.media.action.MEDIA_PLAY_FROM_SEARCH";
-
- /**
- * An intent to perform a search for readable media and automatically play content from the
- * result when possible. This can be fired, for example, by the result of a voice recognition
- * command to read a book or magazine.
- * <p>
- * Contains the {@link android.app.SearchManager#QUERY} extra, which is a string that can
- * contain any type of unstructured text search, like the name of a book or magazine, an author
- * a genre, a publisher, or any combination of these.
- * <p>
- * Because this intent includes an open-ended unstructured search string, it makes the most
- * sense for apps that can support large-scale search of text media, such as services connected
- * to an online database of books and/or magazines which can be read on the device.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String INTENT_ACTION_TEXT_OPEN_FROM_SEARCH =
- "android.media.action.TEXT_OPEN_FROM_SEARCH";
-
- /**
- * An intent to perform a search for video media and automatically play content from the
- * result when possible. This can be fired, for example, by the result of a voice recognition
- * command to play movies.
- * <p>
- * Contains the {@link android.app.SearchManager#QUERY} extra, which is a string that can
- * contain any type of unstructured video search, like the name of a movie, one or more actors,
- * a genre, or any combination of these.
- * <p>
- * Because this intent includes an open-ended unstructured search string, it makes the most
- * sense for apps that can support large-scale search of video, such as services connected to an
- * online database of videos which can be streamed and played on the device.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String INTENT_ACTION_VIDEO_PLAY_FROM_SEARCH =
- "android.media.action.VIDEO_PLAY_FROM_SEARCH";
-
- /**
- * The name of the Intent-extra used to define the artist
- */
- public static final String EXTRA_MEDIA_ARTIST = "android.intent.extra.artist";
- /**
- * The name of the Intent-extra used to define the album
- */
- public static final String EXTRA_MEDIA_ALBUM = "android.intent.extra.album";
- /**
- * The name of the Intent-extra used to define the song title
- */
- public static final String EXTRA_MEDIA_TITLE = "android.intent.extra.title";
- /**
- * The name of the Intent-extra used to define the genre.
- */
- public static final String EXTRA_MEDIA_GENRE = "android.intent.extra.genre";
- /**
- * The name of the Intent-extra used to define the playlist.
- */
- public static final String EXTRA_MEDIA_PLAYLIST = "android.intent.extra.playlist";
- /**
- * The name of the Intent-extra used to define the radio channel.
- */
- public static final String EXTRA_MEDIA_RADIO_CHANNEL = "android.intent.extra.radio_channel";
- /**
- * The name of the Intent-extra used to define the search focus. The search focus
- * indicates whether the search should be for things related to the artist, album
- * or song that is identified by the other extras.
- */
- public static final String EXTRA_MEDIA_FOCUS = "android.intent.extra.focus";
-
- /**
- * The name of the Intent-extra used to control the orientation of a ViewImage or a MovieView.
- * This is an int property that overrides the activity's requestedOrientation.
- * @see android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED
- */
- public static final String EXTRA_SCREEN_ORIENTATION = "android.intent.extra.screenOrientation";
-
- /**
- * The name of an Intent-extra used to control the UI of a ViewImage.
- * This is a boolean property that overrides the activity's default fullscreen state.
- */
- public static final String EXTRA_FULL_SCREEN = "android.intent.extra.fullScreen";
-
- /**
- * The name of an Intent-extra used to control the UI of a ViewImage.
- * This is a boolean property that specifies whether or not to show action icons.
- */
- public static final String EXTRA_SHOW_ACTION_ICONS = "android.intent.extra.showActionIcons";
-
- /**
- * The name of the Intent-extra used to control the onCompletion behavior of a MovieView.
- * This is a boolean property that specifies whether or not to finish the MovieView activity
- * when the movie completes playing. The default value is true, which means to automatically
- * exit the movie player activity when the movie completes playing.
- */
- public static final String EXTRA_FINISH_ON_COMPLETION = "android.intent.extra.finishOnCompletion";
-
- /**
- * The name of the Intent action used to launch a camera in still image mode.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String INTENT_ACTION_STILL_IMAGE_CAMERA = "android.media.action.STILL_IMAGE_CAMERA";
-
- /**
- * Name under which an activity handling {@link #INTENT_ACTION_STILL_IMAGE_CAMERA} or
- * {@link #INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE} publishes the service name for its prewarm
- * service.
- * <p>
- * This meta-data should reference the fully qualified class name of the prewarm service
- * extending {@code CameraPrewarmService}.
- * <p>
- * The prewarm service will get bound and receive a prewarm signal
- * {@code CameraPrewarmService#onPrewarm()} when a camera launch intent fire might be imminent.
- * An application implementing a prewarm service should do the absolute minimum amount of work
- * to initialize the camera in order to reduce startup time in likely case that shortly after a
- * camera launch intent would be sent.
- */
- public static final String META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE =
- "android.media.still_image_camera_preview_service";
-
- /**
- * The name of the Intent action used to launch a camera in still image mode
- * for use when the device is secured (e.g. with a pin, password, pattern,
- * or face unlock). Applications responding to this intent must not expose
- * any personal content like existing photos or videos on the device. The
- * applications should be careful not to share any photo or video with other
- * applications or internet. The activity should use {@link
- * Activity#setShowWhenLocked} to display
- * on top of the lock screen while secured. There is no activity stack when
- * this flag is used, so launching more than one activity is strongly
- * discouraged.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE =
- "android.media.action.STILL_IMAGE_CAMERA_SECURE";
-
- /**
- * The name of the Intent action used to launch a camera in video mode.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String INTENT_ACTION_VIDEO_CAMERA = "android.media.action.VIDEO_CAMERA";
-
- /**
- * Standard Intent action that can be sent to have the camera application
- * capture an image and return it.
- * <p>
- * The caller may pass an extra EXTRA_OUTPUT to control where this image will be written.
- * If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap
- * object in the extra field. This is useful for applications that only need a small image.
- * If the EXTRA_OUTPUT is present, then the full-sized image will be written to the Uri
- * value of EXTRA_OUTPUT.
- * As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this uri can also be supplied through
- * {@link android.content.Intent#setClipData(ClipData)}. If using this approach, you still must
- * supply the uri through the EXTRA_OUTPUT field for compatibility with old applications.
- * If you don't set a ClipData, it will be copied there for you when calling
- * {@link Context#startActivity(Intent)}.
- *
- * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} and above
- * and declares as using the {@link android.Manifest.permission#CAMERA} permission which
- * is not granted, then attempting to use this action will result in a {@link
- * java.lang.SecurityException}.
- *
- * @see #EXTRA_OUTPUT
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public final static String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
-
- /**
- * Intent action that can be sent to have the camera application capture an image and return
- * it when the device is secured (e.g. with a pin, password, pattern, or face unlock).
- * Applications responding to this intent must not expose any personal content like existing
- * photos or videos on the device. The applications should be careful not to share any photo
- * or video with other applications or Internet. The activity should use {@link
- * Activity#setShowWhenLocked} to display on top of the
- * lock screen while secured. There is no activity stack when this flag is used, so
- * launching more than one activity is strongly discouraged.
- * <p>
- * The caller may pass an extra EXTRA_OUTPUT to control where this image will be written.
- * If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap
- * object in the extra field. This is useful for applications that only need a small image.
- * If the EXTRA_OUTPUT is present, then the full-sized image will be written to the Uri
- * value of EXTRA_OUTPUT.
- * As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this uri can also be supplied through
- * {@link android.content.Intent#setClipData(ClipData)}. If using this approach, you still must
- * supply the uri through the EXTRA_OUTPUT field for compatibility with old applications.
- * If you don't set a ClipData, it will be copied there for you when calling
- * {@link Context#startActivity(Intent)}.
- *
- * @see #ACTION_IMAGE_CAPTURE
- * @see #EXTRA_OUTPUT
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_IMAGE_CAPTURE_SECURE =
- "android.media.action.IMAGE_CAPTURE_SECURE";
-
- /**
- * Standard Intent action that can be sent to have the camera application
- * capture a video and return it.
- * <p>
- * The caller may pass in an extra EXTRA_VIDEO_QUALITY to control the video quality.
- * <p>
- * The caller may pass in an extra EXTRA_OUTPUT to control
- * where the video is written. If EXTRA_OUTPUT is not present the video will be
- * written to the standard location for videos, and the Uri of that location will be
- * returned in the data field of the Uri.
- * As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this uri can also be supplied through
- * {@link android.content.Intent#setClipData(ClipData)}. If using this approach, you still must
- * supply the uri through the EXTRA_OUTPUT field for compatibility with old applications.
- * If you don't set a ClipData, it will be copied there for you when calling
- * {@link Context#startActivity(Intent)}.
- *
- * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} and above
- * and declares as using the {@link android.Manifest.permission#CAMERA} permission which
- * is not granted, then atempting to use this action will result in a {@link
- * java.lang.SecurityException}.
- *
- * @see #EXTRA_OUTPUT
- * @see #EXTRA_VIDEO_QUALITY
- * @see #EXTRA_SIZE_LIMIT
- * @see #EXTRA_DURATION_LIMIT
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public final static String ACTION_VIDEO_CAPTURE = "android.media.action.VIDEO_CAPTURE";
-
- /**
- * Standard action that can be sent to review the given media file.
- * <p>
- * The launched application is expected to provide a large-scale view of the
- * given media file, while allowing the user to quickly access other
- * recently captured media files.
- * <p>
- * Input: {@link Intent#getData} is URI of the primary media item to
- * initially display.
- *
- * @see #ACTION_REVIEW_SECURE
- * @see #EXTRA_BRIGHTNESS
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public final static String ACTION_REVIEW = "android.provider.action.REVIEW";
-
- /**
- * Standard action that can be sent to review the given media file when the
- * device is secured (e.g. with a pin, password, pattern, or face unlock).
- * The applications should be careful not to share any media with other
- * applications or Internet. The activity should use
- * {@link Activity#setShowWhenLocked} to display on top of the lock screen
- * while secured. There is no activity stack when this flag is used, so
- * launching more than one activity is strongly discouraged.
- * <p>
- * The launched application is expected to provide a large-scale view of the
- * given primary media file, while only allowing the user to quickly access
- * other media from an explicit secondary list.
- * <p>
- * Input: {@link Intent#getData} is URI of the primary media item to
- * initially display. {@link Intent#getClipData} is the limited list of
- * secondary media items that the user is allowed to review. If
- * {@link Intent#getClipData} is undefined, then no other media access
- * should be allowed.
- *
- * @see #EXTRA_BRIGHTNESS
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public final static String ACTION_REVIEW_SECURE = "android.provider.action.REVIEW_SECURE";
-
- /**
- * When defined, the launched application is requested to set the given
- * brightness value via
- * {@link android.view.WindowManager.LayoutParams#screenBrightness} to help
- * ensure a smooth transition when launching {@link #ACTION_REVIEW} or
- * {@link #ACTION_REVIEW_SECURE} intents.
- */
- public final static String EXTRA_BRIGHTNESS = "android.provider.extra.BRIGHTNESS";
-
- /**
- * The name of the Intent-extra used to control the quality of a recorded video. This is an
- * integer property. Currently value 0 means low quality, suitable for MMS messages, and
- * value 1 means high quality. In the future other quality levels may be added.
- */
- public final static String EXTRA_VIDEO_QUALITY = "android.intent.extra.videoQuality";
-
- /**
- * Specify the maximum allowed size.
- */
- public final static String EXTRA_SIZE_LIMIT = "android.intent.extra.sizeLimit";
-
- /**
- * Specify the maximum allowed recording duration in seconds.
- */
- public final static String EXTRA_DURATION_LIMIT = "android.intent.extra.durationLimit";
-
- /**
- * The name of the Intent-extra used to indicate a content resolver Uri to be used to
- * store the requested image or video.
- */
- public final static String EXTRA_OUTPUT = "output";
-
- /**
- * The string that is used when a media attribute is not known. For example,
- * if an audio file does not have any meta data, the artist and album columns
- * will be set to this value.
- */
- public static final String UNKNOWN_STRING = "<unknown>";
-
- /**
- * Specify a {@link Uri} that is "related" to the current operation being
- * performed.
- * <p>
- * This is typically used to allow an operation that may normally be
- * rejected, such as making a copy of a pre-existing image located under a
- * {@link MediaColumns#RELATIVE_PATH} where new images are not allowed.
- * <p>
- * It's strongly recommended that when making a copy of pre-existing content
- * that you define the "original document ID" GUID as defined by the <em>XMP
- * Media Management</em> standard.
- * <p>
- * This key can be placed in a {@link Bundle} of extras and passed to
- * {@link ContentResolver#insert}.
- */
- public static final String QUERY_ARG_RELATED_URI = "android:query-arg-related-uri";
-
- /**
- * Specify how {@link MediaColumns#IS_PENDING} items should be filtered when
- * performing a {@link MediaStore} operation.
- * <p>
- * This key can be placed in a {@link Bundle} of extras and passed to
- * {@link ContentResolver#query}, {@link ContentResolver#update}, or
- * {@link ContentResolver#delete}.
- * <p>
- * By default, pending items are filtered away from operations.
- */
- @Match
- public static final String QUERY_ARG_MATCH_PENDING = "android:query-arg-match-pending";
-
- /**
- * Specify how {@link MediaColumns#IS_TRASHED} items should be filtered when
- * performing a {@link MediaStore} operation.
- * <p>
- * This key can be placed in a {@link Bundle} of extras and passed to
- * {@link ContentResolver#query}, {@link ContentResolver#update}, or
- * {@link ContentResolver#delete}.
- * <p>
- * By default, trashed items are filtered away from operations.
- *
- * @see MediaColumns#IS_TRASHED
- * @see MediaStore#QUERY_ARG_MATCH_TRASHED
- * @see MediaStore#createTrashRequest
- */
- @Match
- public static final String QUERY_ARG_MATCH_TRASHED = "android:query-arg-match-trashed";
-
- /**
- * Specify how {@link MediaColumns#IS_FAVORITE} items should be filtered
- * when performing a {@link MediaStore} operation.
- * <p>
- * This key can be placed in a {@link Bundle} of extras and passed to
- * {@link ContentResolver#query}, {@link ContentResolver#update}, or
- * {@link ContentResolver#delete}.
- * <p>
- * By default, favorite items are <em>not</em> filtered away from
- * operations.
- *
- * @see MediaColumns#IS_FAVORITE
- * @see MediaStore#QUERY_ARG_MATCH_FAVORITE
- * @see MediaStore#createFavoriteRequest
- */
- @Match
- public static final String QUERY_ARG_MATCH_FAVORITE = "android:query-arg-match-favorite";
-
- /** @hide */
- @IntDef(flag = true, prefix = { "MATCH_" }, value = {
- MATCH_DEFAULT,
- MATCH_INCLUDE,
- MATCH_EXCLUDE,
- MATCH_ONLY,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Match {}
-
- /**
- * Value indicating that the default matching behavior should be used, as
- * defined by the key documentation.
- */
- public static final int MATCH_DEFAULT = 0;
-
- /**
- * Value indicating that operations should include items matching the
- * criteria defined by this key.
- * <p>
- * Note that items <em>not</em> matching the criteria <em>may</em> also be
- * included depending on the default behavior documented by the key. If you
- * want to operate exclusively on matching items, use {@link #MATCH_ONLY}.
- */
- public static final int MATCH_INCLUDE = 1;
-
- /**
- * Value indicating that operations should exclude items matching the
- * criteria defined by this key.
- */
- public static final int MATCH_EXCLUDE = 2;
-
- /**
- * Value indicating that operations should only operate on items explicitly
- * matching the criteria defined by this key.
- */
- public static final int MATCH_ONLY = 3;
-
- /**
- * Update the given {@link Uri} to also include any pending media items from
- * calls such as
- * {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
- * By default no pending items are returned.
- *
- * @see MediaColumns#IS_PENDING
- * @see MediaStore#getIncludePending(Uri)
- * @deprecated consider migrating to {@link #QUERY_ARG_MATCH_PENDING} which
- * is more expressive.
- */
- @Deprecated
- public static @NonNull Uri setIncludePending(@NonNull Uri uri) {
- return setIncludePending(uri.buildUpon()).build();
- }
-
- /** @hide */
- @Deprecated
- public static @NonNull Uri.Builder setIncludePending(@NonNull Uri.Builder uriBuilder) {
- return uriBuilder.appendQueryParameter(PARAM_INCLUDE_PENDING, "1");
- }
-
- /**
- * Return if any pending media items should be included in calls such as
- * {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
- *
- * @see MediaColumns#IS_PENDING
- * @see MediaStore#setIncludePending(Uri)
- * @deprecated consider migrating to {@link #QUERY_ARG_MATCH_PENDING} which
- * is more expressive.
- * @removed
- */
- @Deprecated
- public static boolean getIncludePending(@NonNull Uri uri) {
- return parseBoolean(uri.getQueryParameter(MediaStore.PARAM_INCLUDE_PENDING));
- }
-
- /**
- * Update the given {@link Uri} to also include any trashed media items from
- * calls such as
- * {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
- * By default no trashed items are returned.
- *
- * @see MediaColumns#IS_TRASHED
- * @see MediaStore#setIncludeTrashed(Uri)
- * @see MediaStore#trash(Context, Uri)
- * @see MediaStore#untrash(Context, Uri)
- * @deprecated consider migrating to {@link #QUERY_ARG_MATCH_TRASHED} which
- * is more expressive.
- * @removed
- */
- @Deprecated
- public static @NonNull Uri setIncludeTrashed(@NonNull Uri uri) {
- return uri.buildUpon().appendQueryParameter(PARAM_INCLUDE_TRASHED, "1").build();
- }
-
- /**
- * Update the given {@link Uri} to indicate that the caller requires the
- * original file contents when calling
- * {@link ContentResolver#openFileDescriptor(Uri, String)}.
- * <p>
- * This can be useful when the caller wants to ensure they're backing up the
- * exact bytes of the underlying media, without any Exif redaction being
- * performed.
- * <p>
- * If the original file contents cannot be provided, a
- * {@link UnsupportedOperationException} will be thrown when the returned
- * {@link Uri} is used, such as when the caller doesn't hold
- * {@link android.Manifest.permission#ACCESS_MEDIA_LOCATION}.
- *
- * @see MediaStore#getRequireOriginal(Uri)
- */
- public static @NonNull Uri setRequireOriginal(@NonNull Uri uri) {
- return uri.buildUpon().appendQueryParameter(PARAM_REQUIRE_ORIGINAL, "1").build();
- }
-
- /**
- * Return if the caller requires the original file contents when calling
- * {@link ContentResolver#openFileDescriptor(Uri, String)}.
- *
- * @see MediaStore#setRequireOriginal(Uri)
- */
- public static boolean getRequireOriginal(@NonNull Uri uri) {
- return parseBoolean(uri.getQueryParameter(MediaStore.PARAM_REQUIRE_ORIGINAL));
- }
-
- /**
- * Mark the given item as being "trashed", meaning it should be deleted at
- * some point in the future. This is a more gentle operation than simply
- * calling {@link ContentResolver#delete(Uri, String, String[])}, which
- * would take effect immediately.
- * <p>
- * This method preserves trashed items for at least 48 hours before erasing
- * them, giving the user a chance to untrash the item.
- *
- * @see MediaColumns#IS_TRASHED
- * @see MediaStore#setIncludeTrashed(Uri)
- * @see MediaStore#trash(Context, Uri)
- * @see MediaStore#untrash(Context, Uri)
- * @removed
- */
- @Deprecated
- public static void trash(@NonNull Context context, @NonNull Uri uri) {
- trash(context, uri, 48 * DateUtils.HOUR_IN_MILLIS);
- }
-
- /**
- * Mark the given item as being "trashed", meaning it should be deleted at
- * some point in the future. This is a more gentle operation than simply
- * calling {@link ContentResolver#delete(Uri, String, String[])}, which
- * would take effect immediately.
- * <p>
- * This method preserves trashed items for at least the given timeout before
- * erasing them, giving the user a chance to untrash the item.
- *
- * @see MediaColumns#IS_TRASHED
- * @see MediaStore#setIncludeTrashed(Uri)
- * @see MediaStore#trash(Context, Uri)
- * @see MediaStore#untrash(Context, Uri)
- * @removed
- */
- @Deprecated
- public static void trash(@NonNull Context context, @NonNull Uri uri,
- @DurationMillisLong long timeoutMillis) {
- if (timeoutMillis < 0) {
- throw new IllegalArgumentException();
- }
-
- final ContentValues values = new ContentValues();
- values.put(MediaColumns.IS_TRASHED, 1);
- values.put(MediaColumns.DATE_EXPIRES,
- (System.currentTimeMillis() + timeoutMillis) / 1000);
- context.getContentResolver().update(uri, values, null, null);
- }
-
- /**
- * Mark the given item as being "untrashed", meaning it should no longer be
- * deleted as previously requested through {@link #trash(Context, Uri)}.
- *
- * @see MediaColumns#IS_TRASHED
- * @see MediaStore#setIncludeTrashed(Uri)
- * @see MediaStore#trash(Context, Uri)
- * @see MediaStore#untrash(Context, Uri)
- * @removed
- */
- @Deprecated
- public static void untrash(@NonNull Context context, @NonNull Uri uri) {
- final ContentValues values = new ContentValues();
- values.put(MediaColumns.IS_TRASHED, 0);
- values.putNull(MediaColumns.DATE_EXPIRES);
- context.getContentResolver().update(uri, values, null, null);
- }
-
- /**
- * Rewrite the given {@link Uri} to point at
- * {@link MediaStore#AUTHORITY_LEGACY}.
- *
- * @hide
- */
- public static @NonNull Uri rewriteToLegacy(@NonNull Uri uri) {
- return uri.buildUpon().authority(MediaStore.AUTHORITY_LEGACY).build();
- }
-
- private static @NonNull PendingIntent createRequest(@NonNull ContentResolver resolver,
- @NonNull String method, @NonNull Collection<Uri> uris, @Nullable ContentValues values) {
- Objects.requireNonNull(resolver);
- Objects.requireNonNull(uris);
-
- final Iterator<Uri> it = uris.iterator();
- final ClipData clipData = ClipData.newRawUri(null, it.next());
- while (it.hasNext()) {
- clipData.addItem(new ClipData.Item(it.next()));
- }
-
- final Bundle extras = new Bundle();
- extras.putParcelable(EXTRA_CLIP_DATA, clipData);
- extras.putParcelable(EXTRA_CONTENT_VALUES, values);
- return resolver.call(AUTHORITY, method, null, extras).getParcelable(EXTRA_RESULT);
- }
-
- /**
- * Create a {@link PendingIntent} that will prompt the user to grant your
- * app write access for the requested media items.
- * <p>
- * This call only generates the request for a prompt; to display the prompt,
- * call {@link Activity#startIntentSenderForResult} with
- * {@link PendingIntent#getIntentSender()}. You can then determine if the
- * user granted your request by testing for {@link Activity#RESULT_OK} in
- * {@link Activity#onActivityResult}.
- * <p>
- * Permissions granted through this mechanism are tied to the lifecycle of
- * the {@link Activity} that requests them. If you need to retain
- * longer-term access for background actions, you can place items into a
- * {@link ClipData} or {@link Intent} which can then be passed to
- * {@link Context#startService} or
- * {@link android.app.job.JobInfo.Builder#setClipData}. Be sure to include
- * any relevant access modes you want to retain, such as
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
- * <p>
- * The displayed prompt will reflect all the media items you're requesting,
- * including those for which you already hold write access. If you want to
- * determine if you already hold write access before requesting access, use
- * {@code ContentResolver#checkUriPermission(Uri, int, int)} with
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
- * <p>
- * For security and performance reasons this method does not support
- * {@link Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_PREFIX_URI_PERMISSION}.
- *
- * @param resolver Used to connect with {@link MediaStore#AUTHORITY}.
- * Typically this value is {@link Context#getContentResolver()},
- * but if you need more explicit lifecycle controls, you can
- * obtain a {@link ContentProviderClient} and wrap it using
- * {@link ContentResolver#wrap(ContentProviderClient)}.
- * @param uris The set of media items to include in this request. Each item
- * must be hosted by {@link MediaStore#AUTHORITY} and must
- * reference a specific media item by {@link BaseColumns#_ID}.
- */
- public static @NonNull PendingIntent createWriteRequest(@NonNull ContentResolver resolver,
- @NonNull Collection<Uri> uris) {
- return createRequest(resolver, CREATE_WRITE_REQUEST_CALL, uris, null);
- }
-
- /**
- * Create a {@link PendingIntent} that will prompt the user to trash the
- * requested media items. When the user approves this request,
- * {@link MediaColumns#IS_TRASHED} is set on these items.
- * <p>
- * This call only generates the request for a prompt; to display the prompt,
- * call {@link Activity#startIntentSenderForResult} with
- * {@link PendingIntent#getIntentSender()}. You can then determine if the
- * user granted your request by testing for {@link Activity#RESULT_OK} in
- * {@link Activity#onActivityResult}.
- * <p>
- * The displayed prompt will reflect all the media items you're requesting,
- * including those for which you already hold write access. If you want to
- * determine if you already hold write access before requesting access, use
- * {@code ContentResolver#checkUriPermission(Uri, int, int)} with
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
- *
- * @param resolver Used to connect with {@link MediaStore#AUTHORITY}.
- * Typically this value is {@link Context#getContentResolver()},
- * but if you need more explicit lifecycle controls, you can
- * obtain a {@link ContentProviderClient} and wrap it using
- * {@link ContentResolver#wrap(ContentProviderClient)}.
- * @param uris The set of media items to include in this request. Each item
- * must be hosted by {@link MediaStore#AUTHORITY} and must
- * reference a specific media item by {@link BaseColumns#_ID}.
- * @param value The {@link MediaColumns#IS_TRASHED} value to apply.
- * @see MediaColumns#IS_TRASHED
- * @see MediaStore#QUERY_ARG_MATCH_TRASHED
- */
- public static @NonNull PendingIntent createTrashRequest(@NonNull ContentResolver resolver,
- @NonNull Collection<Uri> uris, boolean value) {
- final ContentValues values = new ContentValues();
- if (value) {
- values.put(MediaColumns.IS_TRASHED, 1);
- values.put(MediaColumns.DATE_EXPIRES,
- (System.currentTimeMillis() + DateUtils.WEEK_IN_MILLIS) / 1000);
- } else {
- values.put(MediaColumns.IS_TRASHED, 0);
- values.putNull(MediaColumns.DATE_EXPIRES);
- }
- return createRequest(resolver, CREATE_TRASH_REQUEST_CALL, uris, values);
- }
-
- /**
- * Create a {@link PendingIntent} that will prompt the user to favorite the
- * requested media items. When the user approves this request,
- * {@link MediaColumns#IS_FAVORITE} is set on these items.
- * <p>
- * This call only generates the request for a prompt; to display the prompt,
- * call {@link Activity#startIntentSenderForResult} with
- * {@link PendingIntent#getIntentSender()}. You can then determine if the
- * user granted your request by testing for {@link Activity#RESULT_OK} in
- * {@link Activity#onActivityResult}.
- * <p>
- * The displayed prompt will reflect all the media items you're requesting,
- * including those for which you already hold write access. If you want to
- * determine if you already hold write access before requesting access, use
- * {@code ContentResolver#checkUriPermission(Uri, int, int)} with
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
- *
- * @param resolver Used to connect with {@link MediaStore#AUTHORITY}.
- * Typically this value is {@link Context#getContentResolver()},
- * but if you need more explicit lifecycle controls, you can
- * obtain a {@link ContentProviderClient} and wrap it using
- * {@link ContentResolver#wrap(ContentProviderClient)}.
- * @param uris The set of media items to include in this request. Each item
- * must be hosted by {@link MediaStore#AUTHORITY} and must
- * reference a specific media item by {@link BaseColumns#_ID}.
- * @param value The {@link MediaColumns#IS_FAVORITE} value to apply.
- * @see MediaColumns#IS_FAVORITE
- * @see MediaStore#QUERY_ARG_MATCH_FAVORITE
- */
- public static @NonNull PendingIntent createFavoriteRequest(@NonNull ContentResolver resolver,
- @NonNull Collection<Uri> uris, boolean value) {
- final ContentValues values = new ContentValues();
- if (value) {
- values.put(MediaColumns.IS_FAVORITE, 1);
- } else {
- values.put(MediaColumns.IS_FAVORITE, 0);
- }
- return createRequest(resolver, CREATE_FAVORITE_REQUEST_CALL, uris, values);
- }
-
- /**
- * Create a {@link PendingIntent} that will prompt the user to permanently
- * delete the requested media items. When the user approves this request,
- * {@link ContentResolver#delete} will be called on these items.
- * <p>
- * This call only generates the request for a prompt; to display the prompt,
- * call {@link Activity#startIntentSenderForResult} with
- * {@link PendingIntent#getIntentSender()}. You can then determine if the
- * user granted your request by testing for {@link Activity#RESULT_OK} in
- * {@link Activity#onActivityResult}.
- * <p>
- * The displayed prompt will reflect all the media items you're requesting,
- * including those for which you already hold write access. If you want to
- * determine if you already hold write access before requesting access, use
- * {@code ContentResolver#checkUriPermission(Uri, int, int)} with
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
- *
- * @param resolver Used to connect with {@link MediaStore#AUTHORITY}.
- * Typically this value is {@link Context#getContentResolver()},
- * but if you need more explicit lifecycle controls, you can
- * obtain a {@link ContentProviderClient} and wrap it using
- * {@link ContentResolver#wrap(ContentProviderClient)}.
- * @param uris The set of media items to include in this request. Each item
- * must be hosted by {@link MediaStore#AUTHORITY} and must
- * reference a specific media item by {@link BaseColumns#_ID}.
- */
- public static @NonNull PendingIntent createDeleteRequest(@NonNull ContentResolver resolver,
- @NonNull Collection<Uri> uris) {
- return createRequest(resolver, CREATE_DELETE_REQUEST_CALL, uris, null);
- }
-
- /**
- * Common media metadata columns.
- */
- public interface MediaColumns extends BaseColumns {
- /**
- * Absolute filesystem path to the media item on disk.
- * <p>
- * Note that apps may not have filesystem permissions to directly access
- * this path. Instead of trying to open this path directly, apps should
- * use {@link ContentResolver#openFileDescriptor(Uri, String)} to gain
- * access.
- *
- * @deprecated Apps may not have filesystem permissions to directly
- * access this path. Instead of trying to open this path
- * directly, apps should use
- * {@link ContentResolver#openFileDescriptor(Uri, String)}
- * to gain access.
- */
- @Deprecated
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String DATA = "_data";
-
- /**
- * Indexed value of {@link File#length()} extracted from this media
- * item.
- */
- @BytesLong
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String SIZE = "_size";
-
- /**
- * The display name of the media item.
- * <p>
- * For example, an item stored at
- * {@code /storage/0000-0000/DCIM/Vacation/IMG1024.JPG} would have a
- * display name of {@code IMG1024.JPG}.
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String DISPLAY_NAME = "_display_name";
-
- /**
- * The time the media item was first added.
- */
- @CurrentTimeSecondsLong
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String DATE_ADDED = "date_added";
-
- /**
- * Indexed value of {@link File#lastModified()} extracted from this
- * media item.
- */
- @CurrentTimeSecondsLong
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String DATE_MODIFIED = "date_modified";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_DATE} or
- * {@link ExifInterface#TAG_DATETIME_ORIGINAL} extracted from this media
- * item.
- * <p>
- * Note that images must define both
- * {@link ExifInterface#TAG_DATETIME_ORIGINAL} and
- * {@code ExifInterface#TAG_OFFSET_TIME_ORIGINAL} to reliably determine
- * this value in relation to the epoch.
- */
- @CurrentTimeMillisLong
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String DATE_TAKEN = "datetaken";
-
- /**
- * The MIME type of the media item.
- * <p>
- * This is typically defined based on the file extension of the media
- * item. However, it may be the value of the {@code format} attribute
- * defined by the <em>Dublin Core Media Initiative</em> standard,
- * extracted from any XMP metadata contained within this media item.
- * <p class="note">
- * Note: the {@code format} attribute may be ignored if the top-level
- * MIME type disagrees with the file extension. For example, it's
- * reasonable for an {@code image/jpeg} file to declare a {@code format}
- * of {@code image/vnd.google.panorama360+jpg}, but declaring a
- * {@code format} of {@code audio/ogg} would be ignored.
- * <p>
- * This is a read-only column that is automatically computed.
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String MIME_TYPE = "mime_type";
-
- /**
- * Non-zero if the media file is drm-protected
- * @hide
- */
- @UnsupportedAppUsage
- @Deprecated
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String IS_DRM = "is_drm";
-
- /**
- * Flag indicating if a media item is pending, and still being inserted
- * by its owner. While this flag is set, only the owner of the item can
- * open the underlying file; requests from other apps will be rejected.
- * <p>
- * Pending items are retained either until they are published by setting
- * the field to {@code 0}, or until they expire as defined by
- * {@link #DATE_EXPIRES}.
- *
- * @see MediaStore#QUERY_ARG_MATCH_PENDING
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String IS_PENDING = "is_pending";
-
- /**
- * Flag indicating if a media item is trashed.
- * <p>
- * Trashed items are retained until they expire as defined by
- * {@link #DATE_EXPIRES}.
- *
- * @see MediaColumns#IS_TRASHED
- * @see MediaStore#QUERY_ARG_MATCH_TRASHED
- * @see MediaStore#createTrashRequest
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String IS_TRASHED = "is_trashed";
-
- /**
- * The time the media item should be considered expired. Typically only
- * meaningful in the context of {@link #IS_PENDING} or
- * {@link #IS_TRASHED}.
- */
- @CurrentTimeSecondsLong
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String DATE_EXPIRES = "date_expires";
-
- /**
- * Indexed value of
- * {@link MediaMetadataRetriever#METADATA_KEY_VIDEO_WIDTH},
- * {@link MediaMetadataRetriever#METADATA_KEY_IMAGE_WIDTH} or
- * {@link ExifInterface#TAG_IMAGE_WIDTH} extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String WIDTH = "width";
-
- /**
- * Indexed value of
- * {@link MediaMetadataRetriever#METADATA_KEY_VIDEO_HEIGHT},
- * {@link MediaMetadataRetriever#METADATA_KEY_IMAGE_HEIGHT} or
- * {@link ExifInterface#TAG_IMAGE_LENGTH} extracted from this media
- * item.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String HEIGHT = "height";
-
- /**
- * Calculated value that combines {@link #WIDTH} and {@link #HEIGHT}
- * into a user-presentable string.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String RESOLUTION = "resolution";
-
- /**
- * Package name that contributed this media. The value may be
- * {@code NULL} if ownership cannot be reliably determined.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String OWNER_PACKAGE_NAME = "owner_package_name";
-
- /**
- * Volume name of the specific storage device where this media item is
- * persisted. The value is typically one of the volume names returned
- * from {@link MediaStore#getExternalVolumeNames(Context)}.
- * <p>
- * This is a read-only column that is automatically computed.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String VOLUME_NAME = "volume_name";
-
- /**
- * Relative path of this media item within the storage device where it
- * is persisted. For example, an item stored at
- * {@code /storage/0000-0000/DCIM/Vacation/IMG1024.JPG} would have a
- * path of {@code DCIM/Vacation/}.
- * <p>
- * This value should only be used for organizational purposes, and you
- * should not attempt to construct or access a raw filesystem path using
- * this value. If you need to open a media item, use an API like
- * {@link ContentResolver#openFileDescriptor(Uri, String)}.
- * <p>
- * When this value is set to {@code NULL} during an
- * {@link ContentResolver#insert} operation, the newly created item will
- * be placed in a relevant default location based on the type of media
- * being inserted. For example, a {@code image/jpeg} item will be placed
- * under {@link Environment#DIRECTORY_PICTURES}.
- * <p>
- * You can modify this column during an {@link ContentResolver#update}
- * call, which will move the underlying file on disk.
- * <p>
- * In both cases above, content must be placed under a top-level
- * directory that is relevant to the media type. For example, attempting
- * to place a {@code audio/mpeg} file under
- * {@link Environment#DIRECTORY_PICTURES} will be rejected.
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String RELATIVE_PATH = "relative_path";
-
- /**
- * The primary bucket ID of this media item. This can be useful to
- * present the user a first-level clustering of related media items.
- * This is a read-only column that is automatically computed.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String BUCKET_ID = "bucket_id";
-
- /**
- * The primary bucket display name of this media item. This can be
- * useful to present the user a first-level clustering of related
- * media items. This is a read-only column that is automatically
- * computed.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
-
- /**
- * The group ID of this media item. This can be useful to present
- * the user a grouping of related media items, such a burst of
- * images, or a {@code JPG} and {@code DNG} version of the same
- * image.
- * <p>
- * This is a read-only column that is automatically computed based
- * on the first portion of the filename. For example,
- * {@code IMG1024.BURST001.JPG} and {@code IMG1024.BURST002.JPG}
- * will have the same {@link #GROUP_ID} because the first portion of
- * their filenames is identical.
- *
- * @removed
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- @Deprecated
- public static final String GROUP_ID = "group_id";
-
- /**
- * The "document ID" GUID as defined by the <em>XMP Media
- * Management</em> standard, extracted from any XMP metadata contained
- * within this media item. The value is {@code null} when no metadata
- * was found.
- * <p>
- * Each "document ID" is created once for each new resource. Different
- * renditions of that resource are expected to have different IDs.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String DOCUMENT_ID = "document_id";
-
- /**
- * The "instance ID" GUID as defined by the <em>XMP Media
- * Management</em> standard, extracted from any XMP metadata contained
- * within this media item. The value is {@code null} when no metadata
- * was found.
- * <p>
- * This "instance ID" changes with each save operation of a specific
- * "document ID".
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String INSTANCE_ID = "instance_id";
-
- /**
- * The "original document ID" GUID as defined by the <em>XMP Media
- * Management</em> standard, extracted from any XMP metadata contained
- * within this media item.
- * <p>
- * This "original document ID" links a resource to its original source.
- * For example, when you save a PSD document as a JPEG, then convert the
- * JPEG to GIF format, the "original document ID" of both the JPEG and
- * GIF files is the "document ID" of the original PSD file.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ORIGINAL_DOCUMENT_ID = "original_document_id";
-
- /**
- * Indexed value of
- * {@link MediaMetadataRetriever#METADATA_KEY_VIDEO_ROTATION},
- * {@link MediaMetadataRetriever#METADATA_KEY_IMAGE_ROTATION}, or
- * {@link ExifInterface#TAG_ORIENTATION} extracted from this media item.
- * <p>
- * For consistency the indexed value is expressed in degrees, such as 0,
- * 90, 180, or 270.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String ORIENTATION = "orientation";
-
- /**
- * Flag indicating if the media item has been marked as being a
- * "favorite" by the user.
- *
- * @see MediaColumns#IS_FAVORITE
- * @see MediaStore#QUERY_ARG_MATCH_FAVORITE
- * @see MediaStore#createFavoriteRequest
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String IS_FAVORITE = "is_favorite";
-
- // =======================================
- // ==== MediaMetadataRetriever values ====
- // =======================================
-
- /**
- * Indexed value of
- * {@link MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER} extracted
- * from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String CD_TRACK_NUMBER = "cd_track_number";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_ALBUM}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ALBUM = "album";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_ARTIST}
- * or {@link ExifInterface#TAG_ARTIST} extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ARTIST = "artist";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_AUTHOR}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String AUTHOR = "author";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_COMPOSER}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String COMPOSER = "composer";
-
- // METADATA_KEY_DATE is DATE_TAKEN
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_GENRE}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String GENRE = "genre";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_TITLE}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String TITLE = "title";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_YEAR}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String YEAR = "year";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_DURATION}
- * extracted from this media item.
- */
- @DurationMillisLong
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String DURATION = "duration";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_NUM_TRACKS}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String NUM_TRACKS = "num_tracks";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_WRITER}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String WRITER = "writer";
-
- // METADATA_KEY_MIMETYPE is MIME_TYPE
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ALBUM_ARTIST = "album_artist";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String DISC_NUMBER = "disc_number";
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_COMPILATION}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String COMPILATION = "compilation";
-
- // HAS_AUDIO is ignored
- // HAS_VIDEO is ignored
- // VIDEO_WIDTH is WIDTH
- // VIDEO_HEIGHT is HEIGHT
-
- /**
- * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_BITRATE}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String BITRATE = "bitrate";
-
- // TIMED_TEXT_LANGUAGES is ignored
- // IS_DRM is ignored
- // LOCATION is LATITUDE and LONGITUDE
- // VIDEO_ROTATION is ORIENTATION
-
- /**
- * Indexed value of
- * {@link MediaMetadataRetriever#METADATA_KEY_CAPTURE_FRAMERATE}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_FLOAT, readOnly = true)
- public static final String CAPTURE_FRAMERATE = "capture_framerate";
-
- // HAS_IMAGE is ignored
- // IMAGE_COUNT is ignored
- // IMAGE_PRIMARY is ignored
- // IMAGE_WIDTH is WIDTH
- // IMAGE_HEIGHT is HEIGHT
- // IMAGE_ROTATION is ORIENTATION
- // VIDEO_FRAME_COUNT is ignored
- // EXIF_OFFSET is ignored
- // EXIF_LENGTH is ignored
- // COLOR_STANDARD is ignored
- // COLOR_TRANSFER is ignored
- // COLOR_RANGE is ignored
- // SAMPLERATE is ignored
- // BITS_PER_SAMPLE is ignored
- }
-
- /**
- * Media provider table containing an index of all files in the media storage,
- * including non-media files. This should be used by applications that work with
- * non-media file types (text, HTML, PDF, etc) as well as applications that need to
- * work with multiple media file types in a single query.
- */
- public static final class Files {
- /** @hide */
- public static final String TABLE = "files";
-
- /** @hide */
- public static final Uri EXTERNAL_CONTENT_URI = getContentUri(VOLUME_EXTERNAL);
-
- /**
- * Get the content:// style URI for the files table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @return the URI to the files table on the given volume
- */
- public static Uri getContentUri(String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("file").build();
- }
-
- /**
- * Get the content:// style URI for a single row in the files table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @param rowId the file to get the URI for
- * @return the URI to the files table on the given volume
- */
- public static final Uri getContentUri(String volumeName,
- long rowId) {
- return ContentUris.withAppendedId(getContentUri(volumeName), rowId);
- }
-
- /** {@hide} */
- @UnsupportedAppUsage
- public static Uri getMtpObjectsUri(@NonNull String volumeName) {
- return MediaStore.Files.getContentUri(volumeName);
- }
-
- /** {@hide} */
- @UnsupportedAppUsage
- public static final Uri getMtpObjectsUri(@NonNull String volumeName, long fileId) {
- return MediaStore.Files.getContentUri(volumeName, fileId);
- }
-
- /** {@hide} */
- @UnsupportedAppUsage
- public static final Uri getMtpReferencesUri(@NonNull String volumeName, long fileId) {
- return MediaStore.Files.getContentUri(volumeName, fileId);
- }
-
- /**
- * Used to trigger special logic for directories.
- * @hide
- */
- public static final Uri getDirectoryUri(String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("dir").build();
- }
-
- /** @hide */
- public static final Uri getContentUriForPath(String path) {
- return getContentUri(getVolumeName(new File(path)));
- }
-
- /**
- * File metadata columns.
- */
- public interface FileColumns extends MediaColumns {
- /**
- * The MTP storage ID of the file
- * @hide
- */
- @UnsupportedAppUsage
- @Deprecated
- // @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String STORAGE_ID = "storage_id";
-
- /**
- * The MTP format code of the file
- * @hide
- */
- @UnsupportedAppUsage
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String FORMAT = "format";
-
- /**
- * The index of the parent directory of the file
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String PARENT = "parent";
-
- /**
- * The MIME type of the media item.
- * <p>
- * This is typically defined based on the file extension of the media
- * item. However, it may be the value of the {@code format} attribute
- * defined by the <em>Dublin Core Media Initiative</em> standard,
- * extracted from any XMP metadata contained within this media item.
- * <p class="note">
- * Note: the {@code format} attribute may be ignored if the top-level
- * MIME type disagrees with the file extension. For example, it's
- * reasonable for an {@code image/jpeg} file to declare a {@code format}
- * of {@code image/vnd.google.panorama360+jpg}, but declaring a
- * {@code format} of {@code audio/ogg} would be ignored.
- * <p>
- * This is a read-only column that is automatically computed.
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String MIME_TYPE = "mime_type";
-
- /** @removed promoted to parent interface */
- public static final String TITLE = "title";
-
- /**
- * The media type (audio, video, image or playlist)
- * of the file, or 0 for not a media file
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String MEDIA_TYPE = "media_type";
-
- /**
- * Constant for the {@link #MEDIA_TYPE} column indicating that file
- * is not an audio, image, video, playlist, or subtitles file.
- */
- public static final int MEDIA_TYPE_NONE = 0;
-
- /**
- * Constant for the {@link #MEDIA_TYPE} column indicating that file
- * is an image file.
- */
- public static final int MEDIA_TYPE_IMAGE = 1;
-
- /**
- * Constant for the {@link #MEDIA_TYPE} column indicating that file
- * is an audio file.
- */
- public static final int MEDIA_TYPE_AUDIO = 2;
-
- /**
- * Constant for the {@link #MEDIA_TYPE} column indicating that file
- * is a video file.
- */
- public static final int MEDIA_TYPE_VIDEO = 3;
-
- /**
- * Constant for the {@link #MEDIA_TYPE} column indicating that file
- * is a playlist file.
- */
- public static final int MEDIA_TYPE_PLAYLIST = 4;
-
- /**
- * Constant for the {@link #MEDIA_TYPE} column indicating that file
- * is a subtitles or lyrics file.
- */
- public static final int MEDIA_TYPE_SUBTITLE = 5;
-
- /**
- * Column indicating if the file is part of Downloads collection.
- * @hide
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String IS_DOWNLOAD = "is_download";
- }
- }
-
- /** @hide */
- public static class ThumbnailConstants {
- public static final int MINI_KIND = 1;
- public static final int FULL_SCREEN_KIND = 2;
- public static final int MICRO_KIND = 3;
-
- public static final Size MINI_SIZE = new Size(512, 384);
- public static final Size FULL_SCREEN_SIZE = new Size(1024, 786);
- public static final Size MICRO_SIZE = new Size(96, 96);
-
- public static @NonNull Size getKindSize(int kind) {
- if (kind == ThumbnailConstants.MICRO_KIND) {
- return ThumbnailConstants.MICRO_SIZE;
- } else if (kind == ThumbnailConstants.FULL_SCREEN_KIND) {
- return ThumbnailConstants.FULL_SCREEN_SIZE;
- } else if (kind == ThumbnailConstants.MINI_KIND) {
- return ThumbnailConstants.MINI_SIZE;
- } else {
- throw new IllegalArgumentException("Unsupported kind: " + kind);
- }
- }
- }
-
- /**
- * Download metadata columns.
- */
- public interface DownloadColumns extends MediaColumns {
- /**
- * Uri indicating where the item has been downloaded from.
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- String DOWNLOAD_URI = "download_uri";
-
- /**
- * Uri indicating HTTP referer of {@link #DOWNLOAD_URI}.
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- String REFERER_URI = "referer_uri";
-
- /**
- * The description of the download.
- *
- * @removed
- */
- @Deprecated
- @Column(Cursor.FIELD_TYPE_STRING)
- String DESCRIPTION = "description";
- }
-
- /**
- * Collection of downloaded items.
- */
- public static final class Downloads implements DownloadColumns {
- private Downloads() {}
-
- /**
- * The content:// style URI for the internal storage.
- */
- @NonNull
- public static final Uri INTERNAL_CONTENT_URI =
- getContentUri("internal");
-
- /**
- * The content:// style URI for the "primary" external storage
- * volume.
- */
- @NonNull
- public static final Uri EXTERNAL_CONTENT_URI =
- getContentUri("external");
-
- /**
- * The MIME type for this table.
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/download";
-
- /**
- * Regex that matches paths that needs to be considered part of downloads collection.
- * @hide
- */
- public static final Pattern PATTERN_DOWNLOADS_FILE = Pattern.compile(
- "(?i)^/storage/[^/]+/(?:[0-9]+/)?(?:Android/sandbox/[^/]+/)?Download/.+");
- private static final Pattern PATTERN_DOWNLOADS_DIRECTORY = Pattern.compile(
- "(?i)^/storage/[^/]+/(?:[0-9]+/)?(?:Android/sandbox/[^/]+/)?Download/?");
-
- /**
- * Get the content:// style URI for the downloads table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @return the URI to the image media table on the given volume
- */
- public static @NonNull Uri getContentUri(@NonNull String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName)
- .appendPath("downloads").build();
- }
-
- /**
- * Get the content:// style URI for a single row in the downloads table
- * on the given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @param id the download to get the URI for
- * @return the URI to the downloads table on the given volume
- */
- public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
- return ContentUris.withAppendedId(getContentUri(volumeName), id);
- }
-
- /** @hide */
- public static @NonNull Uri getContentUriForPath(@NonNull String path) {
- return getContentUri(getVolumeName(new File(path)));
- }
-
- /** @hide */
- public static boolean isDownload(@NonNull String path) {
- return PATTERN_DOWNLOADS_FILE.matcher(path).matches();
- }
-
- /** @hide */
- public static boolean isDownloadDir(@NonNull String path) {
- return PATTERN_DOWNLOADS_DIRECTORY.matcher(path).matches();
- }
- }
-
- /**
- * @deprecated since this method doesn't have a {@link Context}, we can't
- * find the actual {@link StorageVolume} for the given path, so
- * only a vague guess is returned. Callers should use
- * {@link StorageManager#getStorageVolume(File)} instead.
- * @hide
- */
- @Deprecated
- public static @NonNull String getVolumeName(@NonNull File path) {
- // Ideally we'd find the relevant StorageVolume, but we don't have a
- // Context to obtain it from, so the best we can do is assume
- if (path.getAbsolutePath()
- .startsWith(Environment.getStorageDirectory().getAbsolutePath())) {
- return MediaStore.VOLUME_EXTERNAL;
- } else {
- return MediaStore.VOLUME_INTERNAL;
- }
- }
-
- /**
- * This class is used internally by Images.Thumbnails and Video.Thumbnails, it's not intended
- * to be accessed elsewhere.
- */
- @Deprecated
- private static class InternalThumbnails implements BaseColumns {
- /**
- * Currently outstanding thumbnail requests that can be cancelled.
- */
- // @GuardedBy("sPending")
- private static ArrayMap<Uri, CancellationSignal> sPending = new ArrayMap<>();
-
- /**
- * Make a blocking request to obtain the given thumbnail, generating it
- * if needed.
- *
- * @see #cancelThumbnail(ContentResolver, Uri)
- */
- @Deprecated
- static @Nullable Bitmap getThumbnail(@NonNull ContentResolver cr, @NonNull Uri uri,
- int kind, @Nullable BitmapFactory.Options opts) {
- final Size size = ThumbnailConstants.getKindSize(kind);
-
- CancellationSignal signal = null;
- synchronized (sPending) {
- signal = sPending.get(uri);
- if (signal == null) {
- signal = new CancellationSignal();
- sPending.put(uri, signal);
- }
- }
-
- try {
- return cr.loadThumbnail(uri, size, signal);
- } catch (IOException e) {
- Log.w(TAG, "Failed to obtain thumbnail for " + uri, e);
- return null;
- } finally {
- synchronized (sPending) {
- sPending.remove(uri);
- }
- }
- }
-
- /**
- * This method cancels the thumbnail request so clients waiting for
- * {@link #getThumbnail} will be interrupted and return immediately.
- * Only the original process which made the request can cancel their own
- * requests.
- */
- @Deprecated
- static void cancelThumbnail(@NonNull ContentResolver cr, @NonNull Uri uri) {
- synchronized (sPending) {
- final CancellationSignal signal = sPending.get(uri);
- if (signal != null) {
- signal.cancel();
- }
- }
- }
- }
-
- /**
- * Collection of all media with MIME type of {@code image/*}.
- */
- public static final class Images {
- /**
- * Image metadata columns.
- */
- public interface ImageColumns extends MediaColumns {
- /**
- * The picasa id of the image
- *
- * @deprecated this value was only relevant for images hosted on
- * Picasa, which are no longer supported.
- */
- @Deprecated
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String PICASA_ID = "picasa_id";
-
- /**
- * Whether the video should be published as public or private
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String IS_PRIVATE = "isprivate";
-
- /**
- * The latitude where the image was captured.
- *
- * @deprecated location details are no longer indexed for privacy
- * reasons, and this value is now always {@code null}.
- * You can still manually obtain location metadata using
- * {@link ExifInterface#getLatLong(float[])}.
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_FLOAT, readOnly = true)
- public static final String LATITUDE = "latitude";
-
- /**
- * The longitude where the image was captured.
- *
- * @deprecated location details are no longer indexed for privacy
- * reasons, and this value is now always {@code null}.
- * You can still manually obtain location metadata using
- * {@link ExifInterface#getLatLong(float[])}.
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_FLOAT, readOnly = true)
- public static final String LONGITUDE = "longitude";
-
- /** @removed promoted to parent interface */
- public static final String DATE_TAKEN = "datetaken";
- /** @removed promoted to parent interface */
- public static final String ORIENTATION = "orientation";
-
- /**
- * The mini thumb id.
- *
- * @deprecated all thumbnails should be obtained via
- * {@link MediaStore.Images.Thumbnails#getThumbnail}, as this
- * value is no longer supported.
- */
- @Deprecated
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
-
- /** @removed promoted to parent interface */
- public static final String BUCKET_ID = "bucket_id";
- /** @removed promoted to parent interface */
- public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
- /** @removed promoted to parent interface */
- public static final String GROUP_ID = "group_id";
-
- /**
- * Indexed value of {@link ExifInterface#TAG_IMAGE_DESCRIPTION}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String DESCRIPTION = "description";
-
- /**
- * Indexed value of {@link ExifInterface#TAG_EXPOSURE_TIME}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String EXPOSURE_TIME = "exposure_time";
-
- /**
- * Indexed value of {@link ExifInterface#TAG_F_NUMBER}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String F_NUMBER = "f_number";
-
- /**
- * Indexed value of {@link ExifInterface#TAG_ISO_SPEED_RATINGS}
- * extracted from this media item.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String ISO = "iso";
- }
-
- public static final class Media implements ImageColumns {
- /**
- * @deprecated all queries should be performed through
- * {@link ContentResolver} directly, which offers modern
- * features like {@link CancellationSignal}.
- */
- @Deprecated
- public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) {
- return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER);
- }
-
- /**
- * @deprecated all queries should be performed through
- * {@link ContentResolver} directly, which offers modern
- * features like {@link CancellationSignal}.
- */
- @Deprecated
- public static final Cursor query(ContentResolver cr, Uri uri, String[] projection,
- String where, String orderBy) {
- return cr.query(uri, projection, where,
- null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
- }
-
- /**
- * @deprecated all queries should be performed through
- * {@link ContentResolver} directly, which offers modern
- * features like {@link CancellationSignal}.
- */
- @Deprecated
- public static final Cursor query(ContentResolver cr, Uri uri, String[] projection,
- String selection, String [] selectionArgs, String orderBy) {
- return cr.query(uri, projection, selection,
- selectionArgs, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
- }
-
- /**
- * Retrieves an image for the given url as a {@link Bitmap}.
- *
- * @param cr The content resolver to use
- * @param url The url of the image
- * @deprecated loading of images should be performed through
- * {@link ImageDecoder#createSource(ContentResolver, Uri)},
- * which offers modern features like
- * {@link PostProcessor}.
- */
- @Deprecated
- public static final Bitmap getBitmap(ContentResolver cr, Uri url)
- throws FileNotFoundException, IOException {
- InputStream input = cr.openInputStream(url);
- Bitmap bitmap = BitmapFactory.decodeStream(input);
- input.close();
- return bitmap;
- }
-
- /**
- * Insert an image and create a thumbnail for it.
- *
- * @param cr The content resolver to use
- * @param imagePath The path to the image to insert
- * @param name The name of the image
- * @param description The description of the image
- * @return The URL to the newly created image
- * @deprecated inserting of images should be performed using
- * {@link MediaColumns#IS_PENDING}, which offers richer
- * control over lifecycle.
- */
- @Deprecated
- public static final String insertImage(ContentResolver cr, String imagePath,
- String name, String description) throws FileNotFoundException {
- final Bitmap source;
- try {
- source = ImageDecoder
- .decodeBitmap(ImageDecoder.createSource(new File(imagePath)));
- } catch (IOException e) {
- throw new FileNotFoundException(e.getMessage());
- }
- return insertImage(cr, source, name, description);
- }
-
- /**
- * Insert an image and create a thumbnail for it.
- *
- * @param cr The content resolver to use
- * @param source The stream to use for the image
- * @param title The name of the image
- * @param description The description of the image
- * @return The URL to the newly created image, or <code>null</code> if the image failed to be stored
- * for any reason.
- * @deprecated inserting of images should be performed using
- * {@link MediaColumns#IS_PENDING}, which offers richer
- * control over lifecycle.
- */
- @Deprecated
- public static final String insertImage(ContentResolver cr, Bitmap source, String title,
- String description) {
- if (TextUtils.isEmpty(title)) title = "Image";
-
- final long now = System.currentTimeMillis();
- final ContentValues values = new ContentValues();
- values.put(MediaColumns.DISPLAY_NAME, title);
- values.put(MediaColumns.MIME_TYPE, "image/jpeg");
- values.put(MediaColumns.DATE_ADDED, now / 1000);
- values.put(MediaColumns.DATE_MODIFIED, now / 1000);
- values.put(MediaColumns.DATE_EXPIRES, (now + DateUtils.DAY_IN_MILLIS) / 1000);
- values.put(MediaColumns.IS_PENDING, 1);
-
- final Uri uri = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
- try {
- try (OutputStream out = cr.openOutputStream(uri)) {
- source.compress(Bitmap.CompressFormat.JPEG, 90, out);
- }
-
- // Everything went well above, publish it!
- values.clear();
- values.put(MediaColumns.IS_PENDING, 0);
- values.putNull(MediaColumns.DATE_EXPIRES);
- cr.update(uri, values, null, null);
- return uri.toString();
- } catch (Exception e) {
- Log.w(TAG, "Failed to insert image", e);
- cr.delete(uri, null, null);
- return null;
- }
- }
-
- /**
- * Get the content:// style URI for the image media table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @return the URI to the image media table on the given volume
- */
- public static Uri getContentUri(String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("images")
- .appendPath("media").build();
- }
-
- /**
- * Get the content:// style URI for a single row in the images table
- * on the given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @param id the image to get the URI for
- * @return the URI to the images table on the given volume
- */
- public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
- return ContentUris.withAppendedId(getContentUri(volumeName), id);
- }
-
- /**
- * The content:// style URI for the internal storage.
- */
- public static final Uri INTERNAL_CONTENT_URI =
- getContentUri("internal");
-
- /**
- * The content:// style URI for the "primary" external storage
- * volume.
- */
- public static final Uri EXTERNAL_CONTENT_URI =
- getContentUri("external");
-
- /**
- * The MIME type of of this directory of
- * images. Note that each entry in this directory will have a standard
- * image MIME type as appropriate -- for example, image/jpeg.
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/image";
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = ImageColumns.BUCKET_DISPLAY_NAME;
- }
-
- /**
- * This class provides utility methods to obtain thumbnails for various
- * {@link Images} items.
- *
- * @deprecated Callers should migrate to using
- * {@link ContentResolver#loadThumbnail}, since it offers
- * richer control over requested thumbnail sizes and
- * cancellation behavior.
- */
- @Deprecated
- public static class Thumbnails implements BaseColumns {
- /**
- * @deprecated all queries should be performed through
- * {@link ContentResolver} directly, which offers modern
- * features like {@link CancellationSignal}.
- */
- @Deprecated
- public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) {
- return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER);
- }
-
- /**
- * @deprecated all queries should be performed through
- * {@link ContentResolver} directly, which offers modern
- * features like {@link CancellationSignal}.
- */
- @Deprecated
- public static final Cursor queryMiniThumbnails(ContentResolver cr, Uri uri, int kind,
- String[] projection) {
- return cr.query(uri, projection, "kind = " + kind, null, DEFAULT_SORT_ORDER);
- }
-
- /**
- * @deprecated all queries should be performed through
- * {@link ContentResolver} directly, which offers modern
- * features like {@link CancellationSignal}.
- */
- @Deprecated
- public static final Cursor queryMiniThumbnail(ContentResolver cr, long origId, int kind,
- String[] projection) {
- return cr.query(EXTERNAL_CONTENT_URI, projection,
- IMAGE_ID + " = " + origId + " AND " + KIND + " = " +
- kind, null, null);
- }
-
- /**
- * Cancel any outstanding {@link #getThumbnail} requests, causing
- * them to return by throwing a {@link OperationCanceledException}.
- * <p>
- * This method has no effect on
- * {@link ContentResolver#loadThumbnail} calls, since they provide
- * their own {@link CancellationSignal}.
- *
- * @deprecated Callers should migrate to using
- * {@link ContentResolver#loadThumbnail}, since it
- * offers richer control over requested thumbnail sizes
- * and cancellation behavior.
- */
- @Deprecated
- public static void cancelThumbnailRequest(ContentResolver cr, long origId) {
- final Uri uri = ContentUris.withAppendedId(
- Images.Media.EXTERNAL_CONTENT_URI, origId);
- InternalThumbnails.cancelThumbnail(cr, uri);
- }
-
- /**
- * Return thumbnail representing a specific image item. If a
- * thumbnail doesn't exist, this method will block until it's
- * generated. Callers are responsible for their own in-memory
- * caching of returned values.
- *
- * As of {@link android.os.Build.VERSION_CODES#Q}, this output
- * of the thumbnail has correct rotation, don't need to rotate
- * it again.
- *
- * @param imageId the image item to obtain a thumbnail for.
- * @param kind optimal thumbnail size desired.
- * @return decoded thumbnail, or {@code null} if problem was
- * encountered.
- * @deprecated Callers should migrate to using
- * {@link ContentResolver#loadThumbnail}, since it
- * offers richer control over requested thumbnail sizes
- * and cancellation behavior.
- */
- @Deprecated
- public static Bitmap getThumbnail(ContentResolver cr, long imageId, int kind,
- BitmapFactory.Options options) {
- final Uri uri = ContentUris.withAppendedId(
- Images.Media.EXTERNAL_CONTENT_URI, imageId);
- return InternalThumbnails.getThumbnail(cr, uri, kind, options);
- }
-
- /**
- * Cancel any outstanding {@link #getThumbnail} requests, causing
- * them to return by throwing a {@link OperationCanceledException}.
- * <p>
- * This method has no effect on
- * {@link ContentResolver#loadThumbnail} calls, since they provide
- * their own {@link CancellationSignal}.
- *
- * @deprecated Callers should migrate to using
- * {@link ContentResolver#loadThumbnail}, since it
- * offers richer control over requested thumbnail sizes
- * and cancellation behavior.
- */
- @Deprecated
- public static void cancelThumbnailRequest(ContentResolver cr, long origId,
- long groupId) {
- cancelThumbnailRequest(cr, origId);
- }
-
- /**
- * Return thumbnail representing a specific image item. If a
- * thumbnail doesn't exist, this method will block until it's
- * generated. Callers are responsible for their own in-memory
- * caching of returned values.
- *
- * As of {@link android.os.Build.VERSION_CODES#Q}, this output
- * of the thumbnail has correct rotation, don't need to rotate
- * it again.
- *
- * @param imageId the image item to obtain a thumbnail for.
- * @param kind optimal thumbnail size desired.
- * @return decoded thumbnail, or {@code null} if problem was
- * encountered.
- * @deprecated Callers should migrate to using
- * {@link ContentResolver#loadThumbnail}, since it
- * offers richer control over requested thumbnail sizes
- * and cancellation behavior.
- */
- @Deprecated
- public static Bitmap getThumbnail(ContentResolver cr, long imageId, long groupId,
- int kind, BitmapFactory.Options options) {
- return getThumbnail(cr, imageId, kind, options);
- }
-
- /**
- * Get the content:// style URI for the image media table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @return the URI to the image media table on the given volume
- */
- public static Uri getContentUri(String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("images")
- .appendPath("thumbnails").build();
- }
-
- /**
- * The content:// style URI for the internal storage.
- */
- public static final Uri INTERNAL_CONTENT_URI =
- getContentUri("internal");
-
- /**
- * The content:// style URI for the "primary" external storage
- * volume.
- */
- public static final Uri EXTERNAL_CONTENT_URI =
- getContentUri("external");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "image_id ASC";
-
- /**
- * Path to the thumbnail file on disk.
- * <p>
- * Note that apps may not have filesystem permissions to directly
- * access this path. Instead of trying to open this path directly,
- * apps should use
- * {@link ContentResolver#openFileDescriptor(Uri, String)} to gain
- * access.
- *
- * As of {@link android.os.Build.VERSION_CODES#Q}, this thumbnail
- * has correct rotation, don't need to rotate it again.
- *
- * @deprecated Apps may not have filesystem permissions to directly
- * access this path. Instead of trying to open this path
- * directly, apps should use
- * {@link ContentResolver#loadThumbnail}
- * to gain access.
- */
- @Deprecated
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String DATA = "_data";
-
- /**
- * The original image for the thumbnal
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String IMAGE_ID = "image_id";
-
- /**
- * The kind of the thumbnail
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String KIND = "kind";
-
- public static final int MINI_KIND = ThumbnailConstants.MINI_KIND;
- public static final int FULL_SCREEN_KIND = ThumbnailConstants.FULL_SCREEN_KIND;
- public static final int MICRO_KIND = ThumbnailConstants.MICRO_KIND;
-
- /**
- * Return the typical {@link Size} (in pixels) used internally when
- * the given thumbnail kind is requested.
- */
- public static @NonNull Size getKindSize(int kind) {
- return ThumbnailConstants.getKindSize(kind);
- }
-
- /**
- * The blob raw data of thumbnail
- *
- * @deprecated this column never existed internally, and could never
- * have returned valid data.
- */
- @Deprecated
- @Column(Cursor.FIELD_TYPE_BLOB)
- public static final String THUMB_DATA = "thumb_data";
-
- /**
- * The width of the thumbnal
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String WIDTH = "width";
-
- /**
- * The height of the thumbnail
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String HEIGHT = "height";
- }
- }
-
- /**
- * Collection of all media with MIME type of {@code audio/*}.
- */
- public static final class Audio {
- /**
- * Audio metadata columns.
- */
- public interface AudioColumns extends MediaColumns {
-
- /**
- * A non human readable key calculated from the TITLE, used for
- * searching, sorting and grouping
- *
- * @see Audio#keyFor(String)
- * @deprecated These keys are generated using
- * {@link java.util.Locale#ROOT}, which means they don't
- * reflect locale-specific sorting preferences. To apply
- * locale-specific sorting preferences, use
- * {@link ContentResolver#QUERY_ARG_SQL_SORT_ORDER} with
- * {@code COLLATE LOCALIZED}, or
- * {@link ContentResolver#QUERY_ARG_SORT_LOCALE}.
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String TITLE_KEY = "title_key";
-
- /** @removed promoted to parent interface */
- public static final String DURATION = "duration";
-
- /**
- * The position within the audio item at which playback should be
- * resumed.
- */
- @DurationMillisLong
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String BOOKMARK = "bookmark";
-
- /**
- * The id of the artist who created the audio file, if any
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String ARTIST_ID = "artist_id";
-
- /** @removed promoted to parent interface */
- public static final String ARTIST = "artist";
-
- /**
- * The artist credited for the album that contains the audio file
- * @hide
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ALBUM_ARTIST = "album_artist";
-
- /**
- * A non human readable key calculated from the ARTIST, used for
- * searching, sorting and grouping
- *
- * @see Audio#keyFor(String)
- * @deprecated These keys are generated using
- * {@link java.util.Locale#ROOT}, which means they don't
- * reflect locale-specific sorting preferences. To apply
- * locale-specific sorting preferences, use
- * {@link ContentResolver#QUERY_ARG_SQL_SORT_ORDER} with
- * {@code COLLATE LOCALIZED}, or
- * {@link ContentResolver#QUERY_ARG_SORT_LOCALE}.
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ARTIST_KEY = "artist_key";
-
- /** @removed promoted to parent interface */
- public static final String COMPOSER = "composer";
-
- /**
- * The id of the album the audio file is from, if any
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String ALBUM_ID = "album_id";
-
- /** @removed promoted to parent interface */
- public static final String ALBUM = "album";
-
- /**
- * A non human readable key calculated from the ALBUM, used for
- * searching, sorting and grouping
- *
- * @see Audio#keyFor(String)
- * @deprecated These keys are generated using
- * {@link java.util.Locale#ROOT}, which means they don't
- * reflect locale-specific sorting preferences. To apply
- * locale-specific sorting preferences, use
- * {@link ContentResolver#QUERY_ARG_SQL_SORT_ORDER} with
- * {@code COLLATE LOCALIZED}, or
- * {@link ContentResolver#QUERY_ARG_SORT_LOCALE}.
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ALBUM_KEY = "album_key";
-
- /**
- * The track number of this song on the album, if any.
- * This number encodes both the track number and the
- * disc number. For multi-disc sets, this number will
- * be 1xxx for tracks on the first disc, 2xxx for tracks
- * on the second disc, etc.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String TRACK = "track";
-
- /**
- * The year the audio file was recorded, if any
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String YEAR = "year";
-
- /**
- * Non-zero if the audio file is music
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String IS_MUSIC = "is_music";
-
- /**
- * Non-zero if the audio file is a podcast
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String IS_PODCAST = "is_podcast";
-
- /**
- * Non-zero if the audio file may be a ringtone
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String IS_RINGTONE = "is_ringtone";
-
- /**
- * Non-zero if the audio file may be an alarm
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String IS_ALARM = "is_alarm";
-
- /**
- * Non-zero if the audio file may be a notification sound
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String IS_NOTIFICATION = "is_notification";
-
- /**
- * Non-zero if the audio file is an audiobook
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String IS_AUDIOBOOK = "is_audiobook";
-
- /**
- * The id of the genre the audio file is from, if any
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String GENRE_ID = "genre_id";
-
- /**
- * The genre of the audio file, if any.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String GENRE = "genre";
-
- /**
- * A non human readable key calculated from the GENRE, used for
- * searching, sorting and grouping
- *
- * @see Audio#keyFor(String)
- * @deprecated These keys are generated using
- * {@link java.util.Locale#ROOT}, which means they don't
- * reflect locale-specific sorting preferences. To apply
- * locale-specific sorting preferences, use
- * {@link ContentResolver#QUERY_ARG_SQL_SORT_ORDER} with
- * {@code COLLATE LOCALIZED}, or
- * {@link ContentResolver#QUERY_ARG_SORT_LOCALE}.
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String GENRE_KEY = "genre_key";
-
- /**
- * The resource URI of a localized title, if any.
- * <p>
- * Conforms to this pattern:
- * <ul>
- * <li>Scheme: {@link ContentResolver#SCHEME_ANDROID_RESOURCE}
- * <li>Authority: Package Name of ringtone title provider
- * <li>First Path Segment: Type of resource (must be "string")
- * <li>Second Path Segment: Resource ID of title
- * </ul>
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String TITLE_RESOURCE_URI = "title_resource_uri";
- }
-
- private static final Pattern PATTERN_TRIM_BEFORE = Pattern.compile(
- "(?i)(^(the|an|a) |,\\s*(the|an|a)$|[^\\w\\s]|^\\s+|\\s+$)");
- private static final Pattern PATTERN_TRIM_AFTER = Pattern.compile(
- "(^(00)+|(00)+$)");
-
- /**
- * Converts a user-visible string into a "key" that can be used for
- * grouping, sorting, and searching.
- *
- * @return Opaque token that should not be parsed or displayed to users.
- * @deprecated These keys are generated using
- * {@link java.util.Locale#ROOT}, which means they don't
- * reflect locale-specific sorting preferences. To apply
- * locale-specific sorting preferences, use
- * {@link ContentResolver#QUERY_ARG_SQL_SORT_ORDER} with
- * {@code COLLATE LOCALIZED}, or
- * {@link ContentResolver#QUERY_ARG_SORT_LOCALE}.
- */
- @Deprecated
- public static @Nullable String keyFor(@Nullable String name) {
- if (TextUtils.isEmpty(name)) return null;
-
- if (UNKNOWN_STRING.equals(name)) {
- return "01";
- }
-
- final boolean sortFirst = name.startsWith("\001");
-
- name = PATTERN_TRIM_BEFORE.matcher(name).replaceAll("");
- if (TextUtils.isEmpty(name)) return null;
-
- final Collator c = Collator.getInstance(Locale.ROOT);
- c.setStrength(Collator.PRIMARY);
- name = HexEncoding.encodeToString(c.getCollationKey(name).toByteArray(), false);
-
- name = PATTERN_TRIM_AFTER.matcher(name).replaceAll("");
- if (sortFirst) {
- name = "01" + name;
- }
- return name;
- }
-
- public static final class Media implements AudioColumns {
- /**
- * Get the content:// style URI for the audio media table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @return the URI to the audio media table on the given volume
- */
- public static Uri getContentUri(String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("audio")
- .appendPath("media").build();
- }
-
- /**
- * Get the content:// style URI for a single row in the audio table
- * on the given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @param id the audio to get the URI for
- * @return the URI to the audio table on the given volume
- */
- public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
- return ContentUris.withAppendedId(getContentUri(volumeName), id);
- }
-
- /**
- * Get the content:// style URI for the given audio media file.
- *
- * @deprecated Apps may not have filesystem permissions to directly
- * access this path.
- */
- @Deprecated
- public static @Nullable Uri getContentUriForPath(@NonNull String path) {
- return getContentUri(getVolumeName(new File(path)));
- }
-
- /**
- * The content:// style URI for the internal storage.
- */
- public static final Uri INTERNAL_CONTENT_URI =
- getContentUri("internal");
-
- /**
- * The content:// style URI for the "primary" external storage
- * volume.
- */
- public static final Uri EXTERNAL_CONTENT_URI =
- getContentUri("external");
-
- /**
- * The MIME type for this table.
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/audio";
-
- /**
- * The MIME type for an audio track.
- */
- public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/audio";
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = TITLE_KEY;
-
- /**
- * Activity Action: Start SoundRecorder application.
- * <p>Input: nothing.
- * <p>Output: An uri to the recorded sound stored in the Media Library
- * if the recording was successful.
- * May also contain the extra EXTRA_MAX_BYTES.
- * @see #EXTRA_MAX_BYTES
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String RECORD_SOUND_ACTION =
- "android.provider.MediaStore.RECORD_SOUND";
-
- /**
- * The name of the Intent-extra used to define a maximum file size for
- * a recording made by the SoundRecorder application.
- *
- * @see #RECORD_SOUND_ACTION
- */
- public static final String EXTRA_MAX_BYTES =
- "android.provider.MediaStore.extra.MAX_BYTES";
- }
-
- /**
- * Audio genre metadata columns.
- */
- public interface GenresColumns {
- /**
- * The name of the genre
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String NAME = "name";
- }
-
- /**
- * Contains all genres for audio files
- */
- public static final class Genres implements BaseColumns, GenresColumns {
- /**
- * Get the content:// style URI for the audio genres table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @return the URI to the audio genres table on the given volume
- */
- public static Uri getContentUri(String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("audio")
- .appendPath("genres").build();
- }
-
- /**
- * Get the content:// style URI for querying the genres of an audio file.
- *
- * @param volumeName the name of the volume to get the URI for
- * @param audioId the ID of the audio file for which to retrieve the genres
- * @return the URI to for querying the genres for the audio file
- * with the given the volume and audioID
- */
- public static Uri getContentUriForAudioId(String volumeName, int audioId) {
- return ContentUris.withAppendedId(Audio.Media.getContentUri(volumeName), audioId)
- .buildUpon().appendPath("genres").build();
- }
-
- /**
- * The content:// style URI for the internal storage.
- */
- public static final Uri INTERNAL_CONTENT_URI =
- getContentUri("internal");
-
- /**
- * The content:// style URI for the "primary" external storage
- * volume.
- */
- public static final Uri EXTERNAL_CONTENT_URI =
- getContentUri("external");
-
- /**
- * The MIME type for this table.
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/genre";
-
- /**
- * The MIME type for entries in this table.
- */
- public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/genre";
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = NAME;
-
- /**
- * Sub-directory of each genre containing all members.
- */
- public static final class Members implements AudioColumns {
-
- public static final Uri getContentUri(String volumeName, long genreId) {
- return ContentUris
- .withAppendedId(Audio.Genres.getContentUri(volumeName), genreId)
- .buildUpon().appendPath("members").build();
- }
-
- /**
- * A subdirectory of each genre containing all member audio files.
- */
- public static final String CONTENT_DIRECTORY = "members";
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = TITLE_KEY;
-
- /**
- * The ID of the audio file
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String AUDIO_ID = "audio_id";
-
- /**
- * The ID of the genre
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String GENRE_ID = "genre_id";
- }
- }
-
- /**
- * Audio playlist metadata columns.
- */
- public interface PlaylistsColumns {
- /**
- * The name of the playlist
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String NAME = "name";
-
- /**
- * Path to the playlist file on disk.
- * <p>
- * Note that apps may not have filesystem permissions to directly
- * access this path. Instead of trying to open this path directly,
- * apps should use
- * {@link ContentResolver#openFileDescriptor(Uri, String)} to gain
- * access.
- *
- * @deprecated Apps may not have filesystem permissions to directly
- * access this path. Instead of trying to open this path
- * directly, apps should use
- * {@link ContentResolver#openFileDescriptor(Uri, String)}
- * to gain access.
- */
- @Deprecated
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String DATA = "_data";
-
- /**
- * The time the media item was first added.
- */
- @CurrentTimeSecondsLong
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String DATE_ADDED = "date_added";
-
- /**
- * The time the media item was last modified.
- */
- @CurrentTimeSecondsLong
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String DATE_MODIFIED = "date_modified";
- }
-
- /**
- * Contains playlists for audio files
- */
- public static final class Playlists implements BaseColumns,
- PlaylistsColumns {
- /**
- * Get the content:// style URI for the audio playlists table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @return the URI to the audio playlists table on the given volume
- */
- public static Uri getContentUri(String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("audio")
- .appendPath("playlists").build();
- }
-
- /**
- * The content:// style URI for the internal storage.
- */
- public static final Uri INTERNAL_CONTENT_URI =
- getContentUri("internal");
-
- /**
- * The content:// style URI for the "primary" external storage
- * volume.
- */
- public static final Uri EXTERNAL_CONTENT_URI =
- getContentUri("external");
-
- /**
- * The MIME type for this table.
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/playlist";
-
- /**
- * The MIME type for entries in this table.
- */
- public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/playlist";
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = NAME;
-
- /**
- * Sub-directory of each playlist containing all members.
- */
- public static final class Members implements AudioColumns {
- public static final Uri getContentUri(String volumeName, long playlistId) {
- return ContentUris
- .withAppendedId(Audio.Playlists.getContentUri(volumeName), playlistId)
- .buildUpon().appendPath("members").build();
- }
-
- /**
- * Convenience method to move a playlist item to a new location
- * @param res The content resolver to use
- * @param playlistId The numeric id of the playlist
- * @param from The position of the item to move
- * @param to The position to move the item to
- * @return true on success
- */
- public static final boolean moveItem(ContentResolver res,
- long playlistId, int from, int to) {
- Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external",
- playlistId)
- .buildUpon()
- .appendEncodedPath(String.valueOf(from))
- .appendQueryParameter("move", "true")
- .build();
- ContentValues values = new ContentValues();
- values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, to);
- return res.update(uri, values, null, null) != 0;
- }
-
- /**
- * The ID within the playlist.
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String _ID = "_id";
-
- /**
- * A subdirectory of each playlist containing all member audio
- * files.
- */
- public static final String CONTENT_DIRECTORY = "members";
-
- /**
- * The ID of the audio file
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String AUDIO_ID = "audio_id";
-
- /**
- * The ID of the playlist
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String PLAYLIST_ID = "playlist_id";
-
- /**
- * The order of the songs in the playlist
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String PLAY_ORDER = "play_order";
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = PLAY_ORDER;
- }
- }
-
- /**
- * Audio artist metadata columns.
- */
- public interface ArtistColumns {
- /**
- * The artist who created the audio file, if any
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ARTIST = "artist";
-
- /**
- * A non human readable key calculated from the ARTIST, used for
- * searching, sorting and grouping
- *
- * @see Audio#keyFor(String)
- * @deprecated These keys are generated using
- * {@link java.util.Locale#ROOT}, which means they don't
- * reflect locale-specific sorting preferences. To apply
- * locale-specific sorting preferences, use
- * {@link ContentResolver#QUERY_ARG_SQL_SORT_ORDER} with
- * {@code COLLATE LOCALIZED}, or
- * {@link ContentResolver#QUERY_ARG_SORT_LOCALE}.
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ARTIST_KEY = "artist_key";
-
- /**
- * The number of albums in the database for this artist
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String NUMBER_OF_ALBUMS = "number_of_albums";
-
- /**
- * The number of albums in the database for this artist
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String NUMBER_OF_TRACKS = "number_of_tracks";
- }
-
- /**
- * Contains artists for audio files
- */
- public static final class Artists implements BaseColumns, ArtistColumns {
- /**
- * Get the content:// style URI for the artists table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @return the URI to the audio artists table on the given volume
- */
- public static Uri getContentUri(String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("audio")
- .appendPath("artists").build();
- }
-
- /**
- * The content:// style URI for the internal storage.
- */
- public static final Uri INTERNAL_CONTENT_URI =
- getContentUri("internal");
-
- /**
- * The content:// style URI for the "primary" external storage
- * volume.
- */
- public static final Uri EXTERNAL_CONTENT_URI =
- getContentUri("external");
-
- /**
- * The MIME type for this table.
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/artists";
-
- /**
- * The MIME type for entries in this table.
- */
- public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/artist";
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = ARTIST_KEY;
-
- /**
- * Sub-directory of each artist containing all albums on which
- * a song by the artist appears.
- */
- public static final class Albums implements AlbumColumns {
- public static final Uri getContentUri(String volumeName,long artistId) {
- return ContentUris
- .withAppendedId(Audio.Artists.getContentUri(volumeName), artistId)
- .buildUpon().appendPath("albums").build();
- }
- }
- }
-
- /**
- * Audio album metadata columns.
- */
- public interface AlbumColumns {
-
- /**
- * The id for the album
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String ALBUM_ID = "album_id";
-
- /**
- * The album on which the audio file appears, if any
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ALBUM = "album";
-
- /**
- * The ID of the artist whose songs appear on this album.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String ARTIST_ID = "artist_id";
-
- /**
- * The name of the artist whose songs appear on this album.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ARTIST = "artist";
-
- /**
- * A non human readable key calculated from the ARTIST, used for
- * searching, sorting and grouping
- *
- * @see Audio#keyFor(String)
- * @deprecated These keys are generated using
- * {@link java.util.Locale#ROOT}, which means they don't
- * reflect locale-specific sorting preferences. To apply
- * locale-specific sorting preferences, use
- * {@link ContentResolver#QUERY_ARG_SQL_SORT_ORDER} with
- * {@code COLLATE LOCALIZED}, or
- * {@link ContentResolver#QUERY_ARG_SORT_LOCALE}.
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ARTIST_KEY = "artist_key";
-
- /**
- * The number of songs on this album
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String NUMBER_OF_SONGS = "numsongs";
-
- /**
- * This column is available when getting album info via artist,
- * and indicates the number of songs on the album by the given
- * artist.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String NUMBER_OF_SONGS_FOR_ARTIST = "numsongs_by_artist";
-
- /**
- * The year in which the earliest songs
- * on this album were released. This will often
- * be the same as {@link #LAST_YEAR}, but for compilation albums
- * they might differ.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String FIRST_YEAR = "minyear";
-
- /**
- * The year in which the latest songs
- * on this album were released. This will often
- * be the same as {@link #FIRST_YEAR}, but for compilation albums
- * they might differ.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String LAST_YEAR = "maxyear";
-
- /**
- * A non human readable key calculated from the ALBUM, used for
- * searching, sorting and grouping
- *
- * @see Audio#keyFor(String)
- * @deprecated These keys are generated using
- * {@link java.util.Locale#ROOT}, which means they don't
- * reflect locale-specific sorting preferences. To apply
- * locale-specific sorting preferences, use
- * {@link ContentResolver#QUERY_ARG_SQL_SORT_ORDER} with
- * {@code COLLATE LOCALIZED}, or
- * {@link ContentResolver#QUERY_ARG_SORT_LOCALE}.
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String ALBUM_KEY = "album_key";
-
- /**
- * Cached album art.
- *
- * @deprecated Apps may not have filesystem permissions to directly
- * access this path. Instead of trying to open this path
- * directly, apps should use
- * {@link ContentResolver#loadThumbnail}
- * to gain access.
- */
- @Deprecated
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String ALBUM_ART = "album_art";
- }
-
- /**
- * Contains artists for audio files
- */
- public static final class Albums implements BaseColumns, AlbumColumns {
- /**
- * Get the content:// style URI for the albums table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @return the URI to the audio albums table on the given volume
- */
- public static Uri getContentUri(String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("audio")
- .appendPath("albums").build();
- }
-
- /**
- * The content:// style URI for the internal storage.
- */
- public static final Uri INTERNAL_CONTENT_URI =
- getContentUri("internal");
-
- /**
- * The content:// style URI for the "primary" external storage
- * volume.
- */
- public static final Uri EXTERNAL_CONTENT_URI =
- getContentUri("external");
-
- /**
- * The MIME type for this table.
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/albums";
-
- /**
- * The MIME type for entries in this table.
- */
- public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/album";
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = ALBUM_KEY;
- }
-
- public static final class Radio {
- /**
- * The MIME type for entries in this table.
- */
- public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/radio";
-
- // Not instantiable.
- private Radio() { }
- }
-
- /**
- * This class provides utility methods to obtain thumbnails for various
- * {@link Audio} items.
- *
- * @deprecated Callers should migrate to using
- * {@link ContentResolver#loadThumbnail}, since it offers
- * richer control over requested thumbnail sizes and
- * cancellation behavior.
- * @hide
- */
- @Deprecated
- public static class Thumbnails implements BaseColumns {
- /**
- * Path to the thumbnail file on disk.
- * <p>
- * Note that apps may not have filesystem permissions to directly
- * access this path. Instead of trying to open this path directly,
- * apps should use
- * {@link ContentResolver#openFileDescriptor(Uri, String)} to gain
- * access.
- *
- * @deprecated Apps may not have filesystem permissions to directly
- * access this path. Instead of trying to open this path
- * directly, apps should use
- * {@link ContentResolver#loadThumbnail}
- * to gain access.
- */
- @Deprecated
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String DATA = "_data";
-
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String ALBUM_ID = "album_id";
- }
- }
-
- /**
- * Collection of all media with MIME type of {@code video/*}.
- */
- public static final class Video {
-
- /**
- * The default sort order for this table.
- */
- public static final String DEFAULT_SORT_ORDER = MediaColumns.DISPLAY_NAME;
-
- /**
- * @deprecated all queries should be performed through
- * {@link ContentResolver} directly, which offers modern
- * features like {@link CancellationSignal}.
- */
- @Deprecated
- public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) {
- return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER);
- }
-
- /**
- * Video metadata columns.
- */
- public interface VideoColumns extends MediaColumns {
- /** @removed promoted to parent interface */
- public static final String DURATION = "duration";
- /** @removed promoted to parent interface */
- public static final String ARTIST = "artist";
- /** @removed promoted to parent interface */
- public static final String ALBUM = "album";
- /** @removed promoted to parent interface */
- public static final String RESOLUTION = "resolution";
-
- /**
- * The description of the video recording
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String DESCRIPTION = "description";
-
- /**
- * Whether the video should be published as public or private
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String IS_PRIVATE = "isprivate";
-
- /**
- * The user-added tags associated with a video
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String TAGS = "tags";
-
- /**
- * The YouTube category of the video
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String CATEGORY = "category";
-
- /**
- * The language of the video
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String LANGUAGE = "language";
-
- /**
- * The latitude where the video was captured.
- *
- * @deprecated location details are no longer indexed for privacy
- * reasons, and this value is now always {@code null}.
- * You can still manually obtain location metadata using
- * {@link ExifInterface#getLatLong(float[])}.
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_FLOAT, readOnly = true)
- public static final String LATITUDE = "latitude";
-
- /**
- * The longitude where the video was captured.
- *
- * @deprecated location details are no longer indexed for privacy
- * reasons, and this value is now always {@code null}.
- * You can still manually obtain location metadata using
- * {@link ExifInterface#getLatLong(float[])}.
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_FLOAT, readOnly = true)
- public static final String LONGITUDE = "longitude";
-
- /** @removed promoted to parent interface */
- public static final String DATE_TAKEN = "datetaken";
-
- /**
- * The mini thumb id.
- *
- * @deprecated all thumbnails should be obtained via
- * {@link MediaStore.Images.Thumbnails#getThumbnail}, as this
- * value is no longer supported.
- */
- @Deprecated
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
-
- /** @removed promoted to parent interface */
- public static final String BUCKET_ID = "bucket_id";
- /** @removed promoted to parent interface */
- public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
- /** @removed promoted to parent interface */
- public static final String GROUP_ID = "group_id";
-
- /**
- * The position within the video item at which playback should be
- * resumed.
- */
- @DurationMillisLong
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String BOOKMARK = "bookmark";
-
- /**
- * The color standard of this media file, if available.
- *
- * @see MediaFormat#COLOR_STANDARD_BT709
- * @see MediaFormat#COLOR_STANDARD_BT601_PAL
- * @see MediaFormat#COLOR_STANDARD_BT601_NTSC
- * @see MediaFormat#COLOR_STANDARD_BT2020
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String COLOR_STANDARD = "color_standard";
-
- /**
- * The color transfer of this media file, if available.
- *
- * @see MediaFormat#COLOR_TRANSFER_LINEAR
- * @see MediaFormat#COLOR_TRANSFER_SDR_VIDEO
- * @see MediaFormat#COLOR_TRANSFER_ST2084
- * @see MediaFormat#COLOR_TRANSFER_HLG
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String COLOR_TRANSFER = "color_transfer";
-
- /**
- * The color range of this media file, if available.
- *
- * @see MediaFormat#COLOR_RANGE_LIMITED
- * @see MediaFormat#COLOR_RANGE_FULL
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String COLOR_RANGE = "color_range";
- }
-
- public static final class Media implements VideoColumns {
- /**
- * Get the content:// style URI for the video media table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @return the URI to the video media table on the given volume
- */
- public static Uri getContentUri(String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("video")
- .appendPath("media").build();
- }
-
- /**
- * Get the content:// style URI for a single row in the videos table
- * on the given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @param id the video to get the URI for
- * @return the URI to the videos table on the given volume
- */
- public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
- return ContentUris.withAppendedId(getContentUri(volumeName), id);
- }
-
- /**
- * The content:// style URI for the internal storage.
- */
- public static final Uri INTERNAL_CONTENT_URI =
- getContentUri("internal");
-
- /**
- * The content:// style URI for the "primary" external storage
- * volume.
- */
- public static final Uri EXTERNAL_CONTENT_URI =
- getContentUri("external");
-
- /**
- * The MIME type for this table.
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/video";
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = TITLE;
- }
-
- /**
- * This class provides utility methods to obtain thumbnails for various
- * {@link Video} items.
- *
- * @deprecated Callers should migrate to using
- * {@link ContentResolver#loadThumbnail}, since it offers
- * richer control over requested thumbnail sizes and
- * cancellation behavior.
- */
- @Deprecated
- public static class Thumbnails implements BaseColumns {
- /**
- * Cancel any outstanding {@link #getThumbnail} requests, causing
- * them to return by throwing a {@link OperationCanceledException}.
- * <p>
- * This method has no effect on
- * {@link ContentResolver#loadThumbnail} calls, since they provide
- * their own {@link CancellationSignal}.
- *
- * @deprecated Callers should migrate to using
- * {@link ContentResolver#loadThumbnail}, since it
- * offers richer control over requested thumbnail sizes
- * and cancellation behavior.
- */
- @Deprecated
- public static void cancelThumbnailRequest(ContentResolver cr, long origId) {
- final Uri uri = ContentUris.withAppendedId(
- Video.Media.EXTERNAL_CONTENT_URI, origId);
- InternalThumbnails.cancelThumbnail(cr, uri);
- }
-
- /**
- * Return thumbnail representing a specific video item. If a
- * thumbnail doesn't exist, this method will block until it's
- * generated. Callers are responsible for their own in-memory
- * caching of returned values.
- *
- * @param videoId the video item to obtain a thumbnail for.
- * @param kind optimal thumbnail size desired.
- * @return decoded thumbnail, or {@code null} if problem was
- * encountered.
- * @deprecated Callers should migrate to using
- * {@link ContentResolver#loadThumbnail}, since it
- * offers richer control over requested thumbnail sizes
- * and cancellation behavior.
- */
- @Deprecated
- public static Bitmap getThumbnail(ContentResolver cr, long videoId, int kind,
- BitmapFactory.Options options) {
- final Uri uri = ContentUris.withAppendedId(
- Video.Media.EXTERNAL_CONTENT_URI, videoId);
- return InternalThumbnails.getThumbnail(cr, uri, kind, options);
- }
-
- /**
- * Cancel any outstanding {@link #getThumbnail} requests, causing
- * them to return by throwing a {@link OperationCanceledException}.
- * <p>
- * This method has no effect on
- * {@link ContentResolver#loadThumbnail} calls, since they provide
- * their own {@link CancellationSignal}.
- *
- * @deprecated Callers should migrate to using
- * {@link ContentResolver#loadThumbnail}, since it
- * offers richer control over requested thumbnail sizes
- * and cancellation behavior.
- */
- @Deprecated
- public static void cancelThumbnailRequest(ContentResolver cr, long videoId,
- long groupId) {
- cancelThumbnailRequest(cr, videoId);
- }
-
- /**
- * Return thumbnail representing a specific video item. If a
- * thumbnail doesn't exist, this method will block until it's
- * generated. Callers are responsible for their own in-memory
- * caching of returned values.
- *
- * @param videoId the video item to obtain a thumbnail for.
- * @param kind optimal thumbnail size desired.
- * @return decoded thumbnail, or {@code null} if problem was
- * encountered.
- * @deprecated Callers should migrate to using
- * {@link ContentResolver#loadThumbnail}, since it
- * offers richer control over requested thumbnail sizes
- * and cancellation behavior.
- */
- @Deprecated
- public static Bitmap getThumbnail(ContentResolver cr, long videoId, long groupId,
- int kind, BitmapFactory.Options options) {
- return getThumbnail(cr, videoId, kind, options);
- }
-
- /**
- * Get the content:// style URI for the image media table on the
- * given volume.
- *
- * @param volumeName the name of the volume to get the URI for
- * @return the URI to the image media table on the given volume
- */
- public static Uri getContentUri(String volumeName) {
- return AUTHORITY_URI.buildUpon().appendPath(volumeName).appendPath("video")
- .appendPath("thumbnails").build();
- }
-
- /**
- * The content:// style URI for the internal storage.
- */
- public static final Uri INTERNAL_CONTENT_URI =
- getContentUri("internal");
-
- /**
- * The content:// style URI for the "primary" external storage
- * volume.
- */
- public static final Uri EXTERNAL_CONTENT_URI =
- getContentUri("external");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "video_id ASC";
-
- /**
- * Path to the thumbnail file on disk.
- *
- * @deprecated Apps may not have filesystem permissions to directly
- * access this path. Instead of trying to open this path
- * directly, apps should use
- * {@link ContentResolver#openFileDescriptor(Uri, String)}
- * to gain access.
- */
- @Deprecated
- @Column(Cursor.FIELD_TYPE_STRING)
- public static final String DATA = "_data";
-
- /**
- * The original image for the thumbnal
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String VIDEO_ID = "video_id";
-
- /**
- * The kind of the thumbnail
- */
- @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String KIND = "kind";
-
- public static final int MINI_KIND = ThumbnailConstants.MINI_KIND;
- public static final int FULL_SCREEN_KIND = ThumbnailConstants.FULL_SCREEN_KIND;
- public static final int MICRO_KIND = ThumbnailConstants.MICRO_KIND;
-
- /**
- * Return the typical {@link Size} (in pixels) used internally when
- * the given thumbnail kind is requested.
- */
- public static @NonNull Size getKindSize(int kind) {
- return ThumbnailConstants.getKindSize(kind);
- }
-
- /**
- * The width of the thumbnal
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String WIDTH = "width";
-
- /**
- * The height of the thumbnail
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String HEIGHT = "height";
- }
- }
-
- /** @removed */
- @Deprecated
- public static @NonNull Set<String> getAllVolumeNames(@NonNull Context context) {
- return getExternalVolumeNames(context);
- }
-
- /**
- * Return list of all specific volume names that make up
- * {@link #VOLUME_EXTERNAL}. This includes a unique volume name for each
- * shared storage device that is currently attached, which typically
- * includes {@link MediaStore#VOLUME_EXTERNAL_PRIMARY}.
- * <p>
- * Each specific volume name can be passed to APIs like
- * {@link MediaStore.Images.Media#getContentUri(String)} to interact with
- * media on that storage device.
- */
- public static @NonNull Set<String> getExternalVolumeNames(@NonNull Context context) {
- final StorageManager sm = context.getSystemService(StorageManager.class);
- final Set<String> res = new ArraySet<>();
- for (StorageVolume sv : sm.getStorageVolumes()) {
- switch (sv.getState()) {
- case Environment.MEDIA_MOUNTED:
- case Environment.MEDIA_MOUNTED_READ_ONLY: {
- final String volumeName = sv.getMediaStoreVolumeName();
- if (volumeName != null) {
- res.add(volumeName);
- }
- break;
- }
- }
- }
- return res;
- }
-
- /**
- * Return list of all recent volume names that have been part of
- * {@link #VOLUME_EXTERNAL}.
- * <p>
- * These volume names are not currently mounted, but they're likely to
- * reappear in the future, so apps are encouraged to preserve any indexed
- * metadata related to these volumes to optimize user experiences.
- * <p>
- * Each specific volume name can be passed to APIs like
- * {@link MediaStore.Images.Media#getContentUri(String)} to interact with
- * media on that storage device.
- */
- public static @NonNull Set<String> getRecentExternalVolumeNames(@NonNull Context context) {
- final StorageManager sm = context.getSystemService(StorageManager.class);
- final Set<String> res = new ArraySet<>();
- for (StorageVolume sv : sm.getRecentStorageVolumes()) {
- final String volumeName = sv.getMediaStoreVolumeName();
- if (volumeName != null) {
- res.add(volumeName);
- }
- }
- return res;
- }
-
- /**
- * Return the volume name that the given {@link Uri} references.
- */
- public static @NonNull String getVolumeName(@NonNull Uri uri) {
- final List<String> segments = uri.getPathSegments();
- switch (uri.getAuthority()) {
- case AUTHORITY:
- case AUTHORITY_LEGACY: {
- if (segments != null && segments.size() > 0) {
- return segments.get(0);
- }
- }
- }
- throw new IllegalArgumentException("Missing volume name: " + uri);
- }
-
- /** {@hide} */
- public static @NonNull String checkArgumentVolumeName(@NonNull String volumeName) {
- if (TextUtils.isEmpty(volumeName)) {
- throw new IllegalArgumentException();
- }
-
- if (VOLUME_INTERNAL.equals(volumeName)) {
- return volumeName;
- } else if (VOLUME_EXTERNAL.equals(volumeName)) {
- return volumeName;
- } else if (VOLUME_EXTERNAL_PRIMARY.equals(volumeName)) {
- return volumeName;
- }
-
- // When not one of the well-known values above, it must be a hex UUID
- for (int i = 0; i < volumeName.length(); i++) {
- final char c = volumeName.charAt(i);
- if (('a' <= c && c <= 'f') || ('0' <= c && c <= '9') || (c == '-')) {
- continue;
- } else {
- throw new IllegalArgumentException("Invalid volume name: " + volumeName);
- }
- }
- return volumeName;
- }
-
- private static boolean parseBoolean(@Nullable String value) {
- if (value == null) return false;
- if ("1".equals(value)) return true;
- if ("true".equalsIgnoreCase(value)) return true;
- return false;
- }
-
- /**
- * Uri for querying the state of the media scanner.
- */
- public static Uri getMediaScannerUri() {
- return AUTHORITY_URI.buildUpon().appendPath("none").appendPath("media_scanner").build();
- }
-
- /**
- * Name of current volume being scanned by the media scanner.
- */
- public static final String MEDIA_SCANNER_VOLUME = "volume";
-
- /**
- * Name of the file signaling the media scanner to ignore media in the containing directory
- * and its subdirectories. Developers should use this to avoid application graphics showing
- * up in the Gallery and likewise prevent application sounds and music from showing up in
- * the Music app.
- */
- public static final String MEDIA_IGNORE_FILENAME = ".nomedia";
-
- /**
- * Return an opaque version string describing the {@link MediaStore} state.
- * <p>
- * Applications that import data from {@link MediaStore} into their own
- * caches can use this to detect that {@link MediaStore} has undergone
- * substantial changes, and that data should be rescanned.
- * <p>
- * No other assumptions should be made about the meaning of the version.
- * <p>
- * This method returns the version for
- * {@link MediaStore#VOLUME_EXTERNAL_PRIMARY}; to obtain a version for a
- * different volume, use {@link #getVersion(Context, String)}.
- */
- public static @NonNull String getVersion(@NonNull Context context) {
- return getVersion(context, VOLUME_EXTERNAL_PRIMARY);
- }
-
- /**
- * Return an opaque version string describing the {@link MediaStore} state.
- * <p>
- * Applications that import data from {@link MediaStore} into their own
- * caches can use this to detect that {@link MediaStore} has undergone
- * substantial changes, and that data should be rescanned.
- * <p>
- * No other assumptions should be made about the meaning of the version.
- *
- * @param volumeName specific volume to obtain an opaque version string for.
- * Must be one of the values returned from
- * {@link #getExternalVolumeNames(Context)}.
- */
- public static @NonNull String getVersion(@NonNull Context context, @NonNull String volumeName) {
- final ContentResolver resolver = context.getContentResolver();
- try (ContentProviderClient client = resolver.acquireContentProviderClient(AUTHORITY)) {
- final Bundle in = new Bundle();
- in.putString(Intent.EXTRA_TEXT, volumeName);
- final Bundle out = client.call(GET_VERSION_CALL, null, in);
- return out.getString(Intent.EXTRA_TEXT);
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Return a {@link DocumentsProvider} Uri that is an equivalent to the given
- * {@link MediaStore} Uri.
- * <p>
- * This allows apps with Storage Access Framework permissions to convert
- * between {@link MediaStore} and {@link DocumentsProvider} Uris that refer
- * to the same underlying item. Note that this method doesn't grant any new
- * permissions; callers must already hold permissions obtained with
- * {@link Intent#ACTION_OPEN_DOCUMENT} or related APIs.
- *
- * @param mediaUri The {@link MediaStore} Uri to convert.
- * @return An equivalent {@link DocumentsProvider} Uri. Returns {@code null}
- * if no equivalent was found.
- * @see #getMediaUri(Context, Uri)
- */
- public static @Nullable Uri getDocumentUri(@NonNull Context context, @NonNull Uri mediaUri) {
- final ContentResolver resolver = context.getContentResolver();
- final List<UriPermission> uriPermissions = resolver.getPersistedUriPermissions();
-
- try (ContentProviderClient client = resolver.acquireContentProviderClient(AUTHORITY)) {
- final Bundle in = new Bundle();
- in.putParcelable(EXTRA_URI, mediaUri);
- in.putParcelableArrayList(EXTRA_URI_PERMISSIONS, new ArrayList<>(uriPermissions));
- final Bundle out = client.call(GET_DOCUMENT_URI_CALL, null, in);
- return out.getParcelable(EXTRA_URI);
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Return a {@link MediaStore} Uri that is an equivalent to the given
- * {@link DocumentsProvider} Uri.
- * <p>
- * This allows apps with Storage Access Framework permissions to convert
- * between {@link MediaStore} and {@link DocumentsProvider} Uris that refer
- * to the same underlying item. Note that this method doesn't grant any new
- * permissions; callers must already hold permissions obtained with
- * {@link Intent#ACTION_OPEN_DOCUMENT} or related APIs.
- *
- * @param documentUri The {@link DocumentsProvider} Uri to convert.
- * @return An equivalent {@link MediaStore} Uri. Returns {@code null} if no
- * equivalent was found.
- * @see #getDocumentUri(Context, Uri)
- */
- public static @Nullable Uri getMediaUri(@NonNull Context context, @NonNull Uri documentUri) {
- final ContentResolver resolver = context.getContentResolver();
- final List<UriPermission> uriPermissions = resolver.getPersistedUriPermissions();
-
- try (ContentProviderClient client = resolver.acquireContentProviderClient(AUTHORITY)) {
- final Bundle in = new Bundle();
- in.putParcelable(EXTRA_URI, documentUri);
- in.putParcelableArrayList(EXTRA_URI_PERMISSIONS, new ArrayList<>(uriPermissions));
- final Bundle out = client.call(GET_MEDIA_URI_CALL, null, in);
- return out.getParcelable(EXTRA_URI);
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- }
- }
-
- /** @hide */
- @TestApi
- public static void waitForIdle(@NonNull ContentResolver resolver) {
- resolver.call(AUTHORITY, WAIT_FOR_IDLE_CALL, null, null);
- }
-
- /**
- * Perform a blocking scan of the given {@link File}, returning the
- * {@link Uri} of the scanned file.
- *
- * @hide
- */
- @SystemApi
- @TestApi
- @SuppressLint("StreamFiles")
- public static @NonNull Uri scanFile(@NonNull ContentResolver resolver, @NonNull File file) {
- final Bundle out = resolver.call(AUTHORITY, SCAN_FILE_CALL, file.getAbsolutePath(), null);
- return out.getParcelable(Intent.EXTRA_STREAM);
- }
-
- /**
- * Perform a blocking scan of the given storage volume.
- *
- * @hide
- */
- @SystemApi
- @TestApi
- public static void scanVolume(@NonNull ContentResolver resolver, @NonNull String volumeName) {
- resolver.call(AUTHORITY, SCAN_VOLUME_CALL, volumeName, null);
- }
-}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 503d6db..462627e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3900,6 +3900,12 @@
public static final String VOLUME_ACCESSIBILITY = "volume_a11y";
/**
+ * @hide
+ * Volume index for virtual assistant.
+ */
+ public static final String VOLUME_ASSISTANT = "volume_assistant";
+
+ /**
* Master volume (float in the range 0.0f to 1.0f).
*
* @hide
@@ -3977,7 +3983,7 @@
"" /*STREAM_SYSTEM_ENFORCED, no setting for this stream*/,
"" /*STREAM_DTMF, no setting for this stream*/,
"" /*STREAM_TTS, no setting for this stream*/,
- VOLUME_ACCESSIBILITY
+ VOLUME_ACCESSIBILITY, VOLUME_ASSISTANT
};
/**
@@ -4524,6 +4530,7 @@
PUBLIC_SETTINGS.add(VOLUME_ALARM);
PUBLIC_SETTINGS.add(VOLUME_NOTIFICATION);
PUBLIC_SETTINGS.add(VOLUME_BLUETOOTH_SCO);
+ PUBLIC_SETTINGS.add(VOLUME_ASSISTANT);
PUBLIC_SETTINGS.add(RINGTONE);
PUBLIC_SETTINGS.add(NOTIFICATION_SOUND);
PUBLIC_SETTINGS.add(ALARM_ALERT);
@@ -9556,35 +9563,37 @@
*/
public static final String SMS_SHORT_CODE_RULE = "sms_short_code_rule";
- /**
- * Used to select TCP's default initial receiver window size in segments - defaults to a build config value
- * @hide
- */
- public static final String TCP_DEFAULT_INIT_RWND = "tcp_default_init_rwnd";
+ /**
+ * Used to select TCP's default initial receiver window size in segments - defaults to a
+ * build config value.
+ * @hide
+ */
+ public static final String TCP_DEFAULT_INIT_RWND = "tcp_default_init_rwnd";
- /**
- * Used to disable Tethering on a device - defaults to true
- * @hide
- */
- public static final String TETHER_SUPPORTED = "tether_supported";
+ /**
+ * Used to disable Tethering on a device - defaults to true.
+ * @hide
+ */
+ @SystemApi
+ public static final String TETHER_SUPPORTED = "tether_supported";
- /**
- * Used to require DUN APN on the device or not - defaults to a build config value
- * which defaults to false
- * @hide
- */
- public static final String TETHER_DUN_REQUIRED = "tether_dun_required";
+ /**
+ * Used to require DUN APN on the device or not - defaults to a build config value
+ * which defaults to false.
+ * @hide
+ */
+ public static final String TETHER_DUN_REQUIRED = "tether_dun_required";
- /**
- * Used to hold a gservices-provisioned apn value for DUN. If set, or the
- * corresponding build config values are set it will override the APN DB
- * values.
- * Consists of a comma seperated list of strings:
- * "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
- * note that empty fields can be omitted: "name,apn,,,,,,,,,310,260,,DUN"
- * @hide
- */
- public static final String TETHER_DUN_APN = "tether_dun_apn";
+ /**
+ * Used to hold a gservices-provisioned apn value for DUN. If set, or the
+ * corresponding build config values are set it will override the APN DB
+ * values.
+ * Consists of a comma separated list of strings:
+ * "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
+ * note that empty fields can be omitted: "name,apn,,,,,,,,,310,260,,DUN"
+ * @hide
+ */
+ public static final String TETHER_DUN_APN = "tether_dun_apn";
/**
* Used to disable trying to talk to any available tethering offload HAL.
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index c287ae3..fed3d7ba 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1389,7 +1389,6 @@
for (int i = 0; i < pduCount; i++) {
byte[] pdu = (byte[]) messages[i];
msgs[i] = SmsMessage.createFromPdu(pdu, format);
- if (msgs[i] != null) msgs[i].setSubId(subId);
}
return msgs;
}
diff --git a/core/java/android/service/dataloader/DataLoaderService.java b/core/java/android/service/dataloader/DataLoaderService.java
index 373e1e5..54a4fa6 100644
--- a/core/java/android/service/dataloader/DataLoaderService.java
+++ b/core/java/android/service/dataloader/DataLoaderService.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
import android.content.pm.DataLoaderParams;
@@ -45,30 +46,41 @@
* The base class for implementing data loader service to control data loaders. Expecting
* Incremental Service to bind to a children class of this.
*
- * @hide
+ * WARNING: This is a system API to aid internal development.
+ * Use at your own risk. It will change or be removed without warning.
*
- * Hide for now, should be @SystemApi
* TODO(b/136132412): update with latest API design
+ *
+ * @hide
*/
+@SystemApi
public abstract class DataLoaderService extends Service {
private static final String TAG = "IncrementalDataLoaderService";
private final DataLoaderBinderService mBinder = new DataLoaderBinderService();
+ /** @hide */
public static final int DATA_LOADER_READY =
IDataLoaderStatusListener.DATA_LOADER_READY;
+ /** @hide */
public static final int DATA_LOADER_NOT_READY =
IDataLoaderStatusListener.DATA_LOADER_NOT_READY;
+ /** @hide */
public static final int DATA_LOADER_RUNNING =
IDataLoaderStatusListener.DATA_LOADER_RUNNING;
+ /** @hide */
public static final int DATA_LOADER_STOPPED =
IDataLoaderStatusListener.DATA_LOADER_STOPPED;
+ /** @hide */
public static final int DATA_LOADER_SLOW_CONNECTION =
IDataLoaderStatusListener.DATA_LOADER_SLOW_CONNECTION;
+ /** @hide */
public static final int DATA_LOADER_NO_CONNECTION =
IDataLoaderStatusListener.DATA_LOADER_NO_CONNECTION;
+ /** @hide */
public static final int DATA_LOADER_CONNECTION_OK =
IDataLoaderStatusListener.DATA_LOADER_CONNECTION_OK;
+ /** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"DATA_LOADER_"}, value = {
DATA_LOADER_READY,
@@ -85,6 +97,7 @@
/**
* Managed DataLoader interface. Each instance corresponds to a single Incremental File System
* instance.
+ * @hide
*/
public abstract static class DataLoader {
/**
@@ -130,6 +143,7 @@
* DataLoader factory method.
*
* @return An instance of a DataLoader.
+ * @hide
*/
public abstract @Nullable DataLoader onCreateDataLoader();
@@ -220,8 +234,6 @@
* Used by the DataLoaderService implementations.
*
* @hide
- *
- * TODO(b/136132412) Should be @SystemApi
*/
public static final class FileSystemConnector {
/**
@@ -264,7 +276,6 @@
/**
* Wrapper for native reporting DataLoader statuses.
* @hide
- * TODO(b/136132412) Should be @SystemApi
*/
public static final class StatusListener {
/**
diff --git a/core/java/android/util/proto/ProtoOutputStream.java b/core/java/android/util/proto/ProtoOutputStream.java
index 6efcfbf..7b24ba9 100644
--- a/core/java/android/util/proto/ProtoOutputStream.java
+++ b/core/java/android/util/proto/ProtoOutputStream.java
@@ -16,7 +16,8 @@
package android.util.proto;
-import android.annotation.TestApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.util.Log;
import java.io.FileDescriptor;
@@ -28,19 +29,23 @@
/**
* Class to write to a protobuf stream.
*
- * Each write method takes an ID code from the protoc generated classes
- * and the value to write. To make a nested object, call #start
- * and then #end when you are done.
+ * <p>
+ * This API is not as convenient or type safe as the standard protobuf
+ * classes. If possible, the best recommended library is to use protobuf lite.
+ * However, in environements (such as the Android platform itself), a
+ * more memory efficient version is necessary.
*
- * The ID codes have type information embedded into them, so if you call
- * the incorrect function you will get an IllegalArgumentException.
+ * <p>Each write method takes an ID code from the protoc generated classes
+ * and the value to write. To make a nested object, call {@link #start(long)}
+ * and then {@link #end(long)} when you are done.
*
- * To retrieve the encoded protobuf stream, call getBytes().
+ * <p>The ID codes have type information embedded into them, so if you call
+ * the incorrect function you will get an {@link IllegalArgumentException}.
*
- * TODO: Add a constructor that takes an OutputStream and write to that
+ * <p>To retrieve the encoded protobuf stream, call {@link #getBytes()}.
+ *
* stream as the top-level objects are finished.
*
- * @hide
*/
/* IMPLEMENTATION NOTES
@@ -99,7 +104,6 @@
* correctly matched pairs of #start and #end calls, and issue
* errors if they are not matched.
*/
-@TestApi
public final class ProtoOutputStream extends ProtoStream {
/**
* @hide
@@ -124,7 +128,9 @@
/**
* An ID given to objects and returned in the token from startObject
* and stored in the buffer until endObject is called, where the two
- * are checked. Starts at -1 and becomes more negative, so the values
+ * are checked.
+ *
+ * <p>Starts at -1 and becomes more negative, so the values
* aren't likely to alias with the size it will be overwritten with,
* which tend to be small, and we will be more likely to catch when
* the caller of endObject uses a stale token that they didn't intend
@@ -133,8 +139,9 @@
private int mNextObjectId = -1;
/**
- * The object token we are expecting in endObject. If another call to
- * startObject happens, this is written to that location, which gives
+ * The object token we are expecting in endObject.
+ *
+ * <p>If another call to startObject happens, this is written to that location, which gives
* us a stack, stored in the space for the as-yet unused size fields.
*/
private long mExpectedObjectToken;
@@ -151,39 +158,45 @@
private boolean mCompacted;
/**
- * Construct a ProtoOutputStream with the default chunk size.
+ * Construct a {@link ProtoOutputStream} with the default chunk size.
+ *
+ * <p>This is for an in-memory proto. The caller should use {@link #getBytes()} for the result.
*/
public ProtoOutputStream() {
this(0);
}
/**
- * Construct a ProtoOutputStream with the given chunk size.
+ * Construct a {@link ProtoOutputStream with the given chunk size.
+ *
+ * <p>This is for an in-memory proto. The caller should use {@link #getBytes()} for the result.
*/
public ProtoOutputStream(int chunkSize) {
mBuffer = new EncodedBuffer(chunkSize);
}
/**
- * Construct a ProtoOutputStream that sits on top of an OutputStream.
- * @more
- * The {@link #flush() flush()} method must be called when done writing
- * to flush any remanining data, althought data *may* be written at intermediate
+ * Construct a {@link ProtoOutputStream} that sits on top of an {@link OutputStream}.
+ *
+ * <p>The {@link #flush()} method must be called when done writing
+ * to flush any remaining data, although data *may* be written at intermediate
* points within the writing as well.
*/
- public ProtoOutputStream(OutputStream stream) {
+ public ProtoOutputStream(@NonNull OutputStream stream) {
this();
mStream = stream;
}
/**
- * Construct a ProtoOutputStream that sits on top of a FileDescriptor.
- * @more
- * The {@link #flush() flush()} method must be called when done writing
- * to flush any remanining data, althought data *may* be written at intermediate
+ * Construct a {@link ProtoOutputStream} that sits on top of a {@link FileDescriptor}.
+ *
+ * <p>The {@link #flush()} method must be called when done writing
+ * to flush any remaining data, although data *may* be written at intermediate
* points within the writing as well.
+ *
+ * @hide
*/
- public ProtoOutputStream(FileDescriptor fd) {
+ public ProtoOutputStream(@NonNull FileDescriptor fd) {
this(new FileOutputStream(fd));
}
@@ -202,7 +215,7 @@
/**
* Write a value for the given fieldId.
*
- * Will automatically convert for the following field types, and
+ * <p>Will automatically convert for the following field types, and
* throw an exception for others: double, float, int32, int64, uint32, uint64,
* sint32, sint64, fixed32, fixed64, sfixed32, sfixed64, bool, enum.
*
@@ -337,7 +350,7 @@
/**
* Write a value for the given fieldId.
*
- * Will automatically convert for the following field types, and
+ * <p>Will automatically convert for the following field types, and
* throw an exception for others: double, float, int32, int64, uint32, uint64,
* sint32, sint64, fixed32, fixed64, sfixed32, sfixed64, bool, enum.
*
@@ -472,7 +485,7 @@
/**
* Write a value for the given fieldId.
*
- * Will automatically convert for the following field types, and
+ * <p>Will automatically convert for the following field types, and
* throw an exception for others: double, float, int32, int64, uint32, uint64,
* sint32, sint64, fixed32, fixed64, sfixed32, sfixed64, bool, enum.
*
@@ -607,7 +620,7 @@
/**
* Write a value for the given fieldId.
*
- * Will automatically convert for the following field types, and
+ * <p>Will automatically convert for the following field types, and
* throw an exception for others: double, float, int32, int64, uint32, uint64,
* sint32, sint64, fixed32, fixed64, sfixed32, sfixed64, bool, enum.
*
@@ -742,7 +755,7 @@
/**
* Write a boolean value for the given fieldId.
*
- * If the field is not a bool field, an exception will be thrown.
+ * <p>If the field is not a bool field, an {@link IllegalStateException} will be thrown.
*
* @param fieldId The field identifier constant from the generated class.
* @param val The value.
@@ -771,12 +784,12 @@
/**
* Write a string value for the given fieldId.
*
- * If the field is not a string field, an exception will be thrown.
+ * <p>If the field is not a string field, an exception will be thrown.
*
* @param fieldId The field identifier constant from the generated class.
* @param val The value.
*/
- public void write(long fieldId, String val) {
+ public void write(long fieldId, @Nullable String val) {
assertNotCompacted();
final int id = (int)fieldId;
@@ -800,12 +813,12 @@
/**
* Write a byte[] value for the given fieldId.
*
- * If the field is not a bytes or object field, an exception will be thrown.
+ * <p>If the field is not a bytes or object field, an exception will be thrown.
*
* @param fieldId The field identifier constant from the generated class.
* @param val The value.
*/
- public void write(long fieldId, byte[] val) {
+ public void write(long fieldId, @Nullable byte[] val) {
assertNotCompacted();
final int id = (int)fieldId;
@@ -836,6 +849,9 @@
/**
* Start a sub object.
+ *
+ * @param fieldId The field identifier constant from the generated class.
+ * @return The token to call {@link #end(long)} with.
*/
public long start(long fieldId) {
assertNotCompacted();
@@ -855,6 +871,8 @@
/**
* End the object started by start() that returned token.
+ *
+ * @param token The token returned from {@link #start(long)}
*/
public void end(long token) {
endObjectImpl(token, getRepeatedFromToken(token));
@@ -870,7 +888,8 @@
/**
* Write a single proto "double" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, double)} instead.
+ * @hide
*/
@Deprecated
public void writeDouble(long fieldId, double val) {
@@ -890,7 +909,8 @@
/**
* Write a single repeated proto "double" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, double)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedDouble(long fieldId, double val) {
@@ -908,10 +928,11 @@
/**
* Write a list of packed proto "double" type field values.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, double)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedDouble(long fieldId, double[] val) {
+ public void writePackedDouble(long fieldId, @Nullable double[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_DOUBLE);
@@ -934,7 +955,8 @@
/**
* Write a single proto "float" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, float)} instead.
+ * @hide
*/
@Deprecated
public void writeFloat(long fieldId, float val) {
@@ -954,7 +976,8 @@
/**
* Write a single repeated proto "float" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, float)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedFloat(long fieldId, float val) {
@@ -972,10 +995,11 @@
/**
* Write a list of packed proto "float" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, float)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedFloat(long fieldId, float[] val) {
+ public void writePackedFloat(long fieldId, @Nullable float[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_FLOAT);
@@ -999,7 +1023,7 @@
/**
* Writes a java int as an usigned varint.
*
- * The unadorned int32 type in protobuf is unfortunate because it
+ * <p>The unadorned int32 type in protobuf is unfortunate because it
* is stored in memory as a signed value, but encodes as unsigned
* varints, which are formally always longs. So here, we encode
* negative values as 64 bits, which will get the sign-extension,
@@ -1017,11 +1041,12 @@
/**
* Write a single proto "int32" type field value.
*
- * Note that these are stored in memory as signed values and written as unsigned
+ * <p>Note that these are stored in memory as signed values and written as unsigned
* varints, which if negative, are 10 bytes long. If you know the data is likely
* to be negative, use "sint32".
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeInt32(long fieldId, int val) {
@@ -1041,11 +1066,12 @@
/**
* Write a single repeated proto "int32" type field value.
*
- * Note that these are stored in memory as signed values and written as unsigned
+ * <p>Note that these are stored in memory as signed values and written as unsigned
* varints, which if negative, are 10 bytes long. If you know the data is likely
* to be negative, use "sint32".
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedInt32(long fieldId, int val) {
@@ -1063,14 +1089,15 @@
/**
* Write a list of packed proto "int32" type field value.
*
- * Note that these are stored in memory as signed values and written as unsigned
+ * <p>Note that these are stored in memory as signed values and written as unsigned
* varints, which if negative, are 10 bytes long. If you know the data is likely
* to be negative, use "sint32".
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedInt32(long fieldId, int[] val) {
+ public void writePackedInt32(long fieldId, @Nullable int[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_INT32);
@@ -1099,7 +1126,8 @@
/**
* Write a single proto "int64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
public void writeInt64(long fieldId, long val) {
@@ -1119,7 +1147,8 @@
/**
* Write a single repeated proto "int64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedInt64(long fieldId, long val) {
@@ -1137,10 +1166,11 @@
/**
* Write a list of packed proto "int64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedInt64(long fieldId, long[] val) {
+ public void writePackedInt64(long fieldId, @Nullable long[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_INT64);
@@ -1168,7 +1198,8 @@
/**
* Write a single proto "uint32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeUInt32(long fieldId, int val) {
@@ -1188,7 +1219,8 @@
/**
* Write a single repeated proto "uint32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedUInt32(long fieldId, int val) {
@@ -1206,10 +1238,11 @@
/**
* Write a list of packed proto "uint32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedUInt32(long fieldId, int[] val) {
+ public void writePackedUInt32(long fieldId, @Nullable int[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_UINT32);
@@ -1237,7 +1270,8 @@
/**
* Write a single proto "uint64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
public void writeUInt64(long fieldId, long val) {
@@ -1257,7 +1291,8 @@
/**
* Write a single proto "uint64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedUInt64(long fieldId, long val) {
@@ -1275,10 +1310,11 @@
/**
* Write a single proto "uint64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedUInt64(long fieldId, long[] val) {
+ public void writePackedUInt64(long fieldId, @Nullable long[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_UINT64);
@@ -1306,7 +1342,8 @@
/**
* Write a single proto "sint32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeSInt32(long fieldId, int val) {
@@ -1326,7 +1363,8 @@
/**
* Write a single repeated proto "sint32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedSInt32(long fieldId, int val) {
@@ -1344,10 +1382,11 @@
/**
* Write a list of packed proto "sint32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedSInt32(long fieldId, int[] val) {
+ public void writePackedSInt32(long fieldId, @Nullable int[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_SINT32);
@@ -1375,7 +1414,8 @@
/**
* Write a single proto "sint64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
public void writeSInt64(long fieldId, long val) {
@@ -1395,7 +1435,8 @@
/**
* Write a single repeated proto "sint64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedSInt64(long fieldId, long val) {
@@ -1413,10 +1454,11 @@
/**
* Write a list of packed proto "sint64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedSInt64(long fieldId, long[] val) {
+ public void writePackedSInt64(long fieldId, @Nullable long[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_SINT64);
@@ -1443,7 +1485,8 @@
/**
* Write a single proto "fixed32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeFixed32(long fieldId, int val) {
@@ -1463,7 +1506,8 @@
/**
* Write a single repeated proto "fixed32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedFixed32(long fieldId, int val) {
@@ -1481,10 +1525,11 @@
/**
* Write a list of packed proto "fixed32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedFixed32(long fieldId, int[] val) {
+ public void writePackedFixed32(long fieldId, @Nullable int[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_FIXED32);
@@ -1507,7 +1552,8 @@
/**
* Write a single proto "fixed64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
public void writeFixed64(long fieldId, long val) {
@@ -1527,7 +1573,8 @@
/**
* Write a single repeated proto "fixed64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedFixed64(long fieldId, long val) {
@@ -1545,10 +1592,11 @@
/**
* Write a list of packed proto "fixed64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedFixed64(long fieldId, long[] val) {
+ public void writePackedFixed64(long fieldId, @Nullable long[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_FIXED64);
@@ -1570,7 +1618,8 @@
/**
* Write a single proto "sfixed32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeSFixed32(long fieldId, int val) {
@@ -1590,7 +1639,8 @@
/**
* Write a single repeated proto "sfixed32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedSFixed32(long fieldId, int val) {
@@ -1608,10 +1658,11 @@
/**
* Write a list of packed proto "sfixed32" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedSFixed32(long fieldId, int[] val) {
+ public void writePackedSFixed32(long fieldId, @Nullable int[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_SFIXED32);
@@ -1634,7 +1685,8 @@
/**
* Write a single proto "sfixed64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
public void writeSFixed64(long fieldId, long val) {
@@ -1654,7 +1706,8 @@
/**
* Write a single repeated proto "sfixed64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedSFixed64(long fieldId, long val) {
@@ -1672,10 +1725,11 @@
/**
* Write a list of packed proto "sfixed64" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, long)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedSFixed64(long fieldId, long[] val) {
+ public void writePackedSFixed64(long fieldId, @Nullable long[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_SFIXED64);
@@ -1698,7 +1752,8 @@
/**
* Write a single proto "bool" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, boolean)} instead.
+ * @hide
*/
@Deprecated
public void writeBool(long fieldId, boolean val) {
@@ -1719,7 +1774,8 @@
/**
* Write a single repeated proto "bool" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, boolean)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedBool(long fieldId, boolean val) {
@@ -1737,10 +1793,11 @@
/**
* Write a list of packed proto "bool" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, boolean)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedBool(long fieldId, boolean[] val) {
+ public void writePackedBool(long fieldId, @Nullable boolean[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_BOOL);
@@ -1767,10 +1824,11 @@
/**
* Write a single proto "string" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, String)} instead.
+ * @hide
*/
@Deprecated
- public void writeString(long fieldId, String val) {
+ public void writeString(long fieldId, @Nullable String val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_SINGLE | FIELD_TYPE_STRING);
@@ -1786,10 +1844,11 @@
/**
* Write a single repeated proto "string" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, String)} instead.
+ * @hide
*/
@Deprecated
- public void writeRepeatedString(long fieldId, String val) {
+ public void writeRepeatedString(long fieldId, @Nullable String val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_REPEATED | FIELD_TYPE_STRING);
@@ -1828,10 +1887,11 @@
/**
* Write a single proto "bytes" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, byte[])} instead.
+ * @hide
*/
@Deprecated
- public void writeBytes(long fieldId, byte[] val) {
+ public void writeBytes(long fieldId, @Nullable byte[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_SINGLE | FIELD_TYPE_BYTES);
@@ -1848,10 +1908,11 @@
/**
* Write a single repeated proto "bytes" type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, byte[])} instead.
+ * @hide
*/
@Deprecated
- public void writeRepeatedBytes(long fieldId, byte[] val) {
+ public void writeRepeatedBytes(long fieldId, @Nullable byte[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_REPEATED | FIELD_TYPE_BYTES);
@@ -1874,7 +1935,8 @@
/**
* Write a single proto enum type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeEnum(long fieldId, int val) {
@@ -1894,7 +1956,8 @@
/**
* Write a single repeated proto enum type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
public void writeRepeatedEnum(long fieldId, int val) {
@@ -1912,10 +1975,11 @@
/**
* Write a list of packed proto enum type field value.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, int)} instead.
+ * @hide
*/
@Deprecated
- public void writePackedEnum(long fieldId, int[] val) {
+ public void writePackedEnum(long fieldId, @Nullable int[] val) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_PACKED | FIELD_TYPE_ENUM);
@@ -1940,7 +2004,8 @@
* Returns a token which should be passed to endObject. Calls to endObject must be
* nested properly.
*
- * @deprecated Use #start() instead.
+ * @deprecated Use {@link #start(long)} instead.
+ * @hide
*/
@Deprecated
public long startObject(long fieldId) {
@@ -1953,7 +2018,8 @@
/**
* End a child object. Pass in the token from the correspoinding startObject call.
*
- * @deprecated Use #end() instead.
+ * @deprecated Use {@link #end(long)} instead.
+ * @hide
*/
@Deprecated
public void endObject(long token) {
@@ -1968,7 +2034,8 @@
* Returns a token which should be passed to endObject. Calls to endObject must be
* nested properly.
*
- * @deprecated Use #start() instead.
+ * @deprecated Use {@link #start(long)} instead.
+ * @hide
*/
@Deprecated
public long startRepeatedObject(long fieldId) {
@@ -1981,7 +2048,8 @@
/**
* End a child object. Pass in the token from the correspoinding startRepeatedObject call.
*
- * @deprecated Use #end() instead.
+ * @deprecated Use {@link #end(long)} instead.
+ * @hide
*/
@Deprecated
public void endRepeatedObject(long token) {
@@ -2064,12 +2132,13 @@
}
/**
- * Write an object that has already been flattend.
+ * Write an object that has already been flattened.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, byte[])} instead.
+ * @hide
*/
@Deprecated
- public void writeObject(long fieldId, byte[] value) {
+ public void writeObject(long fieldId, @Nullable byte[] value) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_SINGLE | FIELD_TYPE_MESSAGE);
@@ -2084,12 +2153,13 @@
}
/**
- * Write an object that has already been flattend.
+ * Write an object that has already been flattened.
*
- * @deprecated Use #write instead.
+ * @deprecated Use {@link #write(long, byte[])} instead.
+ * @hide
*/
@Deprecated
- public void writeRepeatedObject(long fieldId, byte[] value) {
+ public void writeRepeatedObject(long fieldId, @Nullable byte[] value) {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_REPEATED | FIELD_TYPE_MESSAGE);
@@ -2115,11 +2185,11 @@
}
/**
- * Validates that the fieldId providied is of the type and count from expectedType.
+ * Validates that the fieldId provided is of the type and count from expectedType.
*
- * The type must match exactly to pass this check.
+ * <p>The type must match exactly to pass this check.
*
- * The count must match according to this truth table to pass the check:
+ * <p>The count must match according to this truth table to pass the check:
*
* expectedFlags
* UNKNOWN SINGLE REPEATED PACKED
@@ -2129,7 +2199,7 @@
* REPEATED x false true false
* PACKED x false true true
*
- * @throws IllegalArgumentException if it is not.
+ * @throws {@link IllegalArgumentException} if it is not.
*
* @return The raw ID of that field.
*/
@@ -2201,7 +2271,7 @@
}
/**
- * Write a field tage to the stream.
+ * Write a field tag to the stream.
*/
public void writeTag(int id, int wireType) {
mBuffer.writeRawVarint32((id << FIELD_ID_SHIFT) | wireType);
@@ -2239,10 +2309,10 @@
* Finish the encoding of the data, and return a byte[] with
* the protobuf formatted data.
*
- * After this call, do not call any of the write* functions. The
+ * <p>After this call, do not call any of the write* functions. The
* behavior is undefined.
*/
- public byte[] getBytes() {
+ public @NonNull byte[] getBytes() {
compactIfNecessary();
return mBuffer.getBytes(mBuffer.getReadableSize());
@@ -2289,7 +2359,7 @@
}
/**
- * First compaction pass. Iterate through the data, and fill in the
+ * First compaction pass. Iterate through the data, and fill in the
* nested object sizes so the next pass can compact them.
*/
private int editEncodedSize(int rawSize) {
@@ -2416,10 +2486,10 @@
/**
* Write remaining data to the output stream. If there is no output stream,
* this function does nothing. Any currently open objects (i.e. ones that
- * have not had endObject called for them will not be written). Whether this
+ * have not had {@link #end(long)} called for them will not be written). Whether this
* writes objects that are closed if there are remaining open objects is
* undefined (current implementation does not write it, future ones will).
- * For now, can either call getBytes() or flush(), but not both.
+ * For now, can either call {@link #getBytes()} or {@link #flush()}, but not both.
*/
public void flush() {
if (mStream == null) {
@@ -2457,7 +2527,7 @@
/**
* Dump debugging data about the buffers with the given log tag.
*/
- public void dump(String tag) {
+ public void dump(@NonNull String tag) {
Log.d(tag, mBuffer.getDebugString());
mBuffer.dumpBuffers(tag);
}
diff --git a/core/java/android/util/proto/ProtoStream.java b/core/java/android/util/proto/ProtoStream.java
index 9e2e95a..4969d8a 100644
--- a/core/java/android/util/proto/ProtoStream.java
+++ b/core/java/android/util/proto/ProtoStream.java
@@ -16,28 +16,104 @@
package android.util.proto;
-import android.annotation.TestApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
/**
- * Abstract base class for both protobuf streams.
+ * Base utility class for protobuf streams.
*
- * Contains a set of useful constants and methods used by both
- * ProtoOutputStream and ProtoInputStream
+ * Contains a set of constants and methods used in generated code for
+ * {@link ProtoOutputStream}.
*
* @hide
*/
-@TestApi
-public abstract class ProtoStream {
+public class ProtoStream {
+ /**
+ * Number of bits to shift the field number to form a tag.
+ *
+ * <pre>
+ * // Reading a field number from a tag.
+ * int fieldNumber = tag >>> FIELD_ID_SHIFT;
+ *
+ * // Building a tag from a field number and a wire type.
+ * int tag = (fieldNumber << FIELD_ID_SHIFT) | wireType;
+ * </pre>
+ *
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final int FIELD_ID_SHIFT = 3;
+
+ /**
+ * Mask to select the wire type from a tag.
+ *
+ * <pre>
+ * // Reading a wire type from a tag.
+ * int wireType = tag & WIRE_TYPE_MASK;
+ *
+ * // Building a tag from a field number and a wire type.
+ * int tag = (fieldNumber << FIELD_ID_SHIFT) | wireType;
+ * </pre>
+ *
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final int WIRE_TYPE_MASK = (1 << FIELD_ID_SHIFT) - 1;
+
+ /**
+ * Mask to select the field id from a tag.
+ * @hide (not used by anything, and not actually useful, because you also want
+ * to shift when you mask the field id).
+ */
public static final int FIELD_ID_MASK = ~WIRE_TYPE_MASK;
+ /**
+ * Varint wire type code.
+ *
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final int WIRE_TYPE_VARINT = 0;
+
+ /**
+ * Fixed64 wire type code.
+ *
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final int WIRE_TYPE_FIXED64 = 1;
+
+ /**
+ * Length delimited wire type code.
+ *
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final int WIRE_TYPE_LENGTH_DELIMITED = 2;
+
+ /**
+ * Start group wire type code.
+ *
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final int WIRE_TYPE_START_GROUP = 3;
+
+ /**
+ * End group wire type code.
+ *
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final int WIRE_TYPE_END_GROUP = 4;
+
+ /**
+ * Fixed32 wire type code.
+ *
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final int WIRE_TYPE_FIXED32 = 5;
/**
@@ -51,32 +127,147 @@
*/
public static final long FIELD_TYPE_MASK = 0x0ffL << FIELD_TYPE_SHIFT;
+ /**
+ * Not a real wire type.
+ * @hide
+ */
public static final long FIELD_TYPE_UNKNOWN = 0;
+
+ /*
+ * The FIELD_TYPE_ constants are copied from
+ * external/protobuf/src/google/protobuf/descriptor.h directly, so no
+ * extra mapping needs to be maintained in this case.
+ */
+
/**
- * The types are copied from external/protobuf/src/google/protobuf/descriptor.h directly,
- * so no extra mapping needs to be maintained in this case.
+ * Field type code for double fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, double)
+ * ProtoOutputStream.write(long, double)} method.
*/
public static final long FIELD_TYPE_DOUBLE = 1L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for float fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, float)
+ * ProtoOutputStream.write(long, float)} method.
+ */
public static final long FIELD_TYPE_FLOAT = 2L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for int64 fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, long)
+ * ProtoOutputStream.write(long, long)} method.
+ */
public static final long FIELD_TYPE_INT64 = 3L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for uint64 fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, long)
+ * ProtoOutputStream.write(long, long)} method.
+ */
public static final long FIELD_TYPE_UINT64 = 4L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for int32 fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, int)
+ * ProtoOutputStream.write(long, int)} method.
+ */
public static final long FIELD_TYPE_INT32 = 5L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for fixed64 fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, long)
+ * ProtoOutputStream.write(long, long)} method.
+ */
public static final long FIELD_TYPE_FIXED64 = 6L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for fixed32 fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, int)
+ * ProtoOutputStream.write(long, int)} method.
+ */
+
+ /**
+ * Field type code for fixed32 fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, int)
+ * ProtoOutputStream.write(long, int)} method.
+ */
public static final long FIELD_TYPE_FIXED32 = 7L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for bool fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, boolean)
+ * ProtoOutputStream.write(long, boolean)} method.
+ */
public static final long FIELD_TYPE_BOOL = 8L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for string fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, String)
+ * ProtoOutputStream.write(long, String)} method.
+ */
public static final long FIELD_TYPE_STRING = 9L << FIELD_TYPE_SHIFT;
+
// public static final long FIELD_TYPE_GROUP = 10L << FIELD_TYPE_SHIFT; // Deprecated.
+
+ /**
+ * Field type code for message fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#start(long)
+ * ProtoOutputStream.start(long)} method.
+ */
public static final long FIELD_TYPE_MESSAGE = 11L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for bytes fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, byte[])
+ * ProtoOutputStream.write(long, byte[])} method.
+ */
public static final long FIELD_TYPE_BYTES = 12L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for uint32 fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, int)
+ * ProtoOutputStream.write(long, int)} method.
+ */
public static final long FIELD_TYPE_UINT32 = 13L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for enum fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, int)
+ * ProtoOutputStream.write(long, int)} method.
+ */
public static final long FIELD_TYPE_ENUM = 14L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for sfixed32 fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, int)
+ * ProtoOutputStream.write(long, int)} method.
+ */
public static final long FIELD_TYPE_SFIXED32 = 15L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for sfixed64 fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, long)
+ * ProtoOutputStream.write(long, long)} method.
+ */
public static final long FIELD_TYPE_SFIXED64 = 16L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for sint32 fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, int)
+ * ProtoOutputStream.write(long, int)} method.
+ */
public static final long FIELD_TYPE_SINT32 = 17L << FIELD_TYPE_SHIFT;
+
+ /**
+ * Field type code for sint64 fields. Used to build constants in generated
+ * code for use with the {@link ProtoOutputStream#write(long, long)
+ * ProtoOutputStream.write(long, long)} method.
+ */
public static final long FIELD_TYPE_SINT64 = 18L << FIELD_TYPE_SHIFT;
- protected static final String[] FIELD_TYPE_NAMES = new String[]{
+ private static final @NonNull String[] FIELD_TYPE_NAMES = new String[]{
"Double",
"Float",
"Int64",
@@ -100,19 +291,94 @@
//
// FieldId flags for whether the field is single, repeated or packed.
//
+ /**
+ * Bit offset for building a field id to be used with a
+ * <code>{@link ProtoOutputStream}.write(...)</code>.
+ *
+ * @see #FIELD_COUNT_MASK
+ * @see #FIELD_COUNT_UNKNOWN
+ * @see #FIELD_COUNT_SINGLE
+ * @see #FIELD_COUNT_REPEATED
+ * @see #FIELD_COUNT_PACKED
+ */
public static final int FIELD_COUNT_SHIFT = 40;
+
+ /**
+ * Bit mask for selecting the field count when reading a field id that
+ * is used with a <code>{@link ProtoOutputStream}.write(...)</code> method.
+ *
+ * @see #FIELD_COUNT_SHIFT
+ * @see #FIELD_COUNT_MASK
+ * @see #FIELD_COUNT_UNKNOWN
+ * @see #FIELD_COUNT_SINGLE
+ * @see #FIELD_COUNT_REPEATED
+ * @see #FIELD_COUNT_PACKED
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final long FIELD_COUNT_MASK = 0x0fL << FIELD_COUNT_SHIFT;
+ /**
+ * Unknown field count, encoded into a field id used with a
+ * <code>{@link ProtoOutputStream}.write(...)</code> method.
+ *
+ * @see #FIELD_COUNT_SHIFT
+ * @see #FIELD_COUNT_MASK
+ * @see #FIELD_COUNT_SINGLE
+ * @see #FIELD_COUNT_REPEATED
+ * @see #FIELD_COUNT_PACKED
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final long FIELD_COUNT_UNKNOWN = 0;
+
+ /**
+ * Single field count, encoded into a field id used with a
+ * <code>{@link ProtoOutputStream}.write(...)</code> method.
+ *
+ * @see #FIELD_COUNT_SHIFT
+ * @see #FIELD_COUNT_MASK
+ * @see #FIELD_COUNT_UNKNOWN
+ * @see #FIELD_COUNT_REPEATED
+ * @see #FIELD_COUNT_PACKED
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final long FIELD_COUNT_SINGLE = 1L << FIELD_COUNT_SHIFT;
+
+ /**
+ * Repeated field count, encoded into a field id used with a
+ * <code>{@link ProtoOutputStream}.write(...)</code> method.
+ *
+ * @see #FIELD_COUNT_SHIFT
+ * @see #FIELD_COUNT_MASK
+ * @see #FIELD_COUNT_UNKNOWN
+ * @see #FIELD_COUNT_SINGLE
+ * @see #FIELD_COUNT_PACKED
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final long FIELD_COUNT_REPEATED = 2L << FIELD_COUNT_SHIFT;
+
+ /**
+ * Repeated packed field count, encoded into a field id used with a
+ * <code>{@link ProtoOutputStream}.write(...)</code> method.
+ *
+ * @see #FIELD_COUNT_SHIFT
+ * @see #FIELD_COUNT_MASK
+ * @see #FIELD_COUNT_UNKNOWN
+ * @see #FIELD_COUNT_SINGLE
+ * @see #FIELD_COUNT_REPEATED
+ * @see <a href="https://developers.google.com/protocol-buffers/docs/encoding">Protobuf
+ * Encoding</a>
+ */
public static final long FIELD_COUNT_PACKED = 5L << FIELD_COUNT_SHIFT;
/**
* Get the developer-usable name of a field type.
*/
- public static String getFieldTypeString(long fieldType) {
+ public static @Nullable String getFieldTypeString(long fieldType) {
int index = ((int) ((fieldType & FIELD_TYPE_MASK) >>> FIELD_TYPE_SHIFT)) - 1;
if (index >= 0 && index < FIELD_TYPE_NAMES.length) {
return FIELD_TYPE_NAMES[index];
@@ -124,7 +390,7 @@
/**
* Get the developer-usable name of a field count.
*/
- public static String getFieldCountString(long fieldCount) {
+ public static @Nullable String getFieldCountString(long fieldCount) {
if (fieldCount == FIELD_COUNT_SINGLE) {
return "";
} else if (fieldCount == FIELD_COUNT_REPEATED) {
@@ -139,7 +405,7 @@
/**
* Get the developer-usable name of a wire type.
*/
- public static String getWireTypeString(int wireType) {
+ public static @Nullable String getWireTypeString(int wireType) {
switch (wireType) {
case WIRE_TYPE_VARINT:
return "Varint";
@@ -161,7 +427,7 @@
/**
* Get a debug string for a fieldId.
*/
- public static String getFieldIdString(long fieldId) {
+ public static @NonNull String getFieldIdString(long fieldId) {
final long fieldCount = fieldId & FIELD_COUNT_MASK;
String countString = getFieldCountString(fieldCount);
if (countString == null) {
@@ -218,29 +484,39 @@
/**
* Get the encoded tag size from the token.
+ *
+ * @hide
*/
public static int getTagSizeFromToken(long token) {
return (int) (0x7 & (token >> 61));
}
/**
- * Get whether this is a call to startObject (false) or startRepeatedObject (true).
+ * Get whether the token has the repeated bit set to true or false
+ *
+ * @hide
*/
public static boolean getRepeatedFromToken(long token) {
return (0x1 & (token >> 60)) != 0;
}
/**
- * Get the nesting depth of startObject calls from the token.
+ * Get the nesting depth from the token.
+ *
+ * @hide
*/
public static int getDepthFromToken(long token) {
return (int) (0x01ff & (token >> 51));
}
/**
- * Get the object ID from the token. The object ID is a serial number for the
+ * Get the object ID from the token.
+ *
+ * <p>The object ID is a serial number for the
* startObject calls that have happened on this object. The values are truncated
* to 9 bits, but that is sufficient for error checking.
+ *
+ * @hide
*/
public static int getObjectIdFromToken(long token) {
return (int) (0x07ffff & (token >> 32));
@@ -248,6 +524,8 @@
/**
* Get the location of the offset recorded in the token.
+ *
+ * @hide
*/
public static int getOffsetFromToken(long token) {
return (int) token;
@@ -255,8 +533,11 @@
/**
* Convert the object ID to the ordinal value -- the n-th call to startObject.
- * The object IDs start at -1 and count backwards, so that the value is unlikely
+ *
+ * <p>The object IDs start at -1 and count backwards, so that the value is unlikely
* to alias with an actual size field that had been written.
+ *
+ * @hide
*/
public static int convertObjectIdToOrdinal(int objectId) {
return (-1 & 0x07ffff) - objectId;
@@ -265,7 +546,7 @@
/**
* Return a debugging string of a token.
*/
- public static String token2String(long token) {
+ public static @NonNull String token2String(long token) {
if (token == 0L) {
return "Token(0)";
} else {
@@ -277,4 +558,9 @@
+ ')';
}
}
+
+ /**
+ * @hide
+ */
+ protected ProtoStream() {}
}
diff --git a/core/java/android/util/proto/ProtoUtils.java b/core/java/android/util/proto/ProtoUtils.java
index 03bf590..a71561b 100644
--- a/core/java/android/util/proto/ProtoUtils.java
+++ b/core/java/android/util/proto/ProtoUtils.java
@@ -24,12 +24,12 @@
/**
* This class contains a list of helper functions to write common proto in
* //frameworks/base/core/proto/android/base directory
+ * @hide
*/
public class ProtoUtils {
/**
* Dump AggStats to ProtoOutputStream
- * @hide
*/
public static void toAggStatsProto(ProtoOutputStream proto, long fieldId,
long min, long average, long max) {
@@ -42,7 +42,6 @@
/**
* Dump Duration to ProtoOutputStream
- * @hide
*/
public static void toDuration(ProtoOutputStream proto, long fieldId, long startMs, long endMs) {
final long token = proto.start(fieldId);
@@ -53,7 +52,6 @@
/**
* Helper function to write bit-wise flags to proto as repeated enums
- * @hide
*/
public static void writeBitWiseFlagsToProtoEnum(ProtoOutputStream proto, long fieldId,
int flags, int[] origEnums, int[] protoEnums) {
diff --git a/core/java/android/util/proto/TEST_MAPPING b/core/java/android/util/proto/TEST_MAPPING
index cf9f077..5b98741 100644
--- a/core/java/android/util/proto/TEST_MAPPING
+++ b/core/java/android/util/proto/TEST_MAPPING
@@ -2,6 +2,9 @@
"presubmit": [
{
"name": "ProtoInputStreamTests"
+ },
+ {
+ "name": "CtsProtoTestCases"
}
]
-}
\ No newline at end of file
+}
diff --git a/core/java/android/util/proto/package.html b/core/java/android/util/proto/package.html
index a636bd4..ef1125b 100644
--- a/core/java/android/util/proto/package.html
+++ b/core/java/android/util/proto/package.html
@@ -1,5 +1,5 @@
+<html>
<body>
Provides utility classes to export protocol buffers from the system.
-
-{@hide}
</body>
+</html>
\ No newline at end of file
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 1a6ec4e..b555d20 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -43,7 +43,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
/**
* Provides information about the size and density of a logical display.
@@ -382,6 +384,23 @@
/** @hide */
public static final int COLOR_MODE_DISPLAY_P3 = 9;
+ /** @hide **/
+ @IntDef(prefix = {"COLOR_MODE_"}, value = {
+ COLOR_MODE_INVALID,
+ COLOR_MODE_DEFAULT,
+ COLOR_MODE_BT601_625,
+ COLOR_MODE_BT601_625_UNADJUSTED,
+ COLOR_MODE_BT601_525,
+ COLOR_MODE_BT601_525_UNADJUSTED,
+ COLOR_MODE_BT709,
+ COLOR_MODE_DCI_P3,
+ COLOR_MODE_SRGB,
+ COLOR_MODE_ADOBE_RGB,
+ COLOR_MODE_DISPLAY_P3
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ColorMode {}
+
/**
* Indicates that when display is removed, all its activities will be moved to the primary
* display and the topmost activity should become focused.
@@ -960,6 +979,37 @@
}
/**
+ * Gets the supported wide color gamuts of this device.
+ *
+ * @return Supported WCG color spaces.
+ * @hide
+ */
+ public @ColorMode ColorSpace[] getSupportedWideColorGamut() {
+ synchronized (this) {
+ final ColorSpace[] defaultColorSpaces = new ColorSpace[0];
+ updateDisplayInfoLocked();
+ if (!isWideColorGamut()) {
+ return defaultColorSpaces;
+ }
+
+ final int[] colorModes = getSupportedColorModes();
+ final List<ColorSpace> colorSpaces = new ArrayList<>();
+ for (int colorMode : colorModes) {
+ // Refer to DisplayInfo#isWideColorGamut.
+ switch (colorMode) {
+ case COLOR_MODE_DCI_P3:
+ colorSpaces.add(ColorSpace.get(ColorSpace.Named.DCI_P3));
+ break;
+ case COLOR_MODE_DISPLAY_P3:
+ colorSpaces.add(ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
+ break;
+ }
+ }
+ return colorSpaces.toArray(defaultColorSpaces);
+ }
+ }
+
+ /**
* Gets the app VSYNC offset, in nanoseconds. This is a positive value indicating
* the phase offset of the VSYNC events provided by Choreographer relative to the
* display refresh. For example, if Choreographer reports that the refresh occurred
diff --git a/core/java/android/view/IPinnedStackController.aidl b/core/java/android/view/IPinnedStackController.aidl
index f1d152b..00edb3a 100644
--- a/core/java/android/view/IPinnedStackController.aidl
+++ b/core/java/android/view/IPinnedStackController.aidl
@@ -45,4 +45,17 @@
* {@param animationDuration} suggests the animation duration transitioning to PiP window.
*/
void startAnimation(in Rect destinationBounds, in Rect sourceRectHint, int animationDuration);
+
+ /**
+ * Notifies the controller to reset on bounds animation, if there is any.
+ * This could happen when screen rotation is happening and we need to notify the WM to reset
+ * any running bounds animation on the pinned stack.
+ * {@param bounds} here is the final destination bounds.
+ */
+ void resetBoundsAnimation(in Rect bounds);
+
+ /**
+ * Reports the current default and movement bounds to controller.
+ */
+ void reportBounds(in Rect defaultBounds, in Rect movementBounds);
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 48853bf..246a92c 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1377,9 +1377,8 @@
for (TargetInfo innerInfo : mti.getTargets()) {
labels.add(innerInfo.getResolveInfo().loadLabel(getPackageManager()));
}
- f = new ResolverTargetActionsDialogFragment(
- mti.getResolveInfo().loadLabel(getPackageManager()), name, mti.getTargets(),
- labels);
+ f = new ResolverTargetActionsDialogFragment(mti.getDisplayLabel(), name,
+ mti.getTargets(), labels);
} else {
f = new ResolverTargetActionsDialogFragment(
ti.getResolveInfo().loadLabel(getPackageManager()), name, pinned);
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 99bf93e..46025aa 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -32,14 +32,13 @@
// and not be reordered
int checkOperation(int code, int uid, String packageName);
int noteOperation(int code, int uid, String packageName, @nullable String featureId);
- int startOperation(IBinder token, int code, int uid, String packageName,
+ int startOperation(IBinder clientId, int code, int uid, String packageName,
@nullable String featureId, boolean startIfModeDefault);
@UnsupportedAppUsage
- void finishOperation(IBinder token, int code, int uid, String packageName,
+ void finishOperation(IBinder clientId, int code, int uid, String packageName,
@nullable String featureId);
void startWatchingMode(int op, String packageName, IAppOpsCallback callback);
void stopWatchingMode(IAppOpsCallback callback);
- IBinder getToken(IBinder clientToken);
int permissionToOpCode(String permission);
int checkAudioOperation(int code, int usage, int uid, String packageName);
void noteAsyncOp(@nullable String callingPackageName, int uid, @nullable String packageName,
diff --git a/core/java/com/android/internal/app/chooser/MultiDisplayResolveInfo.java b/core/java/com/android/internal/app/chooser/MultiDisplayResolveInfo.java
index 4c52411..55200c8 100644
--- a/core/java/com/android/internal/app/chooser/MultiDisplayResolveInfo.java
+++ b/core/java/com/android/internal/app/chooser/MultiDisplayResolveInfo.java
@@ -25,7 +25,6 @@
public class MultiDisplayResolveInfo extends DisplayResolveInfo {
List<DisplayResolveInfo> mTargetInfos = new ArrayList<>();
- String mPackageName;
// We'll use this DRI for basic presentation info - eg icon, name.
final DisplayResolveInfo mBaseInfo;
@@ -38,6 +37,12 @@
mTargetInfos.add(firstInfo);
}
+ @Override
+ public CharSequence getExtendedInfo() {
+ // Never show subtitle for stacked apps
+ return null;
+ }
+
/**
* Add another DisplayResolveInfo to the list included for this target.
*/
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index bc80197..c7ec2cd 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -136,6 +136,13 @@
}
/**
+ * Returns the same array or an empty one if it's null.
+ */
+ public static @NonNull <T> T[] emptyIfNull(@Nullable T[] items, Class<T> kind) {
+ return items != null ? items : emptyArray(kind);
+ }
+
+ /**
* Checks if given array is null or has zero elements.
*/
public static boolean isEmpty(@Nullable Collection<?> array) {
@@ -751,6 +758,42 @@
return result;
}
+ /**
+ * Returns an array containing elements from the given one that match the given predicate.
+ */
+ public static @Nullable <T> T[] filter(@Nullable T[] items,
+ @NonNull IntFunction<T[]> arrayConstructor,
+ @NonNull java.util.function.Predicate<T> predicate) {
+ if (isEmpty(items)) {
+ return items;
+ }
+
+ int matchesCount = 0;
+ int size = size(items);
+ for (int i = 0; i < size; i++) {
+ if (predicate.test(items[i])) {
+ matchesCount++;
+ }
+ }
+ if (matchesCount == 0) {
+ return items;
+ }
+ if (matchesCount == items.length) {
+ return items;
+ }
+ if (matchesCount == 0) {
+ return null;
+ }
+ T[] result = arrayConstructor.apply(matchesCount);
+ int outIdx = 0;
+ for (int i = 0; i < size; i++) {
+ if (predicate.test(items[i])) {
+ result[outIdx++] = items[i];
+ }
+ }
+ return result;
+ }
+
public static boolean startsWith(byte[] cur, byte[] val) {
if (cur == null || val == null) return false;
if (cur.length < val.length) return false;
diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java
index c1d129b..362bc92 100644
--- a/core/java/com/android/internal/util/MemInfoReader.java
+++ b/core/java/com/android/internal/util/MemInfoReader.java
@@ -91,7 +91,15 @@
* that are mapped in to processes.
*/
public long getCachedSizeKb() {
- return mInfos[Debug.MEMINFO_BUFFERS] + mInfos[Debug.MEMINFO_SLAB_RECLAIMABLE]
+ long kReclaimable = mInfos[Debug.MEMINFO_KRECLAIMABLE];
+
+ // Note: MEMINFO_KRECLAIMABLE includes MEMINFO_SLAB_RECLAIMABLE and ION pools.
+ // Fall back to using MEMINFO_SLAB_RECLAIMABLE in case of older kernels that do
+ // not include KReclaimable meminfo field.
+ if (kReclaimable == 0) {
+ kReclaimable = mInfos[Debug.MEMINFO_SLAB_RECLAIMABLE];
+ }
+ return mInfos[Debug.MEMINFO_BUFFERS] + kReclaimable
+ mInfos[Debug.MEMINFO_CACHED] - mInfos[Debug.MEMINFO_MAPPED];
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 7cd18a2..98ce8b0 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -141,6 +141,7 @@
"android_os_UEventObserver.cpp",
"android_os_VintfObject.cpp",
"android_os_VintfRuntimeInfo.cpp",
+ "android_os_incremental_IncrementalManager.cpp",
"android_net_LocalSocketImpl.cpp",
"android_net_NetUtils.cpp",
"android_service_DataLoaderService.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 3cde887..c41b19e 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -152,6 +152,7 @@
extern int register_android_os_MemoryFile(JNIEnv* env);
extern int register_android_os_SharedMemory(JNIEnv* env);
extern int register_android_service_DataLoaderService(JNIEnv* env);
+extern int register_android_os_incremental_IncrementalManager(JNIEnv* env);
extern int register_android_net_LocalSocketImpl(JNIEnv* env);
extern int register_android_net_NetworkUtils(JNIEnv* env);
extern int register_android_text_AndroidCharacter(JNIEnv *env);
@@ -1496,6 +1497,7 @@
REG_JNI(register_android_net_NetworkUtils),
REG_JNI(register_android_os_MemoryFile),
REG_JNI(register_android_os_SharedMemory),
+ REG_JNI(register_android_os_incremental_IncrementalManager),
REG_JNI(register_com_android_internal_os_ClassLoaderFactory),
REG_JNI(register_com_android_internal_os_Zygote),
REG_JNI(register_com_android_internal_os_ZygoteInit),
diff --git a/core/jni/android_os_incremental_IncrementalManager.cpp b/core/jni/android_os_incremental_IncrementalManager.cpp
new file mode 100644
index 0000000..698062a
--- /dev/null
+++ b/core/jni/android_os_incremental_IncrementalManager.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#define LOG_TAG "incremental_manager-jni"
+
+#include "core_jni_helpers.h"
+#include "incfs_ndk.h"
+#include "jni.h"
+#include "nativehelper/JNIHelp.h"
+
+#include <iterator>
+#include <memory>
+
+namespace android {
+
+static jboolean nativeIsIncrementalPath(JNIEnv* env,
+ jobject clazz,
+ jstring javaPath) {
+ ScopedUtfChars path(env, javaPath);
+ return (jboolean)IncFs_IsIncFsPath(path.c_str());
+}
+
+static const JNINativeMethod method_table[] = {
+ {"nativeIsIncrementalPath", "(Ljava/lang/String;)Z",
+ (void*)nativeIsIncrementalPath},
+};
+
+int register_android_os_incremental_IncrementalManager(JNIEnv* env) {
+ return jniRegisterNativeMethods(env, "android/os/incremental/IncrementalManager",
+ method_table, std::size(method_table));
+}
+
+} // namespace android
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index a46ad6d..738965e 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -37,6 +37,7 @@
"/apex/com.android.conscrypt/javalib/conscrypt.jar",
"/apex/com.android.ipsec/javalib/ike.jar",
"/apex/com.android.media/javalib/updatable-media.jar",
+ "/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar",
"/apex/com.android.os.statsd/javalib/framework-statsd.jar",
"/apex/com.android.sdkext/javalib/framework-sdkext.jar",
"/apex/com.android.telephony/javalib/telephony-common.jar",
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 039e458..b2a19cf 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -251,6 +251,9 @@
// ACTION: Create a Settings shortcut item.
ACTION_SETTINGS_CREATE_SHORTCUT = 829;
+ // ACTION: A tile in Settings information architecture is clicked
+ ACTION_SETTINGS_TILE_CLICK = 830;
+
// ACTION: Settings advanced button is expanded
ACTION_SETTINGS_ADVANCED_BUTTON_EXPAND = 834;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ee86c162..1165d2d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -307,6 +307,7 @@
<protected-broadcast android:name="android.net.nsd.STATE_CHANGED" />
<protected-broadcast android:name="android.nfc.action.ADAPTER_STATE_CHANGED" />
+ <protected-broadcast android:name="android.nfc.action.PREFERRED_PAYMENT_CHANGED" />
<protected-broadcast android:name="android.nfc.action.TRANSACTION_DETECTED" />
<protected-broadcast android:name="com.android.nfc.action.LLCP_UP" />
<protected-broadcast android:name="com.android.nfc.action.LLCP_DOWN" />
@@ -1629,6 +1630,14 @@
<permission android:name="android.permission.NETWORK_SETTINGS"
android:protectionLevel="signature|telephony" />
+ <!-- Allows holder to request bluetooth/wifi scan bypassing global "use location" setting and
+ location permissions.
+ <p>Not for use by third-party or privileged applications.
+ @hide
+ -->
+ <permission android:name="android.permission.RADIO_SCAN_WITHOUT_LOCATION"
+ android:protectionLevel="signature|companion" />
+
<!-- Allows SetupWizard to call methods in Networking services
<p>Not for use by any other third-party or privileged applications.
@SystemApi
@@ -1749,6 +1758,14 @@
<p>Protection level: normal
-->
<permission android:name="android.permission.NFC_TRANSACTION_EVENT"
+ android:protectionLevel="normal" />
+
+ <!-- Allows applications to receive NFC preferred payment service information.
+ <p>Protection level: normal
+ -->
+ <permission android:name="android.permission.NFC_PREFERRED_PAYMENT_INFO"
+ android:description="@string/permdesc_preferredPaymentInfo"
+ android:label="@string/permlab_preferredPaymentInfo"
android:protectionLevel="normal" />
<!-- @deprecated This permission used to allow too broad access to sensitive methods and all its
@@ -4715,6 +4732,12 @@
<permission android:name="android.permission.PEEK_DROPBOX_DATA"
android:protectionLevel="signature" />
+ <!-- @SystemApi Allows an application to access TV tuner HAL
+ <p>Not for use by third-party applications.
+ @hide -->
+ <permission android:name="android.permission.ACCESS_TV_TUNER"
+ android:protectionLevel="signature|privileged" />
+
<application android:process="system"
android:persistent="true"
android:hasCode="false"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 4acdeeb..c9c0615 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Die werkprofiel se administrasieprogram ontbreek of is korrup. Gevolglik is jou werkprofiel en verwante data uitgevee. Kontak jou administrateur vir bystand."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jou werkprofiel is nie meer op hierdie toestel beskikbaar nie"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Te veel wagwoordpogings"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrateur het toestel vir persoonlike gebruik afgestaan"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Toestel word bestuur"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Jou organisasie bestuur hierdie toestel en kan netwerkverkeer monitor. Tik vir besonderhede."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Jou toestel sal uitgevee word"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Laat die program toe om vaste uitsendings wat agterbly nadat die uitsending eindig, te stuur. Oormatige gebruik kan jou Android TV-toestel stadig of onstabiel maak omdat dit veroorsaak dat jou toestel te veel geheue gebruik."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Laat die program toe om taai uitsendings te stuur, wat agterbly nadat die uitsending klaar is. Oormatige gebruik kan die foon stadig of onstabiel maak deurdat dit te veel geheue gebruik."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"lees jou kontakte"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Laat die program toe om inligting oor jou kontakte wat op jou tablet gestoor is, te lees, insluitend die gereeldheid van oproepe wat jy gemaak het, e-posse wat jy gestuur het, of ander maniere waarop jy met spesifieke individue gekommunikeer het. Hierdie toestemming laat programme toe om jou kontakdata te stoor, en kwaadwillige programme kan moontlik kontakdata sonder jou kennis deel."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Laat die program toe om data te lees oor jou kontakte wat op jou Android TV-toestel geberg is, insluitend hoe gereeld jy spesifieke individue gebel, ge-e-pos of op ander maniere met hulle gekommunikeer het. Hierdie toestemming laat programme toe om jou kontakdata te stoor, én kwaadwillige programme kan kontakdata deel sonder dat jy dit weet."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Laat die program toe om inligting oor jou kontakte wat op jou foon gestoor is, te lees, insluitend die gereeldheid van oproepe wat jy gemaak het, e-posse wat jy gestuur het, of ander maniere waarop jy met spesifieke individue gekommunikeer het. Hierdie toestemming laat programme toe om jou kontakdata te stoor, en kwaadwillige programme kan moontlik kontakdata sonder jou kennis deel."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Laat die program toe om data te lees oor jou kontakte wat op jou tablet geberg is. Programme sal ook toegang hê tot die rekeninge op jou tablet wat kontakte geskep het. Dit kan rekeninge insluit wat geskep is deur programme wat jy geïnstalleer het. Hierdie toestemming laat programme toe om jou kontakdata te stoor, en kwaadwillige programme kan kontakdata deel sonder dat jy dit weet."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Laat die program toe om data te lees oor jou kontakte wat op jou Android TV-toestel geberg is. Programme sal ook toegang hê tot die rekeninge op jou Android TV-toestel wat kontakte geskep het. Dit kan rekeninge insluit wat geskep is deur programme wat jy geïnstalleer het. Hierdie toestemming laat programme toe om jou kontakdata te stoor, en kwaadwillige programme kan kontakdata deel sonder dat jy dit weet."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Laat die program toe om data te lees oor jou kontakte wat op jou foon geberg is. Programme sal ook toegang hê tot die rekeninge op jou foon wat kontakte geskep het. Dit kan rekeninge insluit wat geskep is deur programme wat jy geïnstalleer het. Hierdie toestemming laat programme toe om jou kontakdata te stoor, en kwaadwillige programme kan kontakdata deel sonder dat jy dit weet."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"verander jou kontakte"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Laat die program toe om data oor jou kontakte wat op jou tablet gestoor is te verander, insluitend die gereeldheid van oproepe wat jy gemaak het, e-posse wat jy gestuur het, of ander maniere waarop jy met spesifieke individue gekommunikeer het. Hierdie toestemming laat programme toe om kontakdata uit te vee."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Laat die program toe om die data oor jou kontakte wat op jou Android TV-toestel gestoor is, te verander – dit sluit in hoe gereeld jy spesifieke kontakte gebel, ge-e-pos of op ander maniere met hulle gekommunikeer het. Hierdie toestemming laat programme toe om kontakdata uit te vee."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Laat die program toe om data oor jou kontakte wat op jou foon gestoor is te verander, insluitend die gereeldheid waarop jy oproepe gemaak het, gee-pos het, of op ander maniere met spesifieke kontakte gekommunikeer het. Hierdie toestemming laat programme toe om kontakdata te skrap."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Laat die program toe om die data te wysig oor jou kontakte wat op jou tablet geberg is. Hierdie toestemming laat programme toe om kontakdata uit te vee."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Laat die program toe om die data te wysig oor jou kontakte wat op jou Android TV-toestel geberg is. Hierdie toestemming laat programme toe om kontakdata uit te vee."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Laat die program toe om die data te wysig oor jou kontakte wat op jou foon geberg is. Hierdie toestemming laat programme toe om kontakdata uit te vee."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"lees oproeprekord"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Hierdie program kan jou oproepgeskiedenis lees."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"skryf oproeprekord"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"Kry toegang tot ekstra liggingverskaffer-bevele"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Gee die program toegang tot ekstra liggingverskaffer-bevele. Dit kan die program dalk toelaat om in te meng met die werking van die GPS of ander liggingbronne."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"kry net op die voorgrond toegang tot presiese ligging"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Hierdie program kan jou presiese ligging kry net wanneer dit op die voorgrond is. Hierdie liggingdienste moet aangeskakel wees en op jou foon beskikbaar wees sodat die program hulle kan gebruik. Dit kan veroorsaak dat meer batterykrag gebruik word."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"kry benaderde ligging (netwerkgegrond) net op die voorgrond"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Hierdie program kan jou ligging kry op grond van netwerkhulpbronne soos selfoontorings en Wi-Fi-netwerke, maar net wanneer die program op die voorgrond is. Die program kan hierdie liggingdienste net gebruik as hulle aangeskakel is en op jou tablet beskikbaar is."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Hierdie program kan jou ligging kry op grond van netwerkhulpbronne soos selfoontorings en Wi-Fi-netwerke, maar net wanneer die program op die voorgrond is. Die program kan hierdie liggingdienste net gebruik as hulle aangeskakel is en op jou Android TV-toestel beskikbaar is."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Hierdie program kan jou ligging kry op grond van netwerkhulpbronne soos selfoontorings en Wi-Fi-netwerke, maar net wanneer die program op die voorgrond is. Die program kan hierdie liggingdienste net gebruik as hulle aangeskakel is en op jou foon beskikbaar is."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Hierdie program kan jou presiese ligging kry net wanneer dit op die voorgrond is. Liggingdienste moet aangeskakel wees en op jou toestel beskikbaar wees sodat die program hulle kan gebruik. Dit kan veroorsaak dat meer batterykrag gebruik word."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"kry benaderde ligging net op die voorgrond"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Hierdie program kan jou benaderde ligging net kry wanneer dit op die voorgrond is. Liggingdienste moet aangeskakel wees en op jou toestel beskikbaar wees sodat die program hulle kan gebruik."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"kry ligging op die agtergrond"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"As dit bo en behalwe toegang tot die benaderde of presiese ligging verleen word, kan die program die ligging kry terwyl dit op die agtergrond werk."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Hierdie program het toegang tot ligging terwyl dit op die agtergrond werk, asook voorgrondtoegang tot ligging."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"verander jou klankinstellings"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Laat die program toe om globale klankinstellings soos volume en watter luidspreker vir uitvoer gebruik word, te verander."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"neem klank op"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Laat die program toe om die opstelling van Bluetooth op die tablet te sien, en om verbindings met saamgebinde toestelle te maak en te aanvaar."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Laat die program toe om die opstelling van Bluetooth op jou Android TV-toestel te bekyk, en om verbindings met saamgebinde toestelle te maak en te aanvaar."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Laat die program toe om die opstelling van die Bluetooth op die foon te sien, en om verbindings met saamgebinde toestelle te maak en te aanvaar."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"beheer kortveldkommunikasie"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Laat die program toe om met kortveldkommunikasie- (NFC) merkers, kaarte en lesers te kommunikeer."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"deaktiveer jou skermslot"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Gekoppel aan <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Tik om lêers te bekyk"</string>
<string name="pin_target" msgid="8036028973110156895">"Speld vas"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Ontspeld"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Programinligting"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Begin tans demonstrasie …"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Dateer hierdie items op in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> en <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Stoor"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nee, dankie"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Nie nou nie"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nooit"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Dateer op"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Gaan voort"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"wagwoord"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Wissel verdeelde skerm"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Sluitskerm"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skermkiekie"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g>-program in opspringervenster."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> se onderskrifbalk."</string>
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index c6e55c3..972737d 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"የሥራ መገለጫ አስተዳዳሪ መተግበሪያው ወይም ይጎድላል ወይም ተበላሽቷል። በዚህ ምክንያት የሥራ መገለጫዎ እና ተዛማጅ ውሂብ ተሰርዘዋል። እርዳታን ለማግኘት አስተዳዳሪዎን ያነጋግሩ።"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"የሥራ መገለጫዎ ከዚህ በኋላ በዚህ መሣሪያ ላይ አይገኝም"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"በጣም ብዙ የይለፍ ቃል ሙከራዎች"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"አስተዳዳሪ መሣሪያዎን ለግል ጥቅም ትተውታል"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"መሣሪያው የሚተዳደር ነው"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"የእርስዎ ድርጅት ይህን መሣሪያ ያስተዳድራል፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል። ዝርዝሮችን ለማግኘት መታ ያድርጉ።"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"የእርስዎ መሣሪያ ይደመሰሳል"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"መተግበሪያው ስርጭቱ ከተጠናቀቀ በኋላ የሚቀሩ አጣባቂ ስርጭቶችን እንዲልክ ያስችለዋል። ከልክ በላይ መጠቀም የእርስዎን Android TV መሣሪያ ብዙ ማህደረ ትውስታን እንዲጠቀም በማድረግ ቀርፋፋ ወይም ያልተረጋጋ ሊያደርገው ይችላል።"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"መተግበሪያው ስርጭቱ ከተጠናቀቀ በኋላ የሚቀሩ አጣባቂ ስርጭቶችን እንዲልክ ይፈቅድለታል። ከልክ በላይ መጠቀም ስልኩ ብዙ ማህደረ ትውስታን እንዲጠቀም በማድረግ ቀርፋፋ ወይም ያልተረጋጋ ሊያደርገው ይችላል።"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"እውቂያዎችዎን ያንብቡ"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"መተግበሪያው በጡባዊ ተኮህ ስለተከማቹ ዕውቂያዎች ያሉትን ውሂቦች በሙሉ፤ ጥሪ ያደረግክበትን፣ ኢሜይል የላክበትን ወይም ከተወሰኑ ግለሰቦች ጋር በሌላ መንገድ የተገናኘህበትን ድግምግሞሽ ጨምሮ፣ እንዲያነብ ይፈቅድለታል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብህን እንዲያስቀምጡ የሚፈቅድላቸው ሲሆን ተንኮል አዘል መተግበሪያዎች የእውቂያህን ውሂብ ሳታውቀው ሊያጋሩት ይችላሉ።"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"መተግበሪያው ከተወሰኑ ግለሰቦች ጋር የተደዋወሉበት፣ ኢሜይል የተላላኩበት ወይም የተገናኙበት ተደጋጋሚነትም ጨምሮ በእርስዎ Android TV ላይ ስለተከማቹ እውቂያዎች እንዲያነብ ያስችለዋል። ይህ ፍቃድ መተግበሪያዎች የእውቂያ ውሂብዎን እንዲያስቀምጥ ያስችላቸዋል፣ እና ተንኮል-አዘል መተግበሪያዎች የእውቂያ ውሂብ ያለእውቀትዎ ሊያጋሩ ይችላሉ።"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"መተግበሪያው በስልክዎ ስለተከማቹ ዕውቂያዎች ያሉትን ውሂቦች በሙሉ፤ ጥሪ ያደረጉበትን፣ ኢሜይል የላኩበትን ወይም ከተወሰኑ ግለሰቦች ጋር በሌላ መንገድ የተገናኙበትን ድግምግሞሽ ጨምሮ፣ እንዲያነብ ይፈቅድለታል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብዎን እንዲያስቀምጡ የሚፈቅድላቸው ሲሆን ተንኮል አዘል መተግበሪያዎች የእውቂያዎን ውሂብ ሳያውቁት ሊያጋሩት ይችላሉ።"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"መተግበሪያው በእርስዎ ጡባዊ ላይ ስለተከማቹ ዕውቂያዎችዎ ያለ ውሂብ እንዲያነብብ ያስችለዋል። መተግበሪያዎች እንዲሁም በእርስዎ ጡባዊ ላይ እውቂያዎችን የፈጠሩ የመለያዎች መዳረሻ ይኖራቸዋል። ይህ እርስዎ በጫኗቸው መተግበሪያዎች የተፈጠሩ መለያዎችን ሊያካትት ይችላል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብዎን እንዲያስቀምጡ የሚፈቅድላቸው ሲሆን ተንኮል-አዘል መተግበሪያዎች የእውቂያዎን ውሂብ ሳያውቁት ሊያጋሩት ይችላሉ።"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"መተግበሪያው በእርስዎ የAndroid TV መሣሪያ ላይ ስለተከማቹ እውቂያዎችዎ ያለ ውሂብን እንዲቀይር ያስችለዋል። መተግበሪያዎች እንዲሁም በእርስዎ የAndroid TV መሣሪያ ላይ እውቂያዎችን የፈጠሩ የመለያዎች መዳረሻ ይኖራቸዋል። ይህ እርስዎ በጫኗቸው መተግበሪያዎች የተፈጠሩ መለያዎችን ሊያካትት ይችላል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብዎን እንዲያስቀምጡ የሚፈቅድላቸው ሲሆን ተንኮል-አዘል መተግበሪያዎች የእውቂያዎን ውሂብ ሳያውቁት ሊያጋሩት ይችላሉ።"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"መተግበሪያው በእርስዎ ስልክ ላይ ስለተከማቹ ዕውቂያዎችዎ ያለ ውሂብ እንዲያነብብ ያስችለዋል። መተግበሪያዎች እንዲሁም በእርስዎ ስልክ ላይ እውቂያዎችን የፈጠሩ የመለያዎች መዳረሻ ይኖራቸዋል። ይህ እርስዎ በጫኗቸው መተግበሪያዎች የተፈጠሩ መለያዎችን ሊያካትት ይችላል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብዎን እንዲያስቀምጡ የሚፈቅድላቸው ሲሆን ተንኮል-አዘል መተግበሪያዎች የእውቂያዎን ውሂብ ሳያውቁት ሊያጋሩት ይችላሉ።"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"ዕውቂያዎችዎን ያስተካክሉ"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"መተግበሪያው በጡባዊ ቱኮህ ስለተከማቹ የዕውቂያዎችህ ውሂብ በሙሉ፤ ጥሪ ያደረግክበትን፣ ኢሜይል የላክበትን ወይም ከተወሰኑ እውቂያዎች ጋር በሌላ መንገድ የተገናኘህበትን ድግምግሞሽ ጨምሮ፣ እንዲያስተካክል ይፈቅድለታል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብ እንዲሰርዙ ይፈቅድላቸዋል።"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"መተግበሪያው ከተወሰኑ እውቂያዎች ጋር የሚደዋወሉበት፣ ኢሜይል የሚላላኩበት ወይም የሚገናኙበት ተደጋጋሚነትም ጨምሮ በእርስዎ Android TV ላይ ስለተከማቹ ዕውቂያዎችዎ ያለ ውሂብ እንዲቀይር ያስችለዋል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብ እንዲሰርዙ ያስችላቸዋል።"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"መተግበሪያው በስልክዎ ስለተከማቹ የዕውቂያዎችዎ ውሂብ በሙሉ፤ ጥሪ ያደረጉበትን፣ ኢሜይል የላኩበትን ወይም ከተወሰኑ እውቂያዎች ጋር በሌላ መንገድ የተገናኙበትን ድግምግሞሽ ጨምሮ፣ እንዲያስተካክል ይፈቅድለታል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብ እንዲሰርዙ ይፈቅድላቸዋል።"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"መተግበሪያው በእርስዎ ጡባዊ ላይ ስለተከማቹ እውቂያዎችዎ ያለ ውሂብን እንዲቀይር ያስችለዋል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብን እንዲሰርዙ ያስችላቸዋል።"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"መተግበሪያው በእርስዎ የAndroid TV መሣሪያ ላይ ስለተከማቹ የዕውቂያዎች እንዲቀይር ይፈቅድለታል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብን እንዲሰርዙ ያስችላቸዋል።"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"መተግበሪያው በእርስዎ ስልክ ላይ ስለተከማቹ እውቂያዎችዎ ያለ ውሂብን እንዲቀይር ያስችለዋል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብን እንዲሰርዙ ያስችላቸዋል።"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"የጥሪ ምዝግብ ማስታወሻን ያንብቡ"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"ይህ መተግበሪያ የእርስዎን የጥሪ ታሪክ ማንበብ ይችላል።"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"የጥሪ ምዝግብ ማስታወሻን ፃፍ"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"ተጨማሪ ሥፍራ አቅራቢ ትዕዛዞችን ድረስ።"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"መተግበሪያው ተጨማሪ የአካባቢ አቅራቢ ትእዛዞችን እንዲደርስ ይፈቅድለታል። ይሄ መተግበሪያው በጂፒኤስ ወይም ሌላ የአካባቢ ምንጮች ስራ ላይ ጣልቃ እንዲገባ ሊፈቅድለት ይችላል።"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"መዳረሻ ከፊት ለፊት ብቻ ትክክለኛ ነው"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"ይህ መተግበሪያ ከፊት ላይ ሆኖ ሲበራ ብቻ ትክክለኛውን መገኛ አካባቢ ማግኘት ይችላል። እነዚህ የመገኛ አካባቢ አገልግሎቶች መተግበሪያው መጠቀም እንዲችል ሊበሩ እና በእርስዎ ስልክ ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"ግምታዊ አካባቢ (በአውታረ መረብ ላይ የተመሠረተ) ከፊት ላይ ሲሆን ብቻ መድረስ"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"ይህ መተግበሪያ እንደ የሕዋስ ማማዎች እና የWi-Fi አውታረ መረቦች ባሉ የአውታረ መረብ ምንጮች ላይ በመመስረት የእርስዎን አካባቢ ማግኘት ይችላል፣ ነገር ግን መተግበሪያው ከፊት ሲሆን ብቻ። እነዚህ የአካባቢ አገልግሎቶች መተግበሪያው መጠቀም እንዲችል ሊበሩ እና በእርስዎ ጡባዊ ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"ይህ መተግበሪያ እንደ የሕዋስ ማማዎች እና የWi-Fi አውታረ መረቦች ባሉ የአውታረ መረብ ምንጮች ላይ በመመስረት የእርስዎን አካባቢ ማግኘት ይችላል፣ ነገር ግን መተግበሪያው ከፊት ሲሆን ብቻ። እነዚህ የአካባቢ አገልግሎቶች መተግበሪያው መጠቀም እንዲችል ሊበሩ እና በእርስዎ Android TV መሣሪያ ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"ይህ መተግበሪያ እንደ የሕዋስ ማማዎች እና የWi-Fi አውታረ መረቦች ባሉ የአውታረ መረብ ምንጮች ላይ በመመስረት የእርስዎን አካባቢ ማግኘት ይችላል፣ ነገር ግን መተግበሪያው ከፊት ሲሆን ብቻ። እነዚህ የአካባቢ አገልግሎቶች መተግበሪያው መጠቀም እንዲችል ሊበሩ እና በእርስዎ ስልክ ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"ይህ መተግበሪያ ከፊት ላይ ሆኖ ሲበራ ብቻ ትክክለኛውን አካባቢዎ ማግኘት ይችላል። መተግበሪያው የአካባቢ አገልግሎቶች መጠቀም እንዲችል ሊበሩ እና በእርስዎ መሣሪያ ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"ከፊት ለፊት ብቻ ግምታዊ አካባቢን ድረስ"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"ይህ መተግበሪያ ግምታዊ አካባቢዎን ማግኘት የሚችለው ከፊት ሲሆን ብቻ ነው። መተግበሪያው የአካባቢ አገልግሎቶች መጠቀም እንዲችል ሊበሩ እና በእርስዎ መሣሪያ ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"አካባቢን በበስተጀርባ ድረስ"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"ይህ ከግምታዊ ወይም ትክክለኛ አካባቢ በተጨማሪ ከተሰጠ መተግበሪያው በበስተጀርባ እያሄደ ሳለ አካባቢውን መድረስ ይችላል።"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"ይህ መተግበሪያ ከፊት የአካባቢ መዳረሻ በተጨማሪም ከበስተጀርባ እያሄደ ሳለ አካባቢን መድረስ ይችላል።"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"የድምፅ ቅንብሮችን ለውጥ"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"መተግበሪያው አንደ የድምጽ መጠን እና ለውጽአት የትኛውን የድምጽ ማጉያ ጥቅም ላይ እንደዋለ የመሳሰሉ ሁለንተናዊ የድምጽ ቅንብሮችን እንዲያስተካክል ይፈቅድለታል።"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ኦዲዮ ይቅዱ"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"መተግበሪያው በጡባዊ ተኮው ላይ ያለውን የብሉቱዝ ውቅር እንዲያይ እና ከተጣመሩ መሳሪያዎች ጋር ግንኙነቶችን እንዲያደርግና እንዲቀበል ይፈቅድለታል።"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"በእርስዎ የ Android TV መሣሪያ የብሉቱዝ ውቅረት ለማየት፣ እና ከተጣመረው መሣሪያ ጋር ግንኙነት ለመቀበል እንዲችል ለመተግበሪያው ይፈቅዳል።"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"መተግበሪያው በስልኩ ላይ ያለውን የብሉቱዝ ውቅር እንዲያይ እና ከተጣመሩ መሳሪያዎች ጋር ግንኙነቶችን እንዲያደርግና እንዲቀበል ይፈቅድለታል።"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ቅርብ የግኑኙነትመስክ (NFC) ተቆጣጠር"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"ከቅርብ ግኑኙነት መስክ (NFC) መለያዎች፣ ካርዶች እና አንባቢ ጋር ለማገናኘት ለመተግበሪያው ይፈቅዳሉ።"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"የማያ ገጽዎን መቆለፊያ ያሰናክሉ"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"ከ<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ጋር ተገናኝቷል"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ፋይሎችን ለመመልከት መታ ያድርጉ"</string>
<string name="pin_target" msgid="8036028973110156895">"ፒን"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"ንቀል"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"የመተግበሪያ መረጃ"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ማሳያን በማስጀመር ላይ…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"እነዚህ ንጥሎች በ"<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ውስጥ ይዘመኑ፦ <xliff:g id="TYPE_0">%1$s</xliff:g>፣ <xliff:g id="TYPE_1">%2$s</xliff:g> እና <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"አስቀምጥ"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"አይ፣ አመሰግናለሁ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"አሁን አይደለም"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"በጭራሽ"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"አዘምን"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"ቀጥል"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"የይለፍ ቃል"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"የተከፈለ ማያን ቀያይር"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"የማያ ገጽ ቁልፍ"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ቅጽበታዊ ገጽ እይታ"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"የ<xliff:g id="APP_NAME">%1$s</xliff:g> መተግበሪያ በብቅ-ባይ መስኮት ውስጥ።"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"የ<xliff:g id="APP_NAME">%1$s</xliff:g> የሥዕል ገላጭ ጽሑፍ አሞሌ።"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 609b77e..839a336 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -196,8 +196,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"تطبيق المشرف للملف الشخصي للعمل مفقود أو تالف لذا تم حذف الملف الشخصي للعمل والبيانات ذات الصلة. اتصل بالمشرف للحصول على المساعدة."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"لم يعد ملفك الشخصي للعمل متاحًا على هذا الجهاز"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"تم إجراء محاولات كثيرة جدًا لإدخال كلمة المرور"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"تنازل المشرف عن الجهاز للاستخدام الشخصي"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"تتم إدارة الجهاز"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"تدير مؤسستك هذا الجهاز ويمكنها مراقبة حركة بيانات الشبكة. يمكنك النقر للحصول على تفاصيل."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"سيتم محو بيانات جهازك."</string>
@@ -393,13 +392,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"للسماح للتطبيق بإرسال مواد بث ثابتة، والتي تظل متوفرة بعد انتهاء البث. وقد يؤدي الاستخدام المفرط لهذا التطبيق إلى حدوث بطء أو عدم استقرار في جهاز Android TV من خلال جعل الجهاز يستخدم قدرًا كبيرًا جدًا من الذاكرة."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"للسماح للتطبيق بإرسال مجموعات بث مستمرة، والتي تظل بعد انتهاء البث. قد يؤدي الاستخدام بكثرة إلى حدوث بطء أو عدم استقرار في الهاتف من خلال التسبب في استخدام الهاتف لمساحة كبيرة للغاية من الذاكرة."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"قراءة جهات الاتصال"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"للسماح للتطبيق بقراءة بيانات حول جهات الاتصال المخزنة على الجهاز اللوحي، بما في ذلك مدى تكرار اتصالك بأفراد بعينهم أو مراسلتهم عبر البريد الإلكتروني أو التواصل معهم بطرق أخرى خلافًا لذلك. ويتيح هذا الإذن للتطبيقات حفظ بيانات جهات الاتصال، وقد تشارك التطبيقات الضارة بيانات جهات الاتصال بدون معرفتك."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"للسماح للتطبيق بقراءة البيانات حول جهات الاتصال المخزّنة على جهاز Android TV، بما في ذلك مدى تكرار اتصالك بأفراد بعينهم أو مراسلتهم عبر البريد الإلكتروني أو التواصل معهم بطرق أخرى. ويتيح هذا الإذن للتطبيقات إمكانية حفظ بيانات جهة الاتصال، وقد تشارك التطبيقات الضارة بيانات جهة الاتصال بدون علمك."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"للسماح للتطبيق بقراءة بيانات حول جهات الاتصال المخزنة على الهاتف، بما في ذلك مدى تكرار اتصالك بأفراد بعينهم أو مراسلتهم عبر البريد الإلكتروني أو التواصل معهم بطرق أخرى خلافًا لذلك. ويتيح هذا الإذن للتطبيقات حفظ بيانات جهات الاتصال، وقد تشارك التطبيقات الضارة بيانات جهات الاتصال بدون معرفتك."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"يسمح هذا الإذن للتطبيق بقراءة بيانات حول جهات الاتصال المخزّنة على جهازك اللوحي. ويمكن للتطبيقات أيضًا الوصول إلى الحسابات التي تم إنشاء جهات الاتصال من خلالها على جهازك اللوحي. ويمكن أن يشمل ذلك الحسابات التي أنشأتها التطبيقات التي ثبتّها. ويتيح هذا الإذن للتطبيقات حفظ بيانات جهة الاتصال، وقد تشارك التطبيقات الضارة بيانات جهة الاتصال بدون علمك."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"يسمح هذا الإذن للتطبيق بقراءة بيانات حول جهات الاتصال المخزّنة على جهاز Android TV. ويمكن للتطبيقات أيضًا الوصول إلى الحسابات التي تم إنشاء جهات الاتصال من خلالها على جهاز Android TV. ويمكن أن يشمل ذلك الحسابات التي أنشأتها التطبيقات التي ثبتّها. ويتيح هذا الإذن للتطبيقات حفظ بيانات جهة الاتصال، وقد تشارك التطبيقات الضارة بيانات جهة الاتصال بدون علمك."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"يسمح هذا الإذن للتطبيق بقراءة بيانات حول جهات الاتصال المخزّنة على هاتفك. ويمكن للتطبيقات أيضًا الوصول إلى الحسابات التي تم إنشاء جهات الاتصال من خلالها على هاتفك. ويمكن أن يشمل ذلك الحسابات التي أنشأتها التطبيقات التي ثبتّها. ويتيح هذا الإذن للتطبيقات حفظ بيانات جهة الاتصال، وقد تشارك التطبيقات الضارة بيانات جهة الاتصال بدون علمك."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"تعديل جهات الاتصال"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"للسماح للتطبيق بتعديل البيانات حول جهات الاتصال المخزنة على جهازك اللوحي، بما في ذلك مدى تكرار اتصالك بجهات اتصال بعينها أو مراسلتها عبر البريد الإلكتروني أو التواصل معها بأية طريقة أخرى خلافًا لذلك. وقد يتيح هذا الإذن للتطبيقات حذف بيانات جهات الاتصال."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"للسماح للتطبيق بتعديل البيانات حول جهات الاتصال المخزّنة على جهاز Android TV، بما في ذلك مدى تكرار اتصالك بجهات اتصال بعينها أو مراسلتها عبر البريد الإلكتروني أو التواصل معها بطرق أخرى. ويتيح هذا الإذن للتطبيقات إمكانية حذف بيانات جهات الاتصال."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"للسماح للتطبيق بتعديل البيانات حول جهات الاتصال المخزنة على هاتفك، بما في ذلك مدى تكرار اتصالك بجهات اتصال بعينها أو مراسلتها عبر البريد الإلكتروني أو التواصل معها بأية طريقة أخرى خلافًا لذلك. وقد يتيح هذا الإذن للتطبيقات حذف بيانات جهات الاتصال."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"يسمح هذا الإذن للتطبيق بتعديل البيانات حول جهات الاتصال المخزّنة على جهازك اللوحي. ويسمح هذا الإذن للتطبيقات بحذف بيانات جهات الاتصال."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"يسمح هذا الإذن للتطبيق بتعديل البيانات حول جهات الاتصال المخزّنة على جهاز Android TV. ويسمح هذا الإذن للتطبيقات بحذف بيانات جهات الاتصال."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"يسمح هذا الإذن للتطبيق بتعديل البيانات حول جهات الاتصال المخزّنة على هاتفك. ويسمح هذا الإذن للتطبيقات بحذف بيانات جهات الاتصال."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"قراءة سجل المكالمات"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"يمكن لهذا التطبيق قراءة سجل المكالمات."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"كتابة سجل المكالمات"</string>
@@ -419,13 +418,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"الدخول إلى المزيد من أوامر موفر الموقع"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"للسماح للتطبيق بالدخول إلى أوامر إضافية لموفر الموقع. قد يتيح هذا للتطبيق التداخل مع تشغيل تقنية نظام تحديد المواقع العالمي (GPS) أو مصادر الموقع الأخرى."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"الوصول إلى الموقع الجغرافي الدقيق في الواجهة الأمامية فقط"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"لا يمكن لهذا التطبيق معرفة موقعك الجغرافي بالضبط إلا عندما يعمل في الخلفية. ويجب تفعيل خدمات الموقع الجغرافي هذه وأن تكون متاحة على الهاتف حتى يتمكن التطبيق من استخدامها. وقد يؤدي هذا إلى زيادة استهلاك طاقة البطارية."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"الوصول إلى الموقع الجغرافي التقريبي (بالاعتماد على الشبكة) في الخلفية فقط"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"يمكن لهذا التطبيق معرفة موقعك مستعينًا بمصادر الشبكات مثل الأبراج الخلوية وشبكات Wi-Fi ولكن يجب أن يعمل في الخلفية. ويجب تفعيل خدمات المواقع هذه وتوفّرها على جهازك اللوحي كي يتمكن التطبيق من استخدامها."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"يمكن لهذا التطبيق معرفة موقعك الجغرافي مستعينًا بمصادر الشبكات مثل الأبراج الخلوية وشبكات Wi-Fi، ولكن بشرط أن يعمل التطبيق في الواجهة الأمامية. ويجب تفعيل \"خدمات الموقع الجغرافي\" هذه وتوفّرها على جهاز Android TV لكي يتمكّن التطبيق من استخدامها."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"يمكن لهذا التطبيق معرفة موقعك مستعينًا بمصادر الشبكات مثل الأبراج الخلوية وشبكات Wi-Fi ولكن يجب أن يعمل في الخلفية. ويجب تفعيل خدمات المواقع هذه وتوفّرها على هاتفك كي يتمكن التطبيق من استخدامها."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"لا يمكن لهذا التطبيق معرفة موقعك الجغرافي بالضبط عندما يعمل في الخلفية. ويجب تفعيل خدمات الموقع الجغرافي وأن تكون متاحة على جهازك حتى يتمكن التطبيق من استخدامها. وقد يؤدي هذا إلى زيادة استهلاك طاقة البطارية."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"الوصول إلى الموقع الجغرافي التقريبي في الواجهة الأمامية فقط"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"لا يمكن لهذا التطبيق معرفة موقعك الجغرافي التقريبي إذا كان يعمل في الخلفية. ويجب تفعيل خدمات الموقع الجغرافي وأن تكون متاحة على جهازك حتى يتمكن التطبيق من استخدامها."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"الوصول إلى الموقع الجغرافي في الخلفية"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"إذا تمّ منح إذن التطبيق هذا بالإضافة إلى الموقع الجغرافي التقريبي أو الدقيق، يمكن للتطبيق الوصول إلى الموقع الجغرافي أثناء تشغيله في الخلفية."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"يمكن لهذا التطبيق الوصول إلى الموقع الجغرافي أثناء عمله في الخلفية، بالإضافة إلى إمكانية وصوله للموقع الجغرافي أثناء عمله في الواجهة الأمامية."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"تغيير إعداداتك الصوتية"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"للسماح للتطبيق بتعديل إعدادات الصوت العامة مثل مستوى الصوت وأي السماعات يتم استخدامها للاستماع."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"تسجيل الصوت"</string>
@@ -506,6 +503,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"للسماح للتطبيق بعرض تهيئة البلوتوث على الجهاز اللوحي وإجراء اتصالات وقبولها مع الأجهزة المقترنة."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"للسماح للتطبيق بعرض بيانات ضبط البلوتوث على جهاز Android TV وإجراء اتصالات مع الأجهزة المقترنة وقبولها."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"للسماح للتطبيق بعرض تهيئة البلوتوث على الهاتف وإجراء اتصالات وقبولها مع الأجهزة المقترنة."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"التحكم في اتصال الحقل القريب"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"للسماح للتطبيق بالاتصال بعلامات الاتصال قريب المدى (NFC)، والبطاقات وبرامج القراءة."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"إيقاف قفل الشاشة"</string>
@@ -1990,7 +1991,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"تم الاتصال بـ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"انقر لعرض الملفات"</string>
<string name="pin_target" msgid="8036028973110156895">"تثبيت"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"إزالة تثبيت"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"معلومات عن التطبيق"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"جارٍ بدء العرض التوضيحي…"</string>
@@ -2037,6 +2042,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"هل تريد تحديث هذه العناصر في "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g> و<xliff:g id="TYPE_1">%2$s</xliff:g> و<xliff:g id="TYPE_2">%3$s</xliff:g>؟"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"حفظ"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"لا، شكرًا"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"ليس الآن"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"أبدًا"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"تعديل"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"متابعة"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"كلمة مرور"</string>
@@ -2136,5 +2143,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"تبديل \"تقسيم الشاشة\""</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"شاشة القفل"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"لقطة شاشة"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> في نافذة منبثقة"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"شريط الشرح لتطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 091b563f..a9529db 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"কৰ্মস্থানৰ প্ৰ\'ফাইলৰ প্ৰশাসক এপ্ নাই বা ব্যৱহাৰযোগ্য হৈ থকা নাই। যাৰ ফলত আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইল আৰু ইয়াৰ লগত জড়িত অন্য ডেটাসমূহ মচা হৈছে। সহায়ৰ বাবে আপোনাৰ প্ৰশাসকৰ সৈতে সম্পর্ক কৰক।"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইল এই ডিভাইচটোত আৰু উপলব্ধ নহয়"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"বহুতবাৰ ভুলকৈ পাছৱৰ্ড দিয়া হৈছে"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"প্ৰশাসকে ডিভাইচটো ব্যক্তিগত ব্যৱহাৰৰ বাবে বাজেয়প্ত কৰিছে"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"পৰিচালিত ডিভাইচ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"আপোনাৰ প্ৰতিষ্ঠানটোৱে এই ডিভাইচটো পৰিচালনা কৰে আৰু ই নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ কৰিব পাৰে। সবিশেষ জানিবলৈ টিপক।"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"আপোনাৰ ডিভাইচৰ ডেটা মচা হ\'ব"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"এপ্টোক ব্ৰ’ডকাষ্ট শেষ হোৱাৰ পাছত বাকী থকা ষ্টিকী ব্ৰ’ডকাষ্টবোৰ পঠিয়াবলৈ অনুমতি দিয়ে। ইয়াক অত্যধিক ব্যৱহাৰ কৰিলে আপোনাৰ Android TV ডিভাইচটোক অতি বেছি পৰিমাণৰ মেম’ৰী খৰচ কৰাই লেহেমীয়া অথবা অস্থিৰ কৰিব পাৰে।"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"সম্প্ৰচাৰৰ শেষত বাকী ৰোৱা ষ্টিকী ব্ৰ\'ডকাষ্টবোৰ প্ৰেৰণ কৰিবলৈ এপক অনুমতি দিয়ে। ইয়াক অত্য়ধিক ব্যৱহাৰ কৰাৰ ফলত মেম\'ৰি অধিক খৰচ হোৱাৰ বাবে ফ\'নটো লেহেমীয়া বা অস্থিৰ হৈ পৰে।"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"নিজৰ সম্পর্ক সূচী পঢ়ক"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"আপুনি কোনো ব্যক্তি বিশেষৰ সৈতে টেবলেট, ইমেইল বা অন্য মাধ্যমেৰে কিমান সঘনাই যোগাযোগ কৰিছে সেই তথ্য়সহ ফ\'নৰ সম্পর্কসূচীত সঞ্চয় কৰা ডেটা পঢ়িবলৈ এপক অনুমতি দিয়ে৷ এই কার্যই এপক আপোনাৰ সম্পর্কৰ ডেটা ছেভ কৰিবলৈ অনুমতি দিয়ে আৰু ক্ষতিকাৰক এপবোৰে সম্পর্কসূচীৰ ডেটা আপোনাৰ অজ্ঞাতেই শ্বেয়াৰ কৰিব পাৰে৷"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"এপ্টোক আপোনাৰ Android TV ডিভাইচটোত ষ্ট’ৰ কৰি ৰখা সম্পৰ্কবোৰৰ ডেটা পঢ়িবলৈ দিয়াৰ লগতে আপুনি কোনো বিশেষ ব্যক্তিৰ সৈতে কিমান সঘনাই কল, ইমেইল বা অন্য মাধ্যমেৰে যোগাযোগ কৰিছে তাকো জানিবলৈ অনুমতি দিয়ে। এই অনুমতিটোৱে এপ্টোক আপোনাৰ সম্পর্ক ডেটা ছেভ কৰিবলৈ দিয়ে আৰু ক্ষতিকাৰক এপ্সমূহে আপুনি নজনাকৈ আপোনাৰ সম্পর্কসূচীৰ ডেটা শ্বেয়াৰ কৰিব পাৰে।"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"আপুনি কোনো বিশেষ ব্যক্তিৰ সৈতে কিমান সঘনাই ফ\'ন, ইমেইল বা অন্য মাধ্যমেৰে যোগাযোগ কৰে সেই সম্পর্কে ফ\'নৰ সম্পর্ক সূচীত সঞ্চয় কৰা ডেটা পঢ়িবলৈ এপক অনুমতি দিয়ে। এই অনুমতিএ এপক আপোনাৰ সম্পর্কৰ ডেটা ছেভ কৰিবলৈ দিয়ে আৰু ক্ষতিকাৰক এপবোৰে সম্পর্কৰ ডেটা আপোনাৰ অজ্ঞাতেই শ্বেয়াৰ কৰিব পাৰে।"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"এপ্টোক আপোনাৰ টেবলেটত ষ্ট’ৰ কৰি ৰখা সম্পৰ্কবোৰৰ ডেটা পঢ়িবলৈ দিয়ে। এপ্সমূহৰ আপোনাৰ টেবলেটত থকা একাউণ্টসমূহলৈও এক্সেছ থাকিব যি সম্পৰ্কসমূহ সৃষ্টি কৰিছে। ইয়াত আপুনি ইনষ্টল কৰা এপ্সমূহে সৃষ্টি কৰা একাউণ্টসমূহ অন্তৰ্ভুক্ত হ’ব পাৰে। এই অনুমতিটোৱে এপ্সমূহক আপোনাৰ সম্পর্ক ডেটা ছেভ কৰিবলৈ দিয়ে আৰু ক্ষতিকাৰক এপ্সমূহে আপুনি নজনাকৈ সম্পর্ক ডেটা শ্বেয়াৰ কৰিব পাৰে।"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"এপ্টোক আপোনাৰ Android TV ডিভাইচত ষ্ট’ৰ কৰি ৰখা সম্পৰ্কবোৰৰ ডেটা পঢ়িবলৈ দিয়ে। এপ্সমূহৰ আপোনাৰ Android TV ডিভাইচটোত থকা একাউণ্টসমূহলৈও এক্সেছ থাকিব যিবোৰে সম্পৰ্কসমূহ সৃষ্টি কৰিছে। ইয়াত আপুনি ইনষ্টল কৰা এপ্সমূহে সৃষ্টি কৰা একাউণ্টসমূহ অন্তৰ্ভুক্ত হ’ব পাৰে। এই অনুমতিটোৱে এপ্সমূহক আপোনাৰ সম্পর্ক ডেটা ছেভ কৰিবলৈ দিয়ে আৰু ক্ষতিকাৰক এপ্সমূহে আপুনি নজনাকৈ সম্পর্ক ডেটা শ্বেয়াৰ কৰিব পাৰে।"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"এপ্টোক আপোনাৰ ফ’নত ষ্ট’ৰ কৰি ৰখা সম্পৰ্কবোৰৰ ডেটা পঢ়িবলৈ দিয়ে। এপ্সমূহৰ আপোনাৰ ফ’নত থকা একাউণ্টসমূহলৈও এক্সেছ থাকিব যিবোৰে সম্পৰ্কসমূহ সৃষ্টি কৰিছে। ইয়াত আপুনি ইনষ্টল কৰা এপ্সমূহে সৃষ্টি কৰা একাউণ্টসমূহ অন্তৰ্ভুক্ত হ’ব পাৰে। এই অনুমতিটোৱে এপ্সমূহক আপোনাৰ সম্পর্ক ডেটা ছেভ কৰিবলৈ দিয়ে আৰু ক্ষতিকাৰক এপ্সমূহে আপুনি নজনাকৈ সম্পর্ক ডেটা শ্বেয়াৰ কৰিব পাৰে।"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"আপোনাৰ সম্পর্ক সূচী সংশোধন কৰক"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"আপুনি ব্য়ক্তি বিশেষক কিমান সঘনাই কল কৰিছে, ইমেইল কৰিছে বা অন্য উপায়েৰে যোগাযোগ কৰিছে তাক অন্তৰ্ভুক্ত কৰি এপটোক আপোনাৰ টেবলেটত সঞ্চয় কৰি ৰখা সম্পৰ্ক সূচীৰ ডেটা সংশোধন কৰিবলৈ অনুমতি দিয়ে৷ এই অনুমতি দিলে এপসমূহে সম্পৰ্কসূচীৰ ডেটা মচিব পাৰে।"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"এপ্টোক আপোনাৰ Android TV ডিভাইচটোত ষ্ট’ৰ কৰি ৰখা সম্পৰ্কবোৰৰ ডেটা সংশোধন কৰিবলৈ দিয়াৰ লগতে আপুনি কোনো বিশেষ ব্যক্তিৰ সৈতে কিমান সঘনাই কল, ইমেইল বা অন্য মাধ্যমেৰে যোগাযোগ কৰিছে তাকো জানিবলৈ অনুমতি দিয়ে। এই অনুমতিটোৱে এপ্সমূহক সম্পৰ্কসূচীৰ ডেটা মচিবলৈ অনুমতি দিয়ে।"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"আপুনি কোনো বিশেষ ব্যক্তিৰ সৈতে কিমান সঘনাই ফ\'ন, ইমেইল বা অন্য মাধ্যমেৰে যোগাযোগ কৰে সেই সম্পর্কে ফ\'নৰ সম্পর্ক সূচীত সঞ্চয় কৰা ডেটা পঢ়িবলৈ এপক অনুমতি দিয়ে। এই কার্যই এপক সম্পর্কৰ ডেটা মচিবলৈ অনুমতি দিয়ে।"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"এপ্টোক আপোনাৰ টেবলেটত ষ্ট’ৰ কৰি ৰখা সম্পৰ্কবোৰৰ ডেটা সংশোধন কৰিবলৈ দিয়ে। এই অনুমতিয়ে এপ্সমূহক সম্পর্ক ডেটা মচিবলৈ দিয়ে।"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"এপ্টোক আপোনাৰ Android TV ডিভাইচত ষ্ট’ৰ কৰি ৰখা সম্পৰ্কবোৰৰ ডেটা সংশোধন কৰিবলৈ দিয়ে। এই অনুমতিয়ে এপ্সমূহক সম্পর্ক ডেটা মচিবলৈ দিয়ে।"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"এপ্টোক আপোনাৰ ফ\'নত ষ্ট’ৰ কৰি ৰখা সম্পৰ্কবোৰৰ ডেটা সংশোধন কৰিবলৈ দিয়ে। এই অনুমতিয়ে এপ্সমূহক সম্পর্ক ডেটা মচিবলৈ দিয়ে।"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"কল লগ পঢ়ক"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"এই এপে আপোনাৰ কলৰ ইতিহাস পঢ়িব পাৰে।"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"কল লগ লিখক"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"অতিৰিক্ত অৱস্থান দেখুওৱা নির্দেশত প্ৰৱেশ কৰক"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"অৱস্থানৰ অতিৰিক্ত নির্দেশনাসমূহত প্ৰৱেশ কৰিবলৈ এপক অনুমতি দিয়ে। ইয়ে এপটোক জিপিএছ বা অন্য অৱস্থান উৎসসমূহৰ কাৰ্যকলাপত হস্তক্ষেপ কৰাৰ সুযোগ দিব পাৰে।"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"কেৱল অগ্ৰভূমিত অৱস্থানৰ সঠিক তথ্য় পাওক"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"এই এপটোৱে যেতিয়া ই নেপথ্যত চলি থাকে তেতিয়া আপোনাৰ সঠিক অৱস্থান নিৰ্ণয় কৰিব পাৰে। এপটোৱে ব্যৱহাৰ কৰিব পৰাকৈ এই অৱস্থান সেৱাসমূহ অন হৈ থাকিবই লাগিব আৰু আপোনাৰ ফ\'নত উপলব্ধ হ\'ব লাগিব। ইয়াৰ ফলত বেটাৰিৰ খৰচ বাঢ়িব পাৰে।"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"কেৱল অগ্ৰভূমিত থকা অৱস্থাতহে আনুমানিক অৱস্থানৰ (নেটৱৰ্কৰ ওপৰত ভিত্তি কৰি) এক্সেছ"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"এই এপটোৱে অগ্ৰভূমিত থকা অৱস্থাতহে চেল টাৱাৰ আৰু ৱাই-ফাই নেটৱৰ্ক আদিৰ দৰে নেটৱৰ্ক উৎসৰ ওপৰত ভিত্তি কৰি আপোনাৰ অৱস্থান জানিব পাৰে। এপটোৱে এই অৱস্থান সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ হ\'লে সেইবোৰ অন হৈ থকাৰ লগতে আপোনাৰ টেবলেটত থাকিবই লাগিব।"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"এই এপ্টোৱে অগ্ৰভূমিত থকা অৱস্থাতহে চেল টাৱাৰবোৰ আৰু ৱাই-ফাই নেটৱৰ্কবোৰৰ দৰে নেটৱৰ্ক উৎসবোৰৰ ওপৰত ভিত্তি কৰি আপোনাৰ অৱস্থান পাব পাৰে, কিন্তু কেৱল তেতিয়াহে যেতিয়া এপ্টো অগ্ৰভূমিত থাকে। এপ্টোৱে এই অৱস্থান সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ সেইবোৰ আপোনাৰ Android TV ডিভাইচটোত অন কৰি ৰখাৰ লগতে উপলব্ধ হ’ব লাগিব।"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"এই এপটোৱে অগ্ৰভূমিত থকা অৱস্থাতহে চেল টাৱাৰ আৰু ৱাই-ফাই নেটৱৰ্ক আদিৰ দৰে নেটৱৰ্ক উৎসৰ ওপৰত ভিত্তি কৰি আপোনাৰ অৱস্থান জানিব পাৰে। এপটোৱে এই অৱস্থান সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ হ\'লে সেইবোৰ অন হৈ থকাৰ লগতে আপোনাৰ ফ\'নত থাকিবই লাগিব।"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"এই এপ্টো কেৱল অগ্ৰভূমিত থাকিলেহে এইটোৱে আপোনাৰ সঠিক অৱস্থান লাভ কৰিব পাৰে। এপ্টোৱে অৱস্থান সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ হ’লে সেইবোৰ অন হৈ থকাৰ লগতে সেয়া আপোনাৰ ডিভাইচত উপলব্ধ থাকিবই লাগিব। ইয়াৰ ফলত বেটাৰিৰ খৰচ বাঢ়িব পাৰে।"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"কেৱল অগ্ৰভূমিত আনুমানিক অৱস্থান এক্সেছ কৰক"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"এই এপ্টো অগ্ৰভূমিত থাকিলেহে এইটোৱে আপোনাৰ আনুমানিক অৱস্থান লাভ কৰিব পাৰে। এপ্টোৱে অৱস্থান সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ হ’লে সেইবোৰ অন হৈ থকাৰ লগতে সেয়া আপোনাৰ ডিভাইচত উপলব্ধ থাকিবই লাগিব।"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"নেপথ্যত চলি থকা সময়ত অৱস্থানৰ এক্সেছ"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"ইয়াৰ উপৰিও যদি ইয়াক আনুমানিক বা সঠিক অৱস্থানৰ এক্সেছ দিয়া হয়, তেন্তে উক্ত এপে নেপথ্যত চলি থকাৰ সময়ত অৱস্থানৰ এক্সেছ লাভ কৰিব পাৰে।"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"এই এপ্টোৱে অগ্ৰভূমিত অৱস্থান এক্সেছ কৰাৰ ওপৰিও নেপথ্যত চলি থাকিলেও অৱস্থান এক্সেছ কৰিব পাৰে।"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"আপোনাৰ অডিঅ\' ছেটিংসমূহ সলনি কৰক"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"এপটোক ভলিউমৰ দৰে গ্ল\'বেল অডিঅ\' ছেটিংসমূহ যাৰ স্পীকাৰক আউটপুটৰ বাবে ব্যৱহাৰ হয় তাক সলনি কৰিবলৈ অনুমতি দিয়ে৷"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"অডিঅ\' ৰেকর্ড কৰক"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"টেবলেটত ব্লুটুথৰ কনফিগাৰেশ্বন চাবলৈ আৰু যোৰা লগোৱা ডিভাইচসমূহৰ জৰিয়তে সংযোগ কৰিবলৈ আৰু সংযোগৰ অনুৰোধ স্বীকাৰ কৰিবলৈ এপটোক অনুমতি দিয়ে৷"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"এপ্টোক আপোনাৰ Android TV ডিভাইচটোত ব্লুটুথৰ কনফিগাৰেশ্বন চাবলৈ আৰু পেয়াৰ কৰি থোৱা ডিভাইচসমূহৰ সৈতে সংযোগ কৰিবলৈ আৰু গ্ৰহণ কৰিবলৈ অনুমতি দিয়ে।"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ফ\'নটোত ব্লুটুথৰ কনফিগাৰেশ্বন চাবলৈ আৰু যোৰা লগোৱা ডিভাইচসমূহৰ জৰিয়তে সংযোগ কৰিবলৈ আৰু সংযোগৰ অনুৰোধ স্বীকাৰ কৰিবলৈ এপটোক অনুমতি দিয়ে৷"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"নিয়েৰ ফিল্ড কমিউনিকেশ্বন নিয়ন্ত্ৰণ কৰক"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"এপটোক নিয়েৰ ফিল্ড কমিউনিকেশ্বন (NFC) টেগ, কাৰ্ড আৰু ৰিডাৰসমূহৰ সৈতে যোগাযোগ কৰিবলৈ অনুমতি দিয়ে।"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"আপোনাৰ স্ক্ৰীণ ল\'ক অক্ষম কৰক"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ফাইলসমূহ চাবৰ বাবে টিপক"</string>
<string name="pin_target" msgid="8036028973110156895">"পিন"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"আনপিন"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"এপ্ সম্পৰ্কীয় তথ্য"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ডেম\' আৰম্ভ কৰি থকা হৈছে…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"এই তথ্যবোৰ "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> আৰু <xliff:g id="TYPE_2">%3$s</xliff:g>ত আপডে’ট কৰিবনে ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"ছেভ কৰক"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"নালাগে, ধন্যবাদ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"এতিয়া নহয়"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"কেতিয়াও নহয়"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"আপডে’ট কৰক"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"অব্যাহত ৰাখক"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"পাছৱৰ্ড"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"বিভাজিত স্ক্ৰীন ট’গল কৰক"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"লক স্ক্ৰীন"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"স্ক্ৰীণশ্বট"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"পপ আপ ৱিণ্ড’ত <xliff:g id="APP_NAME">%1$s</xliff:g> এপ্।"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ কেপশ্বন বাৰ।"</string>
</resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 359dfb7..a34da13 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"İş profili admin tətbiqi ya yoxdur, ya da korlanıb. Nəticədə iş profili və onunla bağlı data silinib. Kömək üçün admin ilə əlaqə saxlayın."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"İş profili artıq bu cihazda əlçatan deyil"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Həddindən çox parol cəhdi"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin şəxsi istifadə üçün cihazdan imtina etdi"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Cihaz idarə olunur"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Təşkilat bu cihazı idarə edir və şəbəkənin ötürülməsinə nəzarət edə bilər. Detallar üçün klikləyin."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Cihazınız təmizlənəcəkdir"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Tətbiqə yayım bitdikdən sonra qalan əlaqələndirici yayımları göndərmək icazəsi verir. Həddindən çox istifadə Android TV cihazının daha çox yaddaşdan istifadə etməsinə səbəb olaraq onun surətini zəiflədə və stabilliyini poza bilər."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Tətbiqə yayım bitdikdən sonra da qalan çətin yayımlar göndərməyə imkan verir. Hədsiz istifadə çox yaddaş istifadəsinə səbəb olmaqla telefonu yavaş və qeyri-stabil edə bilər."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"kontakrlatınızı oxumaq"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Tətbiqə planşetinizdə yerləşən kontaktları oxumaq icazəsi verir, tez-tez zəng elədiyiniz, emailləşdiyiniz və ya əlaqə saxladığınız xüsusi individuallar daxil olmaqla. Bu icazə tətbiqlərə kontakt məlumatlarınızı saxlamağa və zərərli tətbiqlərə kontakt məlumatlarını sizin bilginiz olmada paylaşma imkanı yaradır."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Tətbiqə xüsusi şəxslərə hansı müddətdən bir zəng etmək, e-poçt göndərmək və ya onlarla başqa şəkildə əlaqə saxlamaq daxil olmaqla, Android TV cihazında saxlanan kontaktlar haqqında datanı oxumaq icazəsi verir. Bu icazə proqramlara əlaqə məlumatlarınızı saxlamaq imkanı verir və zərərli proqramlar sizin xəbəriniz olmadan əlaqə məlumatlarınızı paylaşa bilər."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Tətbiqə tez-tez zəng elədiyiniz, e-məktub göndərdiyiniz və ya əlaqə saxladığınız xüsusi individuallar daxil olmaqla telefonunuzda yerləşən kontaktları oxumaq icazəsi verir. Bu icazə tətbiqlərə kontakt məlumatlarınızı saxlamağa və zərərli tətbiqlərə kontakt məlumatlarını sizin xəbəriniz olmada paylaşma imkanı yaradır."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Tətbiqə planşetinizdə saxlanılan kontaktlar haqqında datanı oxumaq icazəsi verir. Tətbiqlərin, həmçinin planşetinizdə kontaktlar yaradan hesablara da giriş imkanı olacaq. Buraya quraşdırdığınız tətbiqlər tərəfindən yaradılan hesablar daxil ola bilər. Bu icazə tətbiqlərə kontakt məlumatlarınızı yadda saxlamaq imkanı verir və zərərli tətbiqlər kontakt məlumatlarını xəbəriniz olmadan paylaşa bilər."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Tətbiqə Android TV cihazınızda saxlanan kontaktlar haqqında datanı oxumaq icazəsi verir. Tətbiqlərin, həmçinin Android TV cihazınızda kontaktlar yaradan hesablara da giriş imkanı olacaq. Buraya quraşdırdığınız tətbiqlər tərəfindən yaradılan hesablar daxil ola bilər. Bu icazə tətbiqlərə kontakt məlumatlarınızı yadda saxlamaq imkanı verir və zərərli tətbiqlər kontakt məlumatlarını xəbəriniz olmadan paylaşa bilər."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Tətbiqə telefonunuzda saxlanılan kontaktlar haqqında datanı oxumaq icazəsi verir. Tətbiqlərin, həmçinin telefonunuzda kontaktlar yaradan hesablara da giriş imkanı olacaq. Buraya quraşdırdığınız tətbiqlər tərəfindən yaradılan hesablar daxil ola bilər. Bu icazə tətbiqlərə kontakt məlumatlarınızı yadda saxlamaq imkanı verir və zərərli tətbiqlər kontakt məlumatlarını xəbəriniz olmadan paylaşa bilər."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"kontaktlarınızı dəyişdirir"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Tətbiqə planşetinizdəki zəng etmək tezliyiniz, elektron poçtlarınız, ünsiyyətləriniz haqqında məlumatları dəyişməyə imkan verir. Bu icazə kontakt məlumatlarının silinməsinə də imkan verir."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Tətbiqə xüsusi şəxslərə hansı müddətdən bir zəng etmək, e-poçt göndərmək və ya onlarla başqa şəkildə əlaqə saxlamaq daxil olmaqla, Android TV cihazında saxlanan kontaktlar haqqında datanı dəyişdirmək icazəsi verir. Bu icazə tətbiqlərə kontakt datasını silmək imkanı verir."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Tətbiqə Sizin zəng etmək tezliyiniz, elektron poçtlarınız, ünsiyyətləriniz haqqında məlumatları dəyişməyə imkan verir. Buna kontaktların silinməsi imkanı də daxildir."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Tətbiqə planşetinizdə saxlanan kontaktlar haqqında datanı dəyişdirmək icazəsi verir. Bu icazə tətbiqlərə kontakt datasını silmək imkanı verir."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Tətbiqə Android TV cihazında saxlanan kontaktlar haqqında datanı dəyişdirmək icazəsi verir. Bu icazə tətbiqlərə kontakt datasını silmək imkanı verir."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Tətbiqə telefonunuzda saxlanan kontaktlar haqqında datanı dəyişdirmək icazəsi verir. Bu icazə tətbiqlərə kontakt datasını silmək imkanı verir."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"zəng qeydiyyatını oxu"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Bu tətbiq zəng tarixçənizi oxuya bilər."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"zəng loqu yazır"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"əlavə məkan provayderi əmrlərinə çıxış"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Tətbiqə ekstra məkan provayder əmrlərinə girişə imkan verir. Bu, tətbiqə GPS və ya digər lokal mənbələrlə əməliyyata müdaxiləyə imkan verə bilər."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"yalnız ön planda dəqiq məkana daxil olun"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Bu tətbiq yalnız ön fonda olduqda dəqiq məkanınızı əldə edə bilər. Tətbiqin bunlardan istifadə etməsi üçün bu məkan xidmətləri aktiv edilməlidir və telefonda əlçatan olmalıdır. Bu, batareya sərfiyyatını artıra bilər."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"yalnız ön planda təxmini məkana (şəbəkəyə əsaslanan) giriş"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Bu tətbiq baza stansiyaları və Wi-Fi şəbəkələri kimi şəbəkə mənbələrinə əsaslanaraq məkanınızı əldə edə bilər. Bu, yalnız tətbiq ön planda olduqda mümkündür. Tətbiqin istifadə edə bilməsi üçün bu məkan xidmətləri aktiv edilməli və planşetdə əlçatan olmalıdır."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Bu tətbiq baza stansiyaları və Wi-Fi kimi şəbəkə mənbələrinə əsaslanaraq məkanınızı əldə edə bilər. Bu, yalnız tətbiq ön planda olduqda mümkündür. Tətbiqin istifadə etməsi üçün bu məkan xidmətləri aktiv edilməli və Android TV cihazında əlçatan olmalıdır."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Bu tətbiq baza stansiyaları və Wi-Fi kimi şəbəkə mənbələrinə əsaslanaraq məkanınızı əldə edə bilər. Bu, yalnız tətbiq ön planda olduqda mümkündür. Tətbiqin istifadə edə bilməsi üçün bu məkan xidmətləri aktiv edilməli və telefonda əlçatan olmalıdır."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Bu tətbiq yalnız ön fonda olduqda dəqiq məkanınızı əldə edə bilər. Tətbiqin bunlardan istifadə etməsi üçün məkan xidmətləri aktiv edilməli və cihazda əlçatan olmalıdır. Bu, batareya sərfiyyatını artıra bilər."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"yalnız ön planda təqribi məkana giriş"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Bu tətbiq yalnız ön fonda olduqda təqribi məkanınızı əldə edə bilər. Tətbiqin istifadə edə bilməsi üçün məkan xidmətləri cihazda aktiv edilməli və əlçatan olmalıdır."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"arxa fonda məkan girişi"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Bu, təqribi və ya dəqiq məkan girişinə əlavə olaraq verilərsə, tətbiq arxa fonda işləyərkən məkana daxil ola bilər."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Bu tətbiq ön planda məkana girişlə yanaşı, arxa fonda işləyərkən məkana giriş edə bilər."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"audio ayarlarınızı dəyişir"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Tətbiqə səs və hansı spikerin çıxış üçün istifadə olunduğu kimi qlobal səs ayarlarını dəyişdirməyə imkan verir."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"səs yaz"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Tətbiqə yerli Bluetooth planşetinin konfiqurasiyasını görməyə və cütlənmiş cihazlarla bağlantılar etməyə və qəbul etməyə imkan verir."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Tətbiqə Android TV cihazında Bluetooth konfiqurasiyasına baxmaq, həmçinin qoşulmuş cihazlar ilə bağlantılar yaratmaq və qəbul etmək icazəsi verir."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Tətbiqə Bluetooth və ya telefon konfiqurasiyalarını görməyə və qoşulmuş cihazlarla əlaqə qurmağa və qəbul etməyə icazə verir."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication\'ı kontrol et"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Tətbiqə Yaxın Məsafə Kommunikasiyası (NFC) teqləri, kartları və oxuyucuları ilə əlaqə qurmağa icazə verir."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"Ekran kilidini deaktiv edir"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> məhsuluna bağlandı"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Faylları görmək üçün basın"</string>
<string name="pin_target" msgid="8036028973110156895">"Pin kod"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Çıxarın"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Tətbiq məlumatı"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Demo başlayır…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Bu elementlər "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ünvanında yenilənsin: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> və <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Yadda saxlayın"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Xeyr, çox sağ olun"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"İndi yox"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Heç vaxt"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Yeniləyin"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Davam edin"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"parol"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Bölünmüş Ekrana keçid"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Kilid Ekranı"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekran şəkli"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Açilən pəncərədə <xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> başlıq paneli."</string>
</resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index a27d359..96a12c7 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -190,8 +190,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikacija za administratore na profilu za Work nedostaje ili je oštećena. Zbog toga su profil za Work i povezani podaci izbrisani. Obratite se administratoru za pomoć."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profil za Work više nije dostupan na ovom uređaju"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Previše pokušaja unosa lozinke"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator je ustupio uređaj za ličnu upotrebu"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Uređajem se upravlja"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj. Dodirnite za detalje."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti obrisan"</string>
@@ -384,13 +383,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Dozvoljava aplikaciji da šalje lepljiva emitovanja koja ostaju po završetku emitovanja. Prekomerna upotreba može da uspori ili destabilizuje Android TV uređaj tako što će ga primorati da troši previše memorije."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Dozvoljava aplikaciji da šalje prijemčiva emitovanja, koja ostaju po završetku emitovanja. Prekomerna upotreba može da uspori ili destabilizuje telefon tako što će ga primorati da troši previše memorije."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"čitanje kontakata"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Dozvoljava aplikaciji da čita podatke o kontaktima uskladištene na tabletu, uključujući podatke o tome koliko često zovete određene osobe, šaljete im poruke e-pošte ili na drugi način komunicirate sa njima. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima, a zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Dozvoljava aplikaciji da čita podatke o kontaktima koje čuvate na Android TV uređaju, uključujući učestalost poziva, slanja imejlova ili drugih načina komunikacije sa određenim pojedincima. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima i zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Dozvoljava aplikaciji da čita podatke o kontaktima uskladištene na telefonu, uključujući podatke o tome koliko često zovete određene osobe, šaljete im poruke e-pošte ili na drugi način komunicirate sa njima. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima, a zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Dozvoljava aplikaciji da čita podatke o kontaktima koje čuvate na tabletu. Aplikacije će imati pristup i nalozima na vašem tabletu na kojima su napravljeni kontakti. Tu mogu da spadaju nalozi koje su otvorile aplikacije koje ste instalirali. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima i zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Dozvoljava aplikaciji da čita podatke o kontaktima koje čuvate na Android TV uređaju. Aplikacije će imati pristup i nalozima na vašem Android TV uređaju na kojima su napravljeni kontakti. Tu mogu da spadaju nalozi koje su otvorile aplikacije koje ste instalirali. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima i zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Dozvoljava aplikaciji da čita podatke o kontaktima koje čuvate na telefonu. Aplikacije će imati pristup i nalozima na vašem telefonu na kojima su napravljeni kontakti. Tu mogu da spadaju nalozi koje su otvorile aplikacije koje ste instalirali. Ova dozvola omogućava aplikacijama da čuvaju podatke o kontaktima i zlonamerne aplikacije mogu da dele podatke o kontaktima bez vašeg znanja."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"izmena kontakata"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Dozvoljava aplikaciji da menja podatke o kontaktima uskladištene na tabletu, uključujući podatke o tome koliko često zovete određene kontakte, šaljete im poruke e-pošte ili na drugi način komunicirate sa njima. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Dozvoljava aplikaciji da menja podatke o kontaktima koje čuvate na Android TV uređaju, uključujući učestalost poziva, slanja imejlova ili drugih načina komunikacije sa određenim kontaktima. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Dozvoljava aplikaciji da menja podatke o kontaktima uskladištene na telefonu, uključujući podatke o tome koliko često zovete određene kontakte, šaljete im poruke e-pošte ili na drugi način komunicirate sa njima. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Dozvoljava aplikaciji da menja podatke o kontaktima koje čuvate na tabletu. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Dozvoljava aplikaciji da menja podatke o kontaktima koje čuvate na Android TV uređaju. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Dozvoljava aplikaciji da menja podatke o kontaktima koje čuvate na telefonu. Ova dozvola omogućava aplikacijama da brišu podatke o kontaktima."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"čitanje evidencije poziva"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Ova aplikacija može da čita istoriju poziva."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"pisanje evidencije poziva"</string>
@@ -410,13 +409,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"pristup dodatnim komandama dobavljača lokacije"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Omogućava aplikaciji da pristupa dodatnim komandama davaoca usluga lokacije. To može da omogući aplikaciji da utiče na rad GPS-a ili drugih izvora lokacije."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"pristup preciznoj lokaciji samo u prvom planu"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Ova aplikacija može da odredi vašu tačnu lokaciju samo kada radi u prvom planu. Ove usluge lokacije moraju da budu uključene i dostupne na telefonu da bi aplikacija mogla da ih koristi. To može da poveća potrošnju baterije."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"pristup približnoj lokaciji (utvrđenoj preko mreže) samo u prvom planu"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Ova aplikacija može da pristupi vašoj lokaciji pomoću izvora mreže, kao što su mobilni predajnici i Wi-Fi mreže, ali samo kada aplikacija radi u prvom planu. Ove usluge lokacije moraju da budu uključene i dostupne na tabletu da bi aplikacija mogla da ih koristi"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Ova aplikacija može da pristupi vašoj lokaciji pomoću izvora mreže, kao što su mobilni predajnici i Wi-Fi mreže, ali samo kada aplikacija radi u prvom planu. Ove usluge lokacije moraju da budu uključene i dostupne na Android TV uređaju da bi aplikacija mogla da ih koristi."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Ova aplikacija može da pristupi vašoj lokaciji pomoću izvora mreže, kao što su mobilni predajnici i Wi-Fi mreže, ali samo kada aplikacija radi u prvom planu. Ove usluge lokacije moraju da budu uključene i dostupne na telefonu da bi aplikacija mogla da ih koristi."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Ova aplikacija može da odredi vašu tačnu lokaciju samo kada radi u prvom planu. Usluge lokacije moraju da budu uključene i dostupne na uređaju da bi aplikacija mogla da ih koristi. To može da poveća potrošnju baterije."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"pristup približnoj lokaciji samo u prvom planu"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Ova aplikacija može da odredi vašu približnu lokaciju samo kada radi u prvom planu. Usluge lokacije moraju da budu uključene i dostupne na uređaju da bi aplikacija mogla da ih koristi."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"pristup lokaciji u pozadini"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Ako se pored približnog ili preciznog pristupa lokacija odobri i ovaj, aplikacija može da pristupa lokaciji dok je pokrenuta u pozadini."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Ova aplikacija može da pristupa lokaciji dok radi u pozadini, kao i kada radi u prvom planu."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"promena audio podešavanja"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Dozvoljava aplikaciji da menja globalna audio podešavanja kao što su jačina zvuka i izbor zvučnika koji se koristi kao izlaz."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"snimanje audio zapisa"</string>
@@ -497,6 +494,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Dozvoljava aplikaciji da pregleda konfiguraciju Bluetooth-a na tabletu, kao i da uspostavlja i prihvata veze sa uparenim uređajima."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Dozvoljava aplikaciji da pregleda konfiguraciju Bluetooth-a na Android TV uređaju i da uspostavlja i prihvata veze sa uparenim uređajima."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Dozvoljava aplikaciji da pregleda konfiguraciju Bluetooth-a na telefonu, kao i da uspostavlja i prihvata veze sa uparenim uređajima."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"kontrola komunikacije u užem polju (Near Field Communication)"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Dozvoljava aplikaciji da komunicira sa oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"onemogućavanje zaključavanja ekrana"</string>
@@ -1894,7 +1895,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Povezano je sa proizvodom <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Dodirnite za pregled datoteka"</string>
<string name="pin_target" msgid="8036028973110156895">"Zakači"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Otkači"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Informacije o aplikaciji"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Pokrećemo demonstraciju..."</string>
@@ -1938,6 +1943,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Želite li da ažurirate ove stavke u usluzi "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Sačuvaj"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Ne, hvala"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne sada"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nikada"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Ažuriraj"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Nastavi"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"lozinka"</string>
@@ -2034,5 +2041,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Uključite/isključite podeljeni ekran"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključani ekran"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snimak ekrana"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u iskačućem prozoru."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Traka sa naslovima aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index fb0fa33..c7503d0 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -192,8 +192,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Праграма адміністратара для працоўнага профілю адсутнічае або пашкоджана. У выніку гэтага ваш працоўны профіль і звязаныя з ім даныя былі выдалены. Звярніцеся па дапамогу да адміністратара."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Ваш працоўны профіль больш не даступны на гэтай прыладзе"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Занадта шмат спроб уводу пароля"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Адміністратар пераналадзіў прыладу для асабістага выкарыстання"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Прылада знаходзіцца пад кіраваннем"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ваша арганізацыя кіруе гэтай прыладай і можа сачыць за сеткавым трафікам. Дакраніцеся для атрымання дадатковай інфармацыі."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Даныя вашай прылады будуць сцерты"</string>
@@ -387,13 +386,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Дазваляе праграме адпраўляць замацаваныя трансляцыі, якія застаюцца пасля заканчэння асноўнай трансляцыі. Злоўжыванне гэтым можа зрабіць працу прылады Android TV павольнай або няўстойлівай, прымушаючы яе выкарыстоўваць занадта шмат памяці."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Дазваляе прыкладанню адпраўляць далейшыя звязаныя перадачы, якія застаюцца пасля заканчэння асноўнай перадачы. Злоўжыванне можа зрабіць працу тэлефона павольнай або няўстойлівай, прымушаючы яго выкарыстоўваць занадта шмат памяці."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"чытанне кантактаў"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Дазваляе прыкладанням счытваць дадзеныя аб кантактах, якія захоўваюцца на планшэце, у тым ліку звесткi пра тое, як часта вы выклiкалi канкрэтных абанентаў, пiсалi iм па электроннай пошце або кантактавалi іншымi спосабамі. Дзякуючы гэтаму дазволу прыкладаннi могуць захоўваць дадзеныя гiсторыi выклiкаў, а шкоднасныя прыкладаннi могуць адпраўляць кантактныя дадзеныя без вашага ведама."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Дазваляе праграме счытваць даныя пра кантакты, якія захоўваюцца на прыладзе Android TV, у тым ліку звесткі пра тое, як часта вы выклікалі пэўных абанентаў, пісалі ім электронныя лісты ці звязваліся з імі іншымі спосабамі. Гэты дазвол дае праграмам магчымасць захоўваць даныя пра кантакты, а шкодныя праграмы могуць абагульваць гэтыя даныя без вашага ведама."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Дазваляе прыкладанням счытваць дадзеныя аб кантактах, якія захоўваюцца на тэлефоне, у тым ліку звесткi пра частату, з якой вы выклiкалi iх, пiсалi iм па электроннай пошце ці кантактавалi іншым спосабам. Дзякуючы гэтаму дазволу прыкладаннi могуць захоўваць дадзеныя гiсторыi выклiкаў, а шкоднасныя прыкладаннi могуць адпраўляць кантактныя дадзеныя без вашага ведама."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Дазваляе праграме счытваць даныя пра кантакты, якія захоўваюцца на вашым планшэце. Праграмы таксама атрымаюць доступ на планшэце да ўліковых запісаў, у якіх створаны кантакты. Сярод іх могуць быць уліковыя запісы, створаныя праграмамі, якія вы ўсталявалі. Гэты дазвол дае праграмам магчымасць захоўваць даныя пра кантакты, а шкодныя праграмы могуць абагульваць гэтыя даныя без вашага ведама."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Дазваляе праграме счытваць даныя пра кантакты, якія захоўваюцца на вашай прыладзе Android TV. Праграмы таксама атрымаюць доступ да ўліковых запісаў на прыладзе Android TV, у якіх створаны кантакты. Сярод іх могуць быць уліковыя запісы, створаныя праграмамі, якія вы ўсталявалі. Гэты дазвол дае праграмам магчымасць захоўваць даныя пра кантакты, а шкодныя праграмы могуць абагульваць гэтыя даныя без вашага ведама."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Дазваляе праграме счытваць даныя пра кантакты, якія захоўваюцца на вашым тэлефоне. Праграмы таксама атрымаюць доступ на тэлефоне да ўліковых запісаў, у якіх створаны кантакты. Сярод іх могуць быць уліковыя запісы, створаныя праграмамі, якія вы ўсталявалі. Гэты дазвол дае праграмам магчымасць захоўваць даныя пра кантакты, а шкодныя праграмы могуць абагульваць гэтыя даныя без вашага ведама."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"змена кантактаў"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Дазваляе прыкладанням змяняць дадзеныя аб кантактах, якія захоўваюцца на планшэце, у тым ліку частата, з якой вы выклiкалi асоб, пiсалi па электроннай пошце ці іншым спосабам кантактавалi з iмі. З гэтым дазволам прыкладаннi змогуць выдаляць кантактныя дадзеныя."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Дазваляе праграме змяняць даныя пра кантакты, якія захоўваюцца на прыладзе Android TV, у тым ліку звесткі пра тое, як часта вы выклікалі пэўных абанентаў, пісалі ім электронныя лісты ці звязваліся з імі іншымi спосабамі. Гэты дазвол дае праграмам магчымасць выдаляць даныя пра кантакты."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Дазваляе прыкладанням змяняць дадзеныя аб кантактах, якія захоўваюцца на тэлефоне, у тым ліку частата, з якой вы выклiкалi асоб, пiсалi па электроннай пошце ці іншым спосабам кантактавалi з iмі. З гэтым дазволам прыкладаннi змогуць выдаляць кантактныя дадзеныя."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Дазваляе праграме змяняць даныя пра кантакты, якія захоўваюцца на вашым планшэце. Гэты дазвол дае праграмам магчымасць выдаляць даныя пра кантакты."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Дазваляе праграме змяняць даныя пра кантакты, якія захоўваюцца на вашай прыладзе Android TV. Гэты дазвол дае праграмам магчымасць выдаляць даныя пра кантакты."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Дазваляе праграме змяняць даныя пра кантакты, якія захоўваюцца на вашым тэлефоне. Гэты дазвол дае праграмам магчымасць выдаляць даныя пра кантакты."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"чытанне гiсторыi выклікаў"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Гэта праграма можа чытаць вашу гісторыю выклікаў."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"запіс гiсторыi выклікаў"</string>
@@ -413,13 +412,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"доступ да дадатковых камандаў пастаўшчыка месцазнаходжання"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Дазваляе праграме атрымліваць доступ да дадатковых каманд службаў вызначэння месцазнаходжання. Гэта можа дазволіць праграме ўмешвацца ў функцыянаванне GPS або іншых крыніц даных аб месцазнаходжаннi."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"доступ да дакладнага месцазнаходжання толькі ў асноўным рэжыме"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Гэта праграма можа атрымліваць звесткі пра ваша дакладнае месцазнаходжанне толькі ў асноўным рэжыме. Службы геалакацыі павінны быць уключаны і даступныя на вашым тэлефоне, каб праграма магла імі карыстацца. Гэта можа павялічыць спажыванне зараду акумулятара."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"доступ да прыблізнага месцазнаходжання (на падставе сеткі) толькі ў актыўным рэжыме"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Гэта праграма можа атрымліваць звесткі пра ваша месцазнаходжанне толькі ў актыўным рэжыме на падставе даных сеткавых крыніц, такіх як вышкі сотавай сувязі і сеткі Wi-Fi. Каб праграма магла карыстацца гэтымі службамі геалакацыі, неабходна ўключыць і зрабіць іх даступнымі на планшэце."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Гэта праграма можа атрымліваць звесткі пра ваша месцазнаходжанне толькі ў актыўным рэжыме на падставе даных сеткавых крыніц, такіх як вышкі сотавай сувязі і сеткі Wi-Fi. Уключыце гэтыя службы геалакацыі і зрабіце іх даступнымі на прыладзе Android TV, каб праграма магла выкарыстоўваць іх даныя."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Гэта праграма можа атрымліваць звесткі пра ваша месцазнаходжанне толькі ў актыўным рэжыме на падставе даных сеткавых крыніц, такіх як вышкі сотавай сувязі і сеткі Wi-Fi. Каб праграма магла карыстацца гэтымі службамі геалакацыі, неабходна ўключыць і зрабіць іх даступнымі на тэлефоне."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Гэта праграма можа атрымліваць звесткі пра ваша дакладнае месцазнаходжанне толькі ў актыўным рэжыме. Службы геалакацыі павінны быць уключаны і даступныя на вашай прыладзе, каб праграма магла імі карыстацца. Гэта можа павялічыць спажыванне зараду акумулятара."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"доступ да прыблізнага месцазнаходжання толькі ў актыўным рэжыме"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Гэта праграма можа атрымліваць звесткі пра ваша прыблізнае месцазнаходжанне толькі ў актыўным рэжыме. Службы геалакацыі павінны быць уключаны і даступныя на вашай прыладзе, каб праграма магла імі карыстацца."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"доступ да вызначэння месцазнаходжання ў фонавым рэжыме"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Акрамя доступу да прыкладнага ці дакладнага месцазнаходжання праграма можа мець доступ да вызначэння геалакацыі ў фонавым рэжыме працы. На гэта патрабуецца дазвол."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Гэта праграма можа мець доступ да даных пра месцазнаходжанне не толькі ў актыўным, але і ў фонавым рэжыме."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"змяняць налады аудыё"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Дазваляе прыкладанням змяняць глабальныя налады гуку, такія як моц і тое, што дынамік выкарыстоўваецца для выхаду."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"запіс аўдыя"</string>
@@ -500,6 +497,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Дазваляе прыкладанню праглядаць канфігурацыю Bluetooth на планшэце , а таксама здзяйсняць і прымаць злучэнні са спалучанымі прыладамі."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Дазваляе праграме праглядаць канфігурацыю Bluetooth на прыладзе Android TV, а таксама выконваць і дазваляць злучэнні са спалучанымі прыладамі."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Дазваляе прыкладанню праглядаць канфігурацыю Bluetooth на тэлефоне , а таксама здзяйсняць і прымаць злучэнні са спалучанымі прыладамі."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"кантроль Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Дазваляе прыкладаннzv спалучацца з тэгамі, картамі і счытваючымі прыладамі Near Field Communication (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"адключэнне блакiроўкi экрана"</string>
@@ -1926,7 +1927,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Падлучана да <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Краніце для прагляду файлаў"</string>
<string name="pin_target" msgid="8036028973110156895">"Замацаваць"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Адмацаваць"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Інфармацыя пра праграму"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Ідзе запуск дэманстрацыі…"</string>
@@ -1971,6 +1976,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Абнавіць наступныя элементы ў сэрвісе "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> і <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Захаваць"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Не, дзякуй"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Не зараз"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Ніколі"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Абнавіць"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Працягнуць"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"пароль"</string>
@@ -2068,5 +2075,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Пераключальнік падзеленага экрана"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Экран блакіроўкі"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Здымак экрана"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" ва ўсплывальным акне."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Панэль субцітраў праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 69c998d..882d8fd 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Приложението за администриране на служебния потребителски профил липсва или е повредено. В резултат на това той и свързаните с него данни са изтрити. За съдействие се свържете с администратора си."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Служебният ви потребителски профил вече не е налице на това устройство"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Опитите за паролата са твърде много"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Администраторът предостави устройствотото за лична употреба"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Устройството се управлява"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Организацията ви управлява това устройство и може да наблюдава мрежовия трафик. Докоснете за подробности."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Данните на устройството ви ще бъдат изтрити"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Дава възможност на приложението да изпраща оставащи излъчвания, които се запазват след края на излъчването. Прекалената употреба може да причини бавна или нестабилна работа на устройството ви с Android TV, като го накара да използва твърде много памет."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Разрешава на приложението да изпраща оставащи излъчвания, които се запазват след края на излъчването. Прекалената употреба може да причини бавна или нестабилна работа на телефона, като го накара да използва твърде много памет."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"четене на контактите ви"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Разрешава на приложението да чете данни за съхранените на таблета ви контакти, включително честотата на обаждане, изпращане на имейли или общуване по друг начин с конкретни лица. Това разрешение позволява на приложенията да запазват информацията за контактите ви, а злонамерените могат да я споделят без ваше знание."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Дава възможност на приложението да чете данните за съхраняваните на устройството ви с Android TV контакти, включително колко често сте се обаждали на конкретни хора, изпращали сте им имейли или сте общували с тях по други начини. Това разрешение позволява на приложенията да запазват информация за контактите ви, а злонамерените приложения може да я споделят без знанието ви."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Разрешава на приложението да чете данни за съхранените на телефона ви контакти, включително честотата на обаждане, изпращане на имейли или общуване по друг начин с конкретни лица. Това разрешение позволява на приложенията да запазват информацията за контактите ви, а злонамерените могат да я споделят без ваше знание."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Разрешава на приложението да чете данните за съхраняваните в таблета ви контакти. Приложенията ще имат достъп и до профилите на таблета ви, в които са създадени контакти. Това може да включва и профилите, създадени от инсталирани от вас приложения. Така приложенията могат да запазват данните за контактите ви, а злонамерените приложения – да ги споделят без ваше знание."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Разрешава на приложението да чете данните за съхраняваните в устройството ви с Android TV контакти. Приложенията ще имат достъп и до профилите на устройството ви с Android TV, в които са създадени контакти. Това може да включва и профилите, създадени от инсталирани от вас приложения. Така приложенията могат да запазват данните за контактите ви, а злонамерените приложения – да ги споделят без ваше знание."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Разрешава на приложението да чете данните за съхраняваните в телефона ви контакти. Приложенията ще имат достъп и до профилите на телефона ви, в които са създадени контакти. Това може да включва и профилите, създадени от инсталирани от вас приложения. Така приложенията могат да запазват данните за контактите ви, а злонамерените приложения – да ги споделят без ваше знание."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"промяна на контактите ви"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Разрешава на приложението да променя данните за съхранените на таблета ви контакти, включително честотата на обаждане, изпращане на имейли или общуване по друг начин с конкретни контакти. Това разрешение му позволява да изтрива информацията за тях."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Дава възможност на приложението да променя данните за съхраняваните на устройството ви с Android TV контакти, включително колко често сте се обаждали на конкретни хора, изпращали сте им имейли или сте общували с тях по други начини. Това разрешение позволява на приложенията да изтриват данните за контактите."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Разрешава на приложението да променя данните за съхранените на телефона ви контакти, включително честотата на обаждане, изпращане на имейли или общуване по друг начин с конкретни контакти. Това разрешение му позволява да изтрива информацията за тях."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Разрешава на приложението да променя данните за съхраняваните на таблета ви контакти. Това разрешение позволява на приложенията да изтриват данните за контактите."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Разрешава на приложението да променя данните за съхраняваните на устройството ви с Android TV контакти. Това разрешение позволява на приложенията да изтриват данните за контактите."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Разрешава на приложението да променя данните за съхраняваните на телефона ви контакти. Това разрешение позволява на приложенията да изтриват данните за контактите."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"четене на списъка с обаждания"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Това приложение може да чете историята на обажданията ви."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"запис на списъка с обаждания"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"достъп до допълнителни команди на доставчика на местоположение"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Разрешава на приложението достъп до допълнителни команди на доставчика на местоположение. Това може да позволи на приложението да смущава работата на GPS или на другите източници на местоположение."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"достъп до точното местоположение само на преден план"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Приложението може да получава данни за точното ви местоположение само когато работи на преден план. Тези услуги за местоположение трябва да са включени и налице на телефона ви, за да могат да се използват от приложението. Това може да увеличи потреблението на батерията."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"достъп до приблизителното местоположение (основано на мрежи) само на преден план"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Приложението може да получава данни за местоположението ви въз основа на мрежови източници, като клетъчни базови станции и Wi-Fi мрежи, само когато работи на преден план. Тези услуги за местоположение трябва да са включени и налице на таблета ви, за да могат да се използват от приложението."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Това приложение може да получава данни за местоположението ви въз основа на мрежови източници, като клетъчни базови станции и Wi-Fi мрежи, само когато работи на преден план. Тези услуги за местоположение трябва да са включени и налични на устройството ви с Android TV, за да могат да се използват от приложението."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Приложението може да получава данни за местоположението ви въз основа на мрежови източници, като клетъчни базови станции и Wi-Fi мрежи, само когато работи на преден план. Тези услуги за местоположение трябва да са включени и налице на телефона ви, за да могат да се използват от приложението."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Приложението може да получава данни за точното ви местоположение само когато работи на преден план. Услугите за местоположение трябва да са включени и налице на устройството ви, за да могат да се използват от приложението. Това може да увеличи потреблението на батерията."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"достъп до приблизителното местоположение само на преден план"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Приложението може да получава данни за приблизителното ви местоположение само когато работи на преден план. Услугите за местоположение трябва да са включени и налице на устройството ви, за да могат да се използват от приложението."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"достъп до местоположението на заден план"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Ако разрешението бъде предоставено в допълнение към достъпа до приблизителното или точното местоположение, приложението може да осъществява достъп до местоположението, докато се изпълнява на заден план."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Това приложение освен на преден план може да осъществява достъп до местоположението, докато работи на заден план."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"промяна на настройките ви за звука"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Разрешава на приложението да променя глобалните настройки за звука, като например силата и това, кой високоговорител се използва за изход."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"записва звук"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Разрешава на приложението да вижда конфигурацията на Bluetooth на таблета и да изгражда и приема връзки със сдвоени устройства."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Дава възможност на приложението да преглежда конфигурацията на Bluetooth на устройството ви с Android TV и да създава и приема връзки със сдвоени устройства."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Разрешава на приложението да вижда конфигурацията на Bluetooth на телефона и да изгражда и приема връзки със сдвоени устройства."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"контролиране на комуникацията в близкото поле"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Разрешава на приложението да комуникира с маркери, карти и четци, ползващи комуникация в близкото поле (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"деактивиране на заключването на екрана ви"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Установена е връзка с <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Докоснете, за да прегледате файловете"</string>
<string name="pin_target" msgid="8036028973110156895">"Фиксиране"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Освобождаване"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Информация за приложението"</string>
<string name="negative_duration" msgid="1938335096972945232">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Демонстрацията се стартира…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Искате ли да актуализирате тези елементи в(ъв) "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> и <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Запазване"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Не, благодаря"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Не сега"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Никога"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Актуализиране"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Напред"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"Паролата"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Превключване на разделения екран"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Заключен екран"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Екранна снимка"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Приложението <xliff:g id="APP_NAME">%1$s</xliff:g> в изскачащ прозорец."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Лента за надписи на <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index e335396..98d5e5d 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"কর্মস্থলের প্রোফাইলের প্রশাসক অ্যাপটি হয় নেই, অথবা সেটি ক্ষতিগ্রস্ত হয়েছে৷ এর ফলে আপনার কর্মস্থলের প্রোফাইল এবং সম্পর্কিত ডেটা মুছে ফেলা হয়েছে৷ সহায়তার জন্য আপনার প্রশাসকের সাথে যোগাযোগ করুন৷"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"আপনার কর্মস্থলের প্রোফাইলটি আর এই ডিভাইসে নেই"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"বহুবার ভুল পাসওয়ার্ড দিয়েছেন"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"ব্যক্তিগত কাজের জন্য অ্যাডমিন এই ডিভাইস ব্যবহার করার অনুমতি দেয়নি"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"ডিভাইসটি পরিচালনা করা হচ্ছে"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"আপনার প্রতিষ্ঠান এই ডিভাইসটি পরিচালনা করে এবং এটির নেটওয়ার্ক ট্রাফিকের উপরে নজর রাখতে পারে। বিশদ বিবরণের জন্য ট্যাপ করুন।,"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"আপনার ডিভাইসটি মুছে ফেলা হবে"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"অ্যাপটিকে স্টিকি সম্প্রচার পাঠানোর অনুমতি দেয়। সম্প্রচার শেষ হয়ে যাওয়ার পরেও সেটি সরে যায় না। এটির অতিরিক্ত ব্যবহার করা হলে, অত্যধিক মেমরি ব্যবহার হওয়ার ফলে আপনার Android TV ডিভাইস স্লো হয়ে যেতে পারে অথবা স্থিতিশীলতা হারাতে পারে।"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"স্টিকি সম্প্রচারগুলি পাঠাতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে, যা সম্প্রচার শেষ হয়ে যাওয়ার পরও উপলব্ধ থাকে৷ খুব বেশি পরিমাণে ব্যবহার করার ফলে ফোনটিকে ধীরগতির করে দিতে পারে অথবা খুব বেশি পরিমাণ মেমরি ব্যবহারের ফলে এটি যথাযথভাবে কাজ নাও করতে পারে৷"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"আপনার পরিচিতিগুলি পড়ুন"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"অ্যাপ্লিকেশনটিকে আপনি নির্দিষ্ট একজন স্বতন্ত্র ব্যক্তির সঙ্গে ফ্রিকোয়েন্সি দিয়ে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ট্যাবলেটে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পড়তে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশনগুলিকে আপনার পরিচিতি ডেটা সংরক্ষণ করতে দেয় এবং ক্ষতিকারক অ্যাপ্লিকেশনগুলি আপনাকে না জানিয়ে পরিচিতি ডেটা ভাগ করতে পারে৷"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"এই অ্যাপকে Android TV ডিভাইসে পরিচিতি সম্পর্কে সেভ করা ডেটা পড়ার অনুমতি দেয়, এক্ষেত্রে যেকোনও নির্দিষ্ট ব্যক্তিকে আপনি কত ঘন ঘন কল, ইমেল বা তার সাথে অন্য কোনও মাধ্যমে যোগাযোগ করেছেন তাও অন্তর্ভুক্ত। এই অনুমতির পেলে কোনও অ্যাপ আপনার পরিচিতির ডেটা সেভ করতে পারে এবং ক্ষতিকারক অ্যাপ আপনার অজান্তে পরিচিতির ডেটা শেয়ার করতে পারে।"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"অ্যাপ্লিকেশনটিকে আপনি নির্দিষ্ট একজন স্বতন্ত্র ব্যক্তির সঙ্গে ফ্রিকোয়েন্সি দিয়ে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ফোনে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পড়তে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশনগুলিকে আপনার পরিচিতি ডেটা সংরক্ষণ করতে দেয় এবং ক্ষতিকারক অ্যাপ্লিকেশনগুলি আপনাকে না জানিয়ে পরিচিতি ডেটা ভাগ করতে পারে৷"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"এই অ্যাপকে আপনার ট্যাবলেটে পরিচিতি সম্পর্কে সেভ করা ডেটা পড়ার অনুমতি দেয়। আপনার ট্যাবলেটের যেসব অ্যাকাউন্ট পরিচিতি তৈরি করা হয়েছে, এই অ্যাপ সেই অ্যাকাউন্টও অ্যাক্সেস করতে পারবে। আপনার ইনস্টল করা কোনও অ্যাপ অ্যাকাউন্ট তৈরি করলে এটির মধ্যে সেটিও থাকতে পারে। এই অনুমতি অ্যাপকে আপনার পরিচিতি সংক্রান্ত ডেটা সেভ করতে দেয় এবং ক্ষতিকারক অ্যাপ আপনাকে না জানিয়ে পরিচিতি সংক্রান্ত ডেটা শেয়ার করতে পারে।"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"এই অ্যাপকে Android TV ডিভাইসে পরিচিতি সম্পর্কে সেভ করা ডেটা পড়ার অনুমতি দেয়। আপনার Android TV ডিভাইসে যেসব অ্যাকাউন্টে পরিচিতি তৈরি করা হয়েছে, এই অ্যাপ সেই অ্যাকাউন্টও অ্যাক্সেস করতে পারবে। আপনার ইনস্টল করা কোনও অ্যাপ অ্যাকাউন্ট তৈরি করলে এটির মধ্যে সেটিও থাকতে পারে। এই অনুমতি অ্যাপকে আপনার পরিচিতি সংক্রান্ত ডেটা সেভ করতে দেয় এবং ক্ষতিকারক অ্যাপ আপনাকে না জানিয়ে পরিচিতি সংক্রান্ত ডেটা শেয়ার করতে পারে।"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"এই অ্যাপকে আপনার ফোনে পরিচিতি সম্পর্কে সেভ করা ডেটা পড়ার অনুমতি দেয়। আপনার ফোনের যেসব অ্যাকাউন্ট পরিচিতি তৈরি করা হয়েছে, এই অ্যাপ সেই অ্যাকাউন্টও অ্যাক্সেস করতে পারবে। আপনার ইনস্টল করা কোনও অ্যাপ অ্যাকাউন্ট তৈরি করলে এটির মধ্যে সেটিও থাকতে পারে। এই অনুমতি অ্যাপকে আপনার পরিচিতি সংক্রান্ত ডেটা সেভ করতে দেয় এবং ক্ষতিকারক অ্যাপ আপনাকে না জানিয়ে পরিচিতি সংক্রান্ত ডেটা শেয়ার করতে পারে।"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"আপনার পরিচিতিগুলি সংশোধন করুন"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"অ্যাপ্লিকেশনটিকে আপনি নির্দিষ্ট একজন পরিচিতির সঙ্গে যে ফ্রিকোয়েন্সিতে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ট্যাবলেটে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পরিবর্তন করতে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশনগুলিকে আপনার পরিচিতি ডেটা মুছতে দেয়৷"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"এই অ্যাপকে Android TV ডিভাইসে পরিচিতি সম্পর্কে সেভ করা ডেটা পরিবর্তন করার অনুমতি দেয়, এক্ষেত্রে নির্দিষ্ট পরিচিতিকে আপনি কত ঘন ঘন কল, ইমেল বা তার সাথে অন্য কোনও মাধ্যমে যোগাযোগ করেছেন তাও অন্তর্ভুক্ত। এই অনুমতি পেলে কোনও অ্যাপ আপনার পরিচিতির ডেটা মুছে ফেলতে পারে।"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"অ্যাপ্লিকেশনটিকে আপনি নির্দিষ্ট একজন পরিচিতির সঙ্গে যে ফ্রিকোয়েন্সিতে কল, ইমেল বা যোগাযোগ করেছেন তা সহ আপনার ফোনে সঞ্চিত পরিচিতিগুলি সম্পর্কে ডেটা পরিবর্তন করতে অনুমতি দেয়৷ এই অনুমতি অ্যাপ্লিকেশনগুলিকে আপনার পরিচিতি ডেটা মুছতে দেয়৷"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"এই অ্যাপকে আপনার ট্যাবলেটে পরিচিতি সম্পর্কে সেভ করা ডেটা পরিবর্তন করার অনুমতি দেয়। এই অনুমতি অ্যাপকে যোগাযোগ সংক্রান্ত ডেটা মুছতে দেয়।"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"এই অ্যাপকে Android TV ডিভাইসে পরিচিতি সম্পর্কে সেভ করা ডেটা পরিবর্তন করার অনুমতি দেয়। এই অনুমতি অ্যাপকে যোগাযোগ সংক্রান্ত ডেটা মুছতে দেয়।"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"এই অ্যাপকে আপনার ফোনে পরিচিতি সম্পর্কে সেভ করা ডেটা পরিবর্তন করার অনুমতি দেয়। এই অনুমতি অ্যাপকে যোগাযোগ সংক্রান্ত ডেটা মুছতে দেয়।"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"কল লগ পড়ুন"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"এই অ্যাপটি আপনার কলের ইতিহাস পড়তে পারে৷"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"কল লগ লিখুন"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"অতিরিক্ত লোকেশন প্রদানকারী কমান্ডগুলি অ্যাক্সেস করে"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"লোকেশনের সাথে সম্পর্কিত তথ্য প্রদানকারীর অতিরিক্ত কম্যান্ডগুলিকে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷ এটি অ্যাপ্লিকেশানটিকে GPS অথবা অন্যান্য লোকেশন নির্ণয়ের সাথে সম্পর্কিত উৎসগুলির ক্রিয়াপ্রণালীর নিয়ন্ত্রণকে মঞ্জুর করতে পারে৷"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"শুধুমাত্র অ্যাপটি খোলা থাকলে আপনার যথাযথ লোকেশন অ্যাক্সেস করা"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"এই অ্যাপটি ফোরগ্রাউন্ডে চলতে থাকলে যেকোনও সময়ে আপনার যথাযথ লোকেশন জানতে পারবে। এই লোকেশন পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং আপনার ফোনে সেগুলি উপলভ্য থাকতে হবে যাতে অ্যাপটি সেগুলি ব্যবহার করতে পারে। এর জন্য অতিরিক্ত ব্যাটারি খরচ হতে পারে।"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"শুধুমাত্র খোলা অবস্থায় আনুমানিক লোকেশন (নেটওয়ার্ক ভিত্তিক) অ্যাক্সেস করবে"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"অ্যাপটি শুধুমাত্র খোলা অবস্থায় সেল টাওয়ার এবং ওয়াই-ফাইয়ের মতো নেটওয়ার্ক সোর্স ব্যবহার করে আপনার লোকেশন জানতে পারবে। লোকেশন সংক্রান্ত এই পরিষেবাগুলি অবশ্যই চালু থাকতে হবে এবং আপনার ট্যাবলেটে সেগুলি উপলভ্য থাকতে হবে যাতে অ্যাপটি সেগুলি ব্যবহার করতে পারে।"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"এই অ্যাপ ফোরগ্রাউন্ডে থাকার সময় সেল টাওয়ার ও ওয়াই-ফাই নেটওয়ার্কের মতো নেটওয়ার্ক সোর্স ব্যবহার করে আপনার লোকেশন জানতে পারে। অ্যাপটিকে সেটি ব্যবহার করতে হলে Android TV ডিভাইসে এই লোকেশন পরিষেবা চালু ও উপলভ্য থাকতে হবে।"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"অ্যাপটি শুধুমাত্র খোলা অবস্থায় সেল টাওয়ার এবং ওয়াই-ফাইয়ের মতো নেটওয়ার্ক সোর্স ব্যবহার করে আপনার লোকেশন জানতে পারবে। লোকেশন সংক্রান্ত এই পরিষেবাগুলি অবশ্যই চালু থাকতে হবে এবং আপনার ফোনে সেগুলি উপলভ্য থাকতে হবে যাতে অ্যাপটি সেগুলি ব্যবহার করতে পারে।"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"এই অ্যাপটি ফোরগ্রাউন্ডে চলতে থাকলে যেকোনও সময়ে আপনার যথাযথ লোকেশন জানতে পারবে। তাছাড়াও লোকেশন পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং আপনার ডিভাইসে সেগুলি উপলভ্য থাকতে হবে যাতে অ্যাপটি সেগুলি ব্যবহার করতে পারে। এর জন্য অতিরিক্ত ব্যাটারি খরচ হতে পারে।"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"শুধুমাত্র অ্যাপটি খোলা থাকলে আপনার আনুমানিক লোকেশন অ্যাক্সেস করা"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"এই অ্যাপটি যদি ফোরগ্রাউন্ডে চলতে থাকে তবেই শুধুমাত্র আপনার আনুমানিক লোকেশন জানতে পারবে। আপনার ডিভাইসে লোকেশন পরিষেবা চালু ও উপলভ্য থাকতে হবে, তবেই অ্যাপটি সেগুলি ব্যবহার করতে পারবে।"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"ব্যাকগ্রাউন্ডে লোকেশন অ্যাক্সেস করা"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"আনুমানিক বা একদম যথাযথ লোকেশন অ্যাক্সেস করার অনুমতি দেওয়া হলে এই অ্যাপটি ব্যাকগ্রাউন্ডে চালু থাকাকালীন আপনার লোকেশন অ্যাক্সেস করতে পারবে।"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"ফোরগ্রাউন্ড লোকেশন অ্যাক্সেস করা ছাড়াও, ব্যাকগ্রাউন্ডে চলাকালীন এই অ্যাপটি লোকেশন অ্যাক্সেস করতে পারে।"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"আপনার অডিও সেটিংস পরিবর্তন করে"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"ভলিউম এবং যেখানে স্পিকার আউটপুট হিসাবে ব্যবহৃত হয় সেই সব ক্ষেত্রে গ্লোবাল অডিও সেটিংসের সংশোধন করতে অ্যাপ্লিকেশনটিকে মঞ্জুর করে৷"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"অডিও রেকর্ড"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ট্যাবলেটের ব্লুটুথ কনফিগারেশন দেখতে, এবং যুক্ত ডিভাইসগুলির সাথে সংযোগ স্থাপন এবং সংযোগের অনুরোধ স্বীকার করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"আপনার Android TV ডিভাইসের ব্লুটুথের কনফিগারেশন দেখার এবং পেয়ার করা ডিভাইসের সাথে কানেক্ট করার বা কানেকশন গ্রহণ করার অনুমতি দেয়।"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ফোনের ব্লুটুথ কনফিগারেশন দেখতে, এবং যুক্ত ডিভাইসগুলির সাথে সংযোগ স্থাপন এবং সংযোগের অনুরোধ স্বীকার করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"নিয়ার ফিল্ড কমিউনিকেশন নিয়ন্ত্রণ করে"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"অ্যাপ্লিকেশানকে নিয়ার ফিল্ড কমিউনিকেশন (NFC) ট্যাগ, কার্ড এবং রিডারগুলির সাথে যোগাযোগ করতে দেয়৷"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"আপনার স্ক্রিন লক অক্ষম করুন"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> এর সাথে সংযুক্ত হয়েছে"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ফাইলগুলি দেখতে আলতো চাপ দিন"</string>
<string name="pin_target" msgid="8036028973110156895">"পিন করুন"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"আনপিন করুন"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"অ্যাপের তথ্য"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ডেমো শুরু করা হচ্ছে…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"-এ এই আইটেমগুলি আপডেট করতে চান: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> এবং <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"সেভ করুন"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"না থাক"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"এখনই নয়"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"কখনই নয়"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"আপডেট করুন"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"চালিয়ে যান"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"পাসওয়ার্ড"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"স্প্লিট স্ক্রিন টগল করুন"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"লক স্ক্রিন"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"স্ক্রিনশট"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"পপ-আপ উইন্ডোতে <xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপ।"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এর ক্যাপশন বার।"</string>
</resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index d7bd7a1..58601b5 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -190,8 +190,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Nedostaje aplikacija administratora za radni profil ili je neispravna. Zbog toga su vaš radni profil i povezani podaci izbrisani. Obratite administratoru za pomoć."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Radni profil više nije dostupan na ovom uređaju"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Previše puta ste pokušali otključati uređaj"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator je ustupio uređaj za ličnu upotrebu"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Uređajem se upravlja."</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja ovim uređajem i može pratiti mrežni saobraćaj. Dodirnite za detalje."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti izbrisan"</string>
@@ -384,13 +383,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Omogućava aplikaciji slanje ljepljivih informacija koje ostaju nakon prestanka emitiranja. Pretjeranom upotrebom može se usporiti ili destabilizirati rad Android TV uređaja zbog korištenja previše memorije."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Omogućava aplikaciji slanje ljepljivih informacija koje ostaju nakon prestanka emitiranja. Njihova pretjerana upotreba može usporiti ili destabilizirati rad telefona jer troši previše memorije."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"čitanje vaših kontakata"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Omogućava aplikaciji čitanje podataka o kontaktima koji su pohranjeni na vašem tabletu, uključujući učestalost vaših poziva, slanja e-pošte ili nekog drugog vida komunikacije sa određenim pojedincima. Ovo odobrenje omogućava aplikacijama da pohrane podatke o vašim kontaktima tako da ih zlonamjerne aplikacije mogu podijeliti bez vašeg znanja."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Omogućava aplikaciji da čita podatke o vašim kontaktima pohranjenim na Android TV uređaju, uključujući učestalost poziva, slanja e-poruka ili komuniciranja na bilo koji način s određenim osobama. Ovo odobrenje omogućava aplikacijama da pohrane podatke o vašim kontaktima, a zlonamjerne aplikacije mogu bez vašeg znanja podijeliti ove podatke."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Omogućava aplikaciji čitanje podataka o kontaktima koji su pohranjeni na vašem telefonu, uključujući učestalost vaših poziva, slanja e-pošte ili nekog drugog vida komunikacije sa određenim pojedincima. Ovo odobrenje omogućava aplikacijama da pohrane podatke o vašim kontaktima tako da ih zlonamjerne aplikacije mogu podijeliti bez vašeg znanja."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Dozvoljava aplikaciji da čita podatke o kontaktima pohranjenim na tabletu. Aplikacije će također imati pristup računima na tabletu koji su kreirali kontakte. Ovo može uključivati račune koje su kreirale aplikacije koje ste instalirali. Ovo odobrenje dozvoljava aplikacijama da sačuvaju podatke o kontaktima, a zlonamjerne aplikacije mogu dijeliti te podatke bez vašeg znanja."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Dozvoljava aplikaciji da čita podatke o kontaktima pohranjenim na Android TV uređaju. Aplikacije će također imati pristup računima na Android TV uređaju koji su kreirali kontakte. Ovo može uključivati račune koje su kreirale aplikacije koje ste instalirali. Ovo odobrenje dozvoljava aplikacijama da sačuvaju podatke o kontaktima, a zlonamjerne aplikacije mogu dijeliti te podatke bez vašeg znanja."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Dozvoljava aplikaciji da čita podatke o kontaktima pohranjenim na telefonu. Aplikacije će također imati pristup računima na telefonu koji su kreirali kontakte. Ovo može uključivati račune koje su kreirale aplikacije koje ste instalirali. Ovo odobrenje dozvoljava aplikacijama da sačuvaju podatke o kontaktima, a zlonamjerne aplikacije mogu dijeliti te podatke bez vašeg znanja."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"izmjena podataka o kontaktima"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Omogućava aplikaciji da izmijeni podatke o kontaktima koji su pohranjeni na vašem tabletu, uključujući učestalost vaših poziva, slanje e-pošte, ili neki drugi vid komunikacije sa određenim kontaktima. Ovo odobrenje omogućava aplikaciji da obriše podatke o kontaktima."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Omogućava aplikaciji izmjenu podataka o vašim kontaktima pohranjenim na Android TV uređaju, uključujući učestalost poziva, slanja e-poruka ili komuniciranja na bilo koji način s određenim kontaktima. Ovom dozvolom se aplikacijama omogućava brisanje podataka o kontaktima."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Omogućava aplikaciji da izmijeni podatke o kontaktima koji su pohranjeni na vašem telefonu, uključujući učestalost vaših poziva, slanje e-pošte, ili neki drugi vid komunikacije sa određenim kontaktima. Ovo odobrenje omogućava aplikaciji da izbriše podatke o kontaktima."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Dozvoljava aplikaciji da vrši izmjene podataka o kontaktima pohranjenim na tabletu. Ovo odobrenje dozvoljava aplikacijama da izbrišu podatke o kontaktima."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Dozvoljava aplikaciji da vrši izmjene podataka o kontaktima pohranjenim na Android TV uređaju. Ovo odobrenje dozvoljava aplikacijama da izbrišu podatke o kontaktima."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Dozvoljava aplikaciji da vrši izmjene podataka o kontaktima pohranjenim na telefonu. Ovo odobrenje dozvoljava aplikacijama da izbrišu podatke o kontaktima."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"čitanje zapisnika poziva"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Ova aplikacija može čitati historiju vaših poziva."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"pisanje zapisnika poziva"</string>
@@ -410,13 +409,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"pristup dodatnim informacijama o lokaciji"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Dozvoljava aplikaciji pristup dodatnim naredbama pružatelja lokacija. Ovim se aplikaciji može dozvoliti da ometa rad GPS-a ili drugih izvora lokacija."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"pristup tačnoj lokaciji samo u prvom planu"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Ova aplikacija može odrediti vašu tačnu lokaciju samo kada je u prvom planu. Ove usluge lokacije moraju biti uključene i dostupne na vašem telefonu da ih aplikacija može koristiti. To može dovesti do povećane potrošnje baterije."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"pristup približnoj lokaciji (utvrđena preko mreže) samo u prvom planu"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Ova aplikacija može odrediti vašu lokaciju na osnovu izvora mreže kao što su predajnici za mobilnu mrežu i WiFi mreže ali samo kada je aplikacija u prvom planu. Ove usluge za određivanje lokacije moraju biti uključene i omogućene na vašem tabletu kako bi ih aplikacija mogla koristiti."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Ova aplikacija može odrediti vašu lokaciju na osnovu izvora mreže kao što su predajnici za mobilnu mrežu i WiFi mreže, ali samo kada je aplikacija u prvom planu. Te usluge za određivanje lokacije moraju biti uključene i omogućene na vašem Android TV uređaju kako bi ih aplikacija mogla koristiti."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Ova aplikacija može odrediti vašu lokaciju na osnovu izvora mreže kao što su predajnici za mobilnu mrežu i WiFi mreže ali samo kada je aplikacija u prvom planu. Ove usluge za određivanje lokacije moraju biti uključene i omogućene na vašem telefonu kako bi ih aplikacija mogla koristiti."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Ova aplikacija može odrediti vašu tačnu lokaciju samo kada je u prvom planu. Usluge lokacije moraju biti uključene i dostupne na uređaju da ih aplikacija može koristiti. To može dovesti do povećane potrošnje baterije."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"pristup približnoj lokaciji samo u prvom planu"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Ova aplikacija može odrediti vašu približnu lokaciju samo kada je u prvom planu. Usluge lokacije moraju biti uključene i dostupne na uređaju da ih aplikacija može koristiti."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"pristup lokaciji u pozadini"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Ako je ovo odobreno, pored pristupa približnoj ili tačnoj lokaciji, aplikacija može pristupiti lokaciji dok radi u pozadini."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Ova aplikacija može pristupati lokaciji dok radi u pozadini, pored pristupa lokaciji u prvom planu."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"izmjene postavki zvuka"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Omogućava aplikaciji izmjenu općih postavki zvuka, kao što su jačina zvuka i izbor izlaznog zvučnika."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"snimanje audiozapisa"</string>
@@ -497,6 +494,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Omogućava aplikaciji prikaz konfiguracije za Bluetooth na tabletu, kao i uspostavljanje i prihvatanje veza sa uparenim uređajima."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Omogućava aplikaciji da prikaže konfiguraciju Bluetootha na Android TV uređaju te uspostavi i prihvati vezu s uparenim uređajima."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Omogućava aplikaciji prikaz konfiguracije za Bluetooth na telefonu, kao i uspostavljanje i prihvatanje veza sa uparenim uređajima."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"upravljanje NFC-om"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Dozvoljava aplikaciji komuniciranje sa NFC (komunikacija bliskog polja) oznakama, karticama i čitačima."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"deaktivacija zaključavanja ekrana"</string>
@@ -1896,7 +1897,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Povezan na uređaj <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Dodirnite za prikaz fajlova"</string>
<string name="pin_target" msgid="8036028973110156895">"Zakači"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Otkači"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Informacije o aplikaciji"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Pokretanje demonstracije…"</string>
@@ -1940,6 +1945,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Ažurirati ove stavke u "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Sačuvaj"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Ne, hvala"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne sada"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nikada"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Ažuriraj"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Nastavi"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"lozinka"</string>
@@ -2036,5 +2043,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Uključi/isključi podijeljeni ekran"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključavanje ekrana"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snimak ekrana"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u skočnom prozoru."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Traka za natpis aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 1f7d82e..6e758aa 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Falta l\'aplicació d\'administració del perfil professional o està malmesa. Com a conseqüència, s\'han suprimit el teu perfil professional i les dades relacionades. Contacta amb l\'administrador per obtenir ajuda."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"El teu perfil professional ja no està disponible en aquest dispositiu"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Has intentat introduir la contrasenya massa vegades"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrador ha cedit el dispositiu per a ús personal"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"El dispositiu està gestionat"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"La teva organització gestiona aquest dispositiu i és possible que supervisi el trànsit de xarxa. Toca per obtenir més informació."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"El contingut del dispositiu s\'esborrarà"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permet que l\'aplicació enviï emissions fixes, que es conserven després de finalitzar l\'emissió. L\'ús excessiu pot provocar que el dispositiu Android TV utilitzi massa memòria i s\'alenteixi o es desestabilitzi."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permet que l\'aplicació enviï emissions permanents, que es conserven després de finalitzar l\'emissió. L\'ús excessiu pot alentir o desestabilitzar el telèfon si li fan utilitzar massa memòria."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"consultar els contactes"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Permet que l\'aplicació llegeixi dades sobre els contactes que tinguis emmagatzemats a la tauleta, inclosa la freqüència amb què has trucat, has enviat correus electrònics o t\'has comunicat d\'altres maneres amb persones concretes. Aquest permís permet que les aplicacions desin les dades dels teus contactes, i és possible que les aplicacions malicioses comparteixin dades dels contactes sense el teu coneixement."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Permet que l\'aplicació llegeixi dades sobre els contactes emmagatzemades al dispositiu Android TV, inclosa la freqüència amb què has trucat a contactes concrets, els has enviat correus electrònics o t\'hi has comunicat d\'altres maneres. Aquest permís permet que les aplicacions desin les dades dels teus contactes; és possible que les aplicacions malicioses comparteixin dades dels contactes sense que ho sàpigues."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Permet que l\'aplicació llegeixi dades sobre els contactes que tinguis emmagatzemats al telèfon, inclosa la freqüència amb què has trucat, has enviat correus electrònics o t\'has comunicat d\'altres maneres amb persones concretes. Aquest permís permet que les aplicacions desin les dades dels teus contactes, i és possible que les aplicacions malicioses comparteixin dades dels contactes sense el teu coneixement."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permet que l\'aplicació llegeixi les dades dels contactes que tens emmagatzemats a la tauleta. Les aplicacions també tindran accés als comptes de la tauleta que hagin creat contactes. Això pot incloure els comptes creats per les aplicacions que hi tens instal·lades. Les aplicacions amb aquest permís poden desar les dades dels teus contactes, i és possible que les aplicacions malicioses comparteixin dades dels contactes sense el teu coneixement."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permet que l\'aplicació llegeixi les dades dels contactes que tens emmagatzemats al dispositiu Android TV. Les aplicacions també tindran accés als comptes del teu dispositiu Android TV que hagin creat contactes. Això pot incloure els comptes creats per les aplicacions que hi tens instal·lades. Les aplicacions amb aquest permís poden desar les dades dels teus contactes, i és possible que les aplicacions malicioses comparteixin dades dels contactes sense el teu coneixement."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permet que l\'aplicació llegeixi les dades dels contactes que tens emmagatzemats al telèfon. Les aplicacions també tindran accés als comptes del telèfon que hagin creat contactes. Això pot incloure els comptes creats per les aplicacions que hi tens instal·lades. Les aplicacions amb aquest permís poden desar les dades dels teus contactes, i és possible que les aplicacions malicioses comparteixin dades dels contactes sense el teu coneixement."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modificar els teus contactes"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Permet que l\'aplicació modifiqui les dades sobre contactes emmagatzemades a la tauleta, inclosa la freqüència amb què has trucat, has enviat correus electrònics o t\'has comunicat d\'altres maneres amb contactes concrets. Aquest permís permet que les aplicacions suprimeixin dades de contactes."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Permet que l\'aplicació modifiqui les dades sobre els contactes emmagatzemades al dispositiu Android TV, com ara la freqüència amb què has trucat a contactes concrets, els has enviat correus electrònics o t\'hi has comunicat d\'altres maneres. Amb aquest permís, les aplicacions poden suprimir les dades dels contactes."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Permet que l\'aplicació modifiqui les dades sobre contactes emmagatzemades al telèfon, inclosa la freqüència amb què has trucat, has enviat correus electrònics o t\'has comunicat d\'altres maneres amb contactes concrets. Aquest permís permet que les aplicacions suprimeixin dades de contactes."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permet que l\'aplicació modifiqui les dades dels contactes que tens emmagatzemats a la tauleta. Amb aquest permís, les aplicacions poden suprimir les dades dels contactes."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permet que l\'aplicació modifiqui les dades dels contactes que tens emmagatzemats al dispositiu Android TV. Amb aquest permís, les aplicacions poden suprimir les dades dels contactes."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permet que l\'aplicació modifiqui les dades dels contactes que tens emmagatzemats al telèfon. Amb aquest permís, les aplicacions poden suprimir les dades dels contactes."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"lectura del registre de trucades"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Aquesta aplicació pot llegir el teu historial de trucades."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"escriptura del registre de trucades"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"accedir a ordres del proveïdor d\'ubicació addicionals"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permet que l\'aplicació accedeixi a ordres addicionals del proveïdor d\'ubicacions; per tant, és possible que l\'aplicació pugui interferir en el funcionament del GPS o d\'altres fonts d\'ubicacions."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"accedeix a la ubicació exacta només en primer pla"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Aquesta aplicació pot obtenir la teva ubicació exacta només quan està en primer pla. Aquests serveis d\'ubicació han d\'estar activats i disponibles al telèfon perquè l\'aplicació els pugui utilitzar, i això pot fer que el consum de bateria augmenti."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"accedeix a la ubicació aproximada (basada en xarxa) només en primer pla"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Aquesta aplicació pot obtenir la teva ubicació a partir de fonts de xarxa, com ara torres de telefonia mòbil i xarxes Wi‑Fi, però només quan està en primer pla. Aquests serveis d\'ubicació han d\'estar activats i disponibles a la tauleta perquè l\'aplicació els pugui utilitzar."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Aquesta aplicació pot obtenir la teva ubicació a partir de fonts de xarxa, com ara torres de telefonia mòbil i xarxes Wi‑Fi, però només quan està en primer pla. Aquests serveis d\'ubicació han d\'estar activats i disponibles al dispositiu Android TV perquè l\'aplicació els pugui utilitzar."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Aquesta aplicació pot obtenir la teva ubicació a partir de fonts de xarxa, com ara torres de telefonia mòbil i xarxes Wi‑Fi, però només quan està en primer pla. Aquests serveis d\'ubicació han d\'estar activats i disponibles al telèfon perquè l\'aplicació els pugui utilitzar."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Aquesta aplicació pot obtenir la teva ubicació exacta només quan està en primer pla. Els serveis d\'ubicació han d\'estar activats i disponibles al dispositiu perquè l\'aplicació els pugui utilitzar, i això pot fer que el consum de bateria augmenti."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"accedeix a la ubicació aproximada només en primer pla"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Aquesta aplicació pot obtenir la teva ubicació aproximada només quan està en primer pla. Els serveis d\'ubicació han d\'estar activats i disponibles al dispositiu perquè l\'aplicació els pugui utilitzar."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"accedir a la ubicació en segon pla"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Si es concedeix aquest permís, a més de l\'accés a la ubicació aproximada o exacta, l\'aplicació pot accedir a la ubicació mentre s\'executa en segon pla."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Aquesta aplicació pot accedir a la ubicació mentre s\'executa en segon pla, a més de poder fer-ho en primer pla."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"canviar la configuració d\'àudio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permet que l\'aplicació modifiqui la configuració d\'àudio general, com ara el volum i l\'altaveu de sortida que es fa servir."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"gravar àudio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permet que l\'aplicació visualitzi la configuració del Bluetooth de la tauleta i que estableixi i accepti connexions amb dispositius sincronitzats."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permet que l\'aplicació visualitzi la configuració del Bluetooth del dispositiu Android TV i que estableixi i accepti connexions amb dispositius vinculats."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permet que una aplicació visualitzi la configuració del Bluetooth del telèfon i que estableixi i accepti connexions amb els dispositius sincronitzats."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicació de camp proper (NFC)"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Permet que l\'aplicació es comuniqui amb les etiquetes, les targetes i els lectors de Comunicació de camp proper (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"desactivació del bloqueig de pantalla"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"S\'ha connectat a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Toca per veure els fitxers"</string>
<string name="pin_target" msgid="8036028973110156895">"Fixa"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"No fixis"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Informació de l\'aplicació"</string>
<string name="negative_duration" msgid="1938335096972945232">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"S\'està iniciant la demostració…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Vols actualitzar <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g> a "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Desa"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"No, gràcies"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ara no"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Mai"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Actualitza"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continua"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"contrasenya"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Commuta Pantalla dividida"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Pantalla de bloqueig"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de pantalla"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplicació <xliff:g id="APP_NAME">%1$s</xliff:g> a la finestra emergent."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de títol de l\'aplicació <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index e05f299..9dbefad 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -192,8 +192,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikace pro správu pracovního profilu chybí nebo je poškozena. Váš pracovní profil a související data proto byla smazána. Požádejte o pomoc administrátora."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Váš pracovní profil v tomto zařízení již není k dispozici"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Příliš mnoho pokusů o zadání hesla"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrátor zařízení uvolnil k osobnímu používání"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Zařízení je spravováno"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Toto zařízení je spravováno vaší organizací, která může sledovat síťový provoz. Podrobnosti zobrazíte klepnutím."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Zařízení bude vymazáno"</string>
@@ -387,13 +386,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Umožňuje aplikaci odesílat trvalá vysílání, která přetrvávají i po skončení. Nadměrné používání může zařízení Android TV zpomalit či způsobit jeho nestabilitu, protože bude používat příliš mnoho paměti."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Umožňuje aplikaci odesílat trvalá vysílání, která přetrvávají i po skončení vysílání. Nadměrné používání může telefon zpomalit či způsobit jeho nestabilitu, protože bude používat příliš mnoho paměti."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"čtení kontaktů"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Umožňuje aplikaci číst údaje o kontaktech uložených v tabletu, včetně toho, jak často voláte, posíláte e‑maily nebo jinak komunikujete s konkrétními osobami. Toto oprávnění umožňuje aplikacím ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Umožňuje aplikaci číst údaje o kontaktech uložených v zařízení Android TV, včetně toho, jak často voláte, posíláte e‑maily nebo jinými způsoby komunikujete s konkrétními osobami. Toto oprávnění aplikacím umožňuje ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Umožňuje aplikaci číst údaje o kontaktech uložených v telefonu, včetně toho, jak často voláte, posíláte e‑maily nebo komunikujete jinými způsoby s konkrétními osobami. Toto oprávnění umožňuje aplikacím ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Umožňuje aplikaci číst údaje o kontaktech uložené v tabletu. Aplikace také budou mít přístup k účtům v tabletu, pomocí kterých byly vytvořeny kontakty. Může se jednat i o účty vytvořené aplikacemi, které jste nainstalovali. Toto oprávnění aplikacím umožňuje ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Umožňuje aplikaci číst údaje o kontaktech uložené v zařízení Android TV. Aplikace také budou mít přístup k účtům v zařízení Android TV, pomocí kterých byly vytvořeny kontakty. Může se jednat i o účty vytvořené aplikacemi, které jste nainstalovali. Toto oprávnění aplikacím umožňuje ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Umožňuje aplikaci číst údaje o kontaktech uložené v telefonu. Aplikace také budou mít přístup k účtům v telefonu, pomocí kterých byly vytvořeny kontakty. Může se jednat i o účty vytvořené aplikacemi, které jste nainstalovali. Toto oprávnění aplikacím umožňuje ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"úprava kontaktů"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Umožňuje aplikaci upravit údaje o kontaktech uložených v tabletu včetně toho, jak často voláte, posíláte e‑maily nebo komunikujete jinými způsoby s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Umožňuje aplikaci upravit údaje o kontaktech uložených v zařízení Android TV včetně toho, jak často voláte, posíláte e‑maily nebo komunikujete jinými způsoby s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Umožňuje aplikaci upravit údaje o kontaktech uložených v telefonu včetně toho, jak často voláte, posíláte e‑maily nebo komunikujete jinými způsoby s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Umožňuje aplikaci upravovat údaje o kontaktech uložené v tabletu. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Umožňuje aplikaci upravovat údaje o kontaktech uložené v zařízení Android TV. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Umožňuje aplikaci upravovat údaje o kontaktech uložení v telefonu. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"čtení seznamu hovorů"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Tato aplikace může číst historii volání."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"zápis do seznamu hovorů"</string>
@@ -413,13 +412,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"přístup k dalším příkazům poskytovatele polohy"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Umožňuje aplikaci přístup k dalším příkazům poskytovatele polohy. To aplikaci umožní zasahovat do fungování systému GPS a dalších zdrojů polohy."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"přístup k přesné poloze jen na popředí"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Tato aplikace může zjistit vaši přesnou polohu, jen když běží na popředí. Aby tyto služby určování polohy mohla aplikace používat, musí být v telefonu dostupné a musí být zapnuté. Tyto služby mohou způsobit rychlejší vybíjení baterie."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"přístup k přibližené poloze (na základě sítě) jen na popředí"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Tato aplikace může zjistit vaši polohu podle zdrojů sítě, jako jsou vysílací věže nebo sítě Wi-Fi (ale pouze pokud je aplikace na popředí). Aby tyto služby určování polohy mohla aplikace používat, musí být v tabletu dostupné a musí být zapnuté."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Tato aplikace může zjistit vaši polohu podle zdrojů sítě, jako jsou vysílací věže nebo sítě Wi-Fi (ale pouze pokud je aplikace na popředí). Aby tyto služby určování polohy mohla aplikace používat, musí být v zařízení Android TV dostupné a musí být zapnuté."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Tato aplikace může zjistit vaši polohu podle zdrojů sítě, jako jsou vysílací věže nebo sítě Wi-Fi (ale pouze pokud je aplikace na popředí). Aby tyto služby určování polohy mohla aplikace používat, musí být v telefonu dostupné a musí být zapnuté."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Tato aplikace může zjistit vaši přesnou polohu, jen když běží na popředí. Aby aplikace mohla služby určování polohy používat, musí být v zařízení dostupné a musí být zapnuté. To může vést k rychlejšímu vybíjení baterie."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"přístup k přibližné poloze jen na popředí"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Tato aplikace může zjistit vaši přibližnou polohu, jen když běží na popředí. Aby aplikace mohla služby určování polohy používat, musí být v zařízení dostupné a musí být zapnuté."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"přístup k poloze na pozadí"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Bude-li oprávnění uděleno dodatečně k přístupu k přibližné nebo přesné poloze, aplikace bude moci používat polohu při spuštění na pozadí."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Tato aplikace má přístup k poloze, nejen když je v popředí, ale i když běží na pozadí."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"změna nastavení zvuku"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Umožňuje aplikaci změnit globální nastavení zvuku, například hlasitost či reproduktor pro výstup zvuku."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"nahrávání zvuku"</string>
@@ -500,6 +497,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Umožňuje aplikaci zobrazit konfiguraci tabletu s rozhraním Bluetooth, vytvářet připojení ke spárovaným zařízením a přijímat tato připojení."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Umožňuje aplikaci zobrazit konfiguraci rozhraním Bluetooth na zařízení Android TV a vytvářet a přijímat připojení ke spárovaným zařízením."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Umožňuje aplikaci zobrazit konfiguraci telefonu s rozhraním Bluetooth, vytvářet připojení ke spárovaným zařízením a přijímat tato připojení."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ovládání technologie NFC"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Umožňuje aplikaci komunikovat se štítky, kartami a čtečkami s podporou technologie NFC."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"vypnutí zámku obrazovky"</string>
@@ -1926,7 +1927,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Připojeno k zařízení <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Klepnutím zobrazíte soubory"</string>
<string name="pin_target" msgid="8036028973110156895">"Připnout"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Odepnout"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"O aplikaci"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Spouštění ukázky…"</string>
@@ -1971,6 +1976,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Aktualizovat tyto položky ve službě "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> a <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Uložit"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Ne, děkuji"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Teď ne"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nikdy"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Aktualizovat"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Pokračovat"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"heslo"</string>
@@ -2068,5 +2075,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Přepnout rozdělenou obrazovku"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Obrazovka uzamčení"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snímek obrazovky"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> ve vyskakovacím okně."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Popisek aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 772b7b0..151becd 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Administrationsappen til arbejdsprofilen mangler eller er beskadiget. Derfor er din arbejdsprofil og dine relaterede data blevet slettet. Kontakt din administrator for at få hjælp."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Din arbejdsprofil er ikke længere tilgængelig på denne enhed"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"For mange mislykkede adgangskodeforsøg"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratoren har gjort personlig brug af enheden utilgængelig"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Dette er en administreret enhed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Din organisation administrerer denne enhed og kan overvåge netværkstrafik. Tryk for at se info."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Enheden slettes"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Tillader, at appen kan sende klæbende udsendelser, der forbliver, når udsendelsen er slut. Overdreven brug kan gøre din Android TV-enhed langsom eller ustabil, da det tvinger den til at bruge for meget hukommelse."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Tillader, at appen kan sende klæbende udsendelser, der forbliver tilbage, når udsendelsen er slut. Overdreven brug kan gøre din telefon langsom eller ustabil ved at tvinge den til at bruge for meget hukommelse."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"læse dine kontakter"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Tillader, at appen kan læse data om de kontakter, der er gemt på din tablet, f.eks. hvor ofte du har ringet til, sendt mail til eller på anden måde kommunikeret med bestemte personer. Med denne tilladelse kan apps gemme dine kontaktdata, og skadelige apps kan dele kontaktdata uden din viden."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Tillader, at appen kan læse gemte data på din Android TV-enhed om dine kontakter, bl.a. hvor ofte du har ringet til dem, sendt mail til dem eller på anden måde kommunikeret med bestemte personer. Denne tilladelse giver apps mulighed for at gemme dine kontaktdata, og skadelige apps kan dele kontaktdata uden din viden."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Tillader, at appen kan læse data om de kontakter, der er gemt på din telefon, f.eks. hvor ofte du har ringet til, sendt mail til eller på anden måde kommunikeret med bestemte personer. Med denne tilladelse kan apps gemme dine kontaktdata, og skadelige apps kan dele kontaktdata uden din viden."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Tillader, at appen kan læse data om de kontakter, der er gemt på din tablet. Apps får også adgang til de konti på din tablet, som har oprettet kontakter. Dette kan omfatte konti, som er oprettet af apps, du har installeret. Med denne tilladelse kan apps gemme dine kontaktdata, og skadelige apps kan dele kontaktdata uden din viden."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Tillader, at appen kan læse data om de kontakter, der er gemt på din Android TV-enhed. Apps får også adgang til de konti på din Android TV-enhed, som har oprettet kontakter. Dette kan omfatte konti, som er oprettet af apps, du har installeret. Med denne tilladelse kan apps gemme dine kontaktdata, og skadelige apps kan dele kontaktdata uden din viden."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Tillader, at appen læser data om de kontakter, der er gemt på din telefon. Apps får også adgang til de konti på din telefon, som har oprettet kontakter. Dette kan omfatte konti, som er oprettet af apps, du har installeret. Med denne tilladelse kan apps gemme dine kontaktdata, og skadelige apps kan dele kontaktdata uden din viden."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"ændre dine kontakter"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Tillader, at appen kan ændre data om de kontakter, der er gemt på din tablet, f.eks. hvor ofte du har ringet til dem, sendt dem en mail eller på anden måde kommunikeret med bestemte kontakter. Med denne tilladelse kan apps slette kontaktoplysninger."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Tillader, at appen kan ændre data om de kontakter, der er gemt på din Android TV-enhed, bl.a. hvor ofte du har ringet til dem, sendt en mail til dem eller på anden måde kommunikeret med bestemte kontakter. Med denne tilladelse kan apps slette kontaktoplysninger."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Tillader, at appen kan ændre data om de kontakter, der er gemt på din telefon, f.eks. hvor ofte du har ringet til dem, sendt en mail til dem eller på anden måde kommunikeret med bestemte kontakter. Med denne tilladelse kan apps slette kontaktoplysninger."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Tillader, at appen kan ændre data om de kontakter, der er gemt på din tablet. Denne tilladelse giver apps mulighed for at slette kontaktdata."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Tillader, at appen kan ændre data om de kontakter, der er gemt på din Android TV-enhed. Denne tilladelse giver apps mulighed for at slette kontaktdata."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Tillader, at appen kan ændre data om de kontakter, der er gemt på din telefon. Denne tilladelse giver apps mulighed for at slette kontaktdata."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"læse opkaldsliste"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Denne app kan læse din opkaldshistorik."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"skriv opkaldsliste"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"få adgang til yderligere kommandoer for placeringsudbyder"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Tillader, at appen kan få adgang til yderligere kommandoer for placeringsudbydere. Dette kan gøre det muligt for appen at forstyrre GPS-funktionen eller andre placeringskilder."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"få kun adgang til nøjagtig placering i forgrunden"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Denne app kan kun få din nøjagtige placering, når den er i forgrunden. Disse placeringstjenester skal være aktiverede og tilgængelige på din telefon, før appen kan bruge dem. Dette kan øge batteriforbruget."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"få kun adgang til omtrentlig placering (netværksbaseret) i forgrunden"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Denne app kan fastslå din placering ved hjælp af netværkskilder som f.eks. mobilmaster og Wi-Fi-netværk, men kun når appen er i forgrunden. Disse placeringstjenester skal være aktiverede og tilgængelige på din tablet, før appen kan bruge dem."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Denne app kan fastslå din placering ved hjælp af netværkskilder som f.eks. mobilmaster og Wi-Fi-netværk, men kun når appen er i forgrunden. Disse placeringstjenester skal være aktiverede og tilgængelige på din Android TV-enhed, før appen kan bruge dem."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Denne app kan fastslå din placering ved hjælp af netværkskilder som f.eks. mobilmaster og Wi-Fi-netværk, men kun når appen er i forgrunden. Disse placeringstjenester skal være aktiveret og tilgængelige på din telefon, før appen kan bruge dem."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Denne app kan kun finde din nøjagtige placering, når den er i forgrunden. Placeringstjenester skal være aktiverede og tilgængelige på din telefon, før appen kan anvende dem. Dette kan øge batteriforbruget."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"få kun adgang til omtrentlig placering i forgrunden"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Denne app kan kun finde din omtrentlige placering, når den er i forgrunden. Placeringstjenester skal være aktiverede og tilgængelige på din enhed, før appen kan anvende dem."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"adgang til placering i baggrunden"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Hvis appen godkendes, og der gives adgang til den omtrentlige eller nøjagtige placering, kan appen registrere placeringen, mens den kører i baggrunden."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Foruden adgang til placering ved kørsel i forgrunden har denne app også adgang til din placering, mens den kører i baggrunden."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"skifte dine lydindstillinger"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Tillader, at appen kan ændre globale lydindstillinger, som f.eks. lydstyrke og hvilken højttaler der bruges til output."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"optage lyd"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Tillader, at appen kan læse konfigurationen af Bluetooth på tabletten samt kan oprette og acceptere forbindelser med parrede enheder."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Tillader, at appen kan se konfigurationen af Bluetooth på din Android TV-enhed samt oprette og acceptere forbindelser med parrede enheder."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Tillader, at appen kan læse konfigurationen af Bluetooth på telefonen samt kan oprette og acceptere forbindelser med parrede enheder."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"administrere Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Tillader, at appen kan kommunikere med NFC-tags (Near Field Communication), -kort og -læsere."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"deaktivere din skærmlås"</string>
@@ -900,7 +901,7 @@
<string name="factorytest_no_action" msgid="339252838115675515">"Der blev ikke fundet nogen pakke, som leverer handlingen FACTORY_TEST."</string>
<string name="factorytest_reboot" msgid="2050147445567257365">"Genstart"</string>
<string name="js_dialog_title" msgid="7464775045615023241">"På siden på \"<xliff:g id="TITLE">%s</xliff:g>\" står der:"</string>
- <string name="js_dialog_title_default" msgid="3769524569903332476">"Javascript"</string>
+ <string name="js_dialog_title_default" msgid="3769524569903332476">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="7012587995876771246">"Bekræft navigation"</string>
<string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"Forlad denne side"</string>
<string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"Bliv på denne side"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Tilsluttet <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Tryk for at se filer"</string>
<string name="pin_target" msgid="8036028973110156895">"Fastgør"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Frigør"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Appinfo"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Starter demoen…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Vil du opdatere disse elementer i "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> og <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Gem"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nej tak"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ikke nu"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Aldrig"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Opdater"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Fortsæt"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"adgangskode"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Slå Opdelt skærm til eller fra"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Låseskærm"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g>-appen i et pop op-vindue."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Titellinje for <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index bb29a0e..06610c7 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Die Admin-App für das Arbeitsprofil fehlt oder ist beschädigt. Daher wurden dein Arbeitsprofil und alle zugehörigen Daten gelöscht. Bitte wende dich für weitere Hilfe an deinen Administrator."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Dein Arbeitsprofil ist auf diesem Gerät nicht mehr verfügbar"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Zu viele falsche Passworteingaben"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator hat das Gerät zur persönlichen Nutzung abgegeben"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Dies ist ein verwaltetes Gerät"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Deine Organisation verwaltet dieses Gerät und überprüft unter Umständen den Netzwerkverkehr. Tippe hier, um weitere Informationen zu erhalten."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Die Daten auf deinem Gerät werden gelöscht."</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Ermöglicht der App, dauerhafte Broadcasts zu senden, die auch nach dem Ende des Broadcasts bestehen bleiben. Ein zu intensiver Einsatz kann das Android TV-Gerät langsam oder instabil machen, weil zu viel Arbeitsspeicher belegt wird."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Ermöglicht der App, dauerhafte Broadcasts zu senden, die auch nach Ende des Broadcasts bestehen bleiben. Ein zu intensiver Einsatz kann das Telefon langsam oder instabil machen, weil zu viel Arbeitsspeicher belegt wird."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"Kontakte lesen"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Ermöglicht der App, Daten zu den auf deinem Tablet gespeicherten Kontakten zu lesen, einschließlich der Häufigkeit, mit der du bestimmte Personen angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert hast. Die Berechtigung erlaubt Apps, deine Kontaktdaten zu speichern, und schädliche Apps können Kontaktdaten ohne dein Wissen weiterleiten."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Ermöglicht der App, Daten zu den auf deinem Android TV-Gerät gespeicherten Kontakten zu lesen, einschließlich der Häufigkeit, mit der du mit den einzelnen Kontakten telefonisch, per E‑Mail, oder anderweitig kommuniziert hast. Diese Berechtigung erlaubt Apps, deine Kontaktdaten zu speichern, weshalb schädliche Apps damit Kontaktdaten ohne dein Wissen teilen können."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Ermöglicht der App, Daten zu den auf deinem Telefon gespeicherten Kontakten zu lesen, einschließlich der Häufigkeit, mit der du bestimmte Personen angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert hast. Die Berechtigung erlaubt Apps, deine Kontaktdaten zu speichern, und schädliche Apps können Kontaktdaten ohne dein Wissen weiterleiten."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Ermöglicht der App, Daten zu den auf deinem Tablet gespeicherten Kontakten zu lesen. Darüber hinaus haben Apps Zugriff auf die Konten auf deinem Tablet, über die Kontakte erstellt wurden. Dabei kann es sich auch um Konten handeln, die von installierten Apps erstellt wurden. Diese Berechtigung erlaubt Apps, deine Kontaktdaten zu speichern. Schädliche Apps könnten dadurch ohne dein Wissen Kontaktdaten teilen."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Ermöglicht der App, Daten zu den auf deinem Android TV-Gerät gespeicherten Kontakten zu lesen. Darüber hinaus haben Apps Zugriff auf die Konten auf deinem Android TV-Gerät, über die Kontakte erstellt wurden. Dabei kann es sich auch um Konten handeln, die von installierten Apps erstellt wurden. Diese Berechtigung erlaubt Apps, deine Kontaktdaten zu speichern. Schädliche Apps könnten dadurch ohne dein Wissen Kontaktdaten teilen."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Ermöglicht der App, Daten zu den auf deinem Smartphone gespeicherten Kontakten zu lesen. Darüber hinaus haben Apps Zugriff auf die Konten auf deinem Smartphone, über die Kontakte erstellt wurden. Dabei kann es sich auch um Konten handeln, die von installierten Apps erstellt wurden. Diese Berechtigung erlaubt Apps, deine Kontaktdaten zu speichern. Schädliche Apps könnten dadurch ohne dein Wissen Kontaktdaten teilen."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"Kontakte ändern"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Ermöglicht der App, Daten zu Kontakten, die auf deinem Tablet gespeichert sind, zu ändern, einschließlich der Häufigkeit, mit der du bestimmte Kontakte angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert hast. Die Berechtigung erlaubt Apps, Kontaktdaten zu löschen."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Ermöglicht der App, Daten zu den auf deinem Android TV-Gerät gespeicherten Kontakten zu ändern, einschließlich der Häufigkeit, mit der du mit den einzelnen Kontakten telefonisch, per E‑Mail, oder anderweitig kommuniziert hast. Diese Berechtigung ermöglicht Apps, Kontaktdaten zu löschen."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Ermöglicht der App, Daten zu Kontakten, die auf deinem Telefon gespeichert sind, zu ändern, einschließlich der Häufigkeit, mit der du bestimmte Kontakte angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert hast. Die Berechtigung erlaubt Apps, Kontaktdaten zu löschen."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Ermöglicht der App, Daten zu den auf deinem Tablet gespeicherten Kontakten zu ändern. Diese Berechtigung erlaubt Apps, Kontaktdaten zu löschen."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Ermöglicht der App, Daten zu den auf deinem Android TV-Gerät gespeicherten Kontakten zu ändern. Diese Berechtigung erlaubt Apps, Kontaktdaten zu löschen."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Ermöglicht der App, Daten zu den auf deinem Smartphone gespeicherten Kontakten zu ändern. Diese Berechtigung erlaubt Apps, Kontaktdaten zu löschen."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"Anrufliste lesen"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Diese App kann deine Anrufliste lesen."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"Anrufliste bearbeiten"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"Auf zusätzliche Dienstanbieterbefehle für Standort zugreifen"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Ermöglicht der App, auf zusätzliche Standortanbieterbefehle zuzugreifen. Damit könnte die App die Funktionsweise von GPS oder anderen Standortquellen beeinträchtigen."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"Nur bei Ausführung im Vordergrund auf den genauen Standort zugreifen"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Diese App kann deinen genauen Standort nur dann ermitteln, wenn sie im Vordergrund ausgeführt wird. Die App kann diese Standortdienste nur verwenden, wenn sie auf deinem Smartphone aktiviert und verfügbar sind. Hierdurch kann sich der Akkuverbrauch erhöhen."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"Nur bei Ausführung im Vordergrund auf den ungefähren Standort (netzwerkbasiert) zugreifen"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Diese App kann deinen Standort anhand von Netzwerkquellen wie Mobilfunkmasten und WLANs ermitteln, allerdings nur, wenn sie im Vordergrund ausgeführt wird. Diese Standortdienste müssen auf deinem Tablet aktiviert und verfügbar sein, damit die App sie nutzen kann."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Diese App kann deinen Standort anhand von Netzwerkquellen wie Mobilfunkmasten und WLANs ermitteln, allerdings nur, wenn sie im Vordergrund ausgeführt wird. Damit die App sie nutzen kann, müssen diese Standortdienste auf deinem Android TV-Gerät aktiviert und verfügbar sein."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Diese App kann deinen Standort anhand von Netzwerkquellen wie Mobilfunkmasten und WLANs ermitteln, allerdings nur, wenn sie im Vordergrund ausgeführt wird. Diese Standortdienste müssen auf deinem Smartphone aktiviert und verfügbar sein, damit die App sie nutzen kann."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Diese App kann deinen genauen Standort nur dann ermitteln, wenn sie im Vordergrund ausgeführt wird. Damit die App Standortdienste nutzen kann, müssen sie auf deinem Gerät aktiviert und verfügbar sein. Hierdurch kann sich der Akkuverbrauch erhöhen."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"Nur bei Ausführung im Vordergrund auf den ungefähren Standort zugreifen"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Diese App kann deinen ungefähren Standort nur dann ermitteln, wenn sie im Vordergrund ausgeführt wird. Damit die App Standortdienste nutzen kann, müssen sie auf deinem Gerät aktiviert und verfügbar sein."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"Im Hintergrund auf den Standort zugreifen"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Wenn zusätzlich zum Zugriff auf den ungefähren oder genauen Standort diese Erlaubnis erteilt wird, kann die App bei Ausführung im Hintergrund auf den Standort zugreifen."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Diese App kann bei Ausführung im Vorder- und Hintergrund auf den Standort zugreifen."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"Audio-Einstellungen ändern"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Ermöglicht der App, globale Audio-Einstellungen zu ändern, etwa die Lautstärke und den Lautsprecher für die Ausgabe."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"Audio aufnehmen"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Ermöglicht der App, die Bluetooth-Konfiguration eines Tablets einzusehen und Verbindungen zu gekoppelten Geräten herzustellen und zu akzeptieren."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Ermöglicht der App, die Bluetooth-Konfiguration des Android TV-Geräts abzurufen und Verbindungen zu gekoppelten Geräten herzustellen und zu akzeptieren."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Ermöglicht der App, die Bluetooth-Konfiguration des Telefons einzusehen und Verbindungen mit gekoppelten Geräten herzustellen und zu akzeptieren."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"Nahfeldkommunikation steuern"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Ermöglicht der App die Kommunikation mit Tags für die Nahfeldkommunikation, Karten und Readern"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"Displaysperre deaktivieren"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Verbunden mit <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Zum Ansehen der Dateien tippen"</string>
<string name="pin_target" msgid="8036028973110156895">"Markieren"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Markierung entfernen"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"App-Informationen"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Demo wird gestartet…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> und <xliff:g id="TYPE_2">%3$s</xliff:g> in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" aktualisieren?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Speichern"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nein danke"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Nicht jetzt"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nie"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Aktualisieren"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Fortsetzen"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"Passwort"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"\"Bildschirm teilen\" ein-/ausschalten"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Sperrbildschirm"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"App \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" im Pop-up-Fenster."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Untertitelleiste von <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 807c4c2..4e6d695 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Η εφαρμογή διαχείρισης προφίλ εργασίας είτε λείπει είτε είναι κατεστραμμένη. Ως αποτέλεσμα, διαγράφηκε το προφίλ εργασίας και τα σχετικά δεδομένα. Επικοινωνήστε με τον διαχειριστή σας για βοήθεια."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Το προφίλ εργασίας σας δεν είναι πια διαθέσιμο σε αυτήν τη συσκευή"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Πάρα πολλές προσπάθειες εισαγωγής κωδικού πρόσβασης"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Συσκευή από την οποία αποσύρθηκε ο διαχειριστής για προσωπική χρήση"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Η συσκευή είναι διαχειριζόμενη"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ο οργανισμός σας διαχειρίζεται αυτήν τη συσκευή και ενδέχεται να παρακολουθεί την επισκεψιμότητα δικτύου. Πατήστε για λεπτομέρειες."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Η συσκευή σας θα διαγραφεί"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Επιτρέπει στην εφαρμογή την αποστολή μεταδόσεων που παραμένουν μετά το τέλος της διαδικασίας μετάδοσης. Η υπερβολική χρήση αυτής της δυνατότητας μπορεί να καταστήσει τη λειτουργία της συσκευής Android TV αργή ή ασταθή λόγω της χρήσης πολλής μνήμης."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Επιτρέπει στην εφαρμογή την αποστολή εκπομπών sticky, οι οποίες παραμένουν μετά το τέλος της εκπομπής. Η υπερβολική χρήση ενδέχεται να καταστήσει τη λειτουργία του τηλεφώνου αργή ή ασταθή, προκαλώντας τη χρήση μεγάλου τμήματος της μνήμης."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"διαβάζει τις επαφές σας"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Επιτρέπει στην εφαρμογή την ανάγνωση δεδομένων σχετικά με τις επαφές σας που είναι αποθηκευμένες στο tablet σας, συμπεριλαμβανομένης της συχνότητας με την οποία έχετε καλέσει συγκεκριμένα άτομα ή έχετε επικοινωνήσει μαζί τους μέσω ηλεκτρονικού ταχυδρομείου ή άλλου τρόπου. Αυτή η άδεια δίνει τη δυνατότητα σε εφαρμογές να αποθηκεύουν τα δεδομένα των επαφών σας και οι κακόβουλες εφαρμογές ενδέχεται να μοιράζονται δεδομένα επαφών χωρίς να το γνωρίζετε."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Επιτρέπει στην εφαρμογή να διαβάζει τα δεδομένα που αποθηκεύονται στη συσκευή Android TV σχετικά με τις επαφές σας, συμπεριλαμβανομένης της συχνότητας με την οποία κάνετε κλήσεις, στέλνετε μηνύματα ηλεκτρονικού ταχυδρομείου ή επικοινωνείτε με άλλους τρόπους με συγκεκριμένα άτομα. Αυτή η άδεια δίνει τη δυνατότητα στις εφαρμογές να αποθηκεύουν τα δεδομένα των επαφών σας. Οι κακόβουλες εφαρμογές ενδέχεται να μοιράζονται τα δεδομένα επαφών χωρίς να το γνωρίζετε."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Επιτρέπει στην εφαρμογή την ανάγνωση δεδομένων σχετικά με τις επαφές σας που είναι αποθηκευμένες στο τηλέφωνό σας, συμπεριλαμβανομένης της συχνότητας με την οποία έχετε καλέσει συγκεκριμένα άτομα ή έχετε επικοινωνήσει μαζί τους μέσω ηλεκτρονικού ταχυδρομείου ή άλλου τρόπου. Αυτή η άδεια δίνει τη δυνατότητα σε εφαρμογές να αποθηκεύουν τα δεδομένα των επαφών σας και οι κακόβουλες εφαρμογές ενδέχεται να μοιράζονται δεδομένα επαφών χωρίς να το γνωρίζετε."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Επιτρέπει στην εφαρμογή να διαβάζει δεδομένα σχετικά με τις επαφές σας που έχουν αποθηκευτεί στο tablet. Οι εφαρμογές θα έχουν επίσης πρόσβαση στους λογαριασμούς στο tablet, οι οποίοι έχουν δημιουργήσει επαφές. Σε αυτούς ενδέχεται να περιλαμβάνονται λογαριασμοί που δημιουργήθηκαν από εφαρμογές που έχετε εγκαταστήσει. Αυτή η άδεια δίνει τη δυνατότητα στις εφαρμογές να αποθηκεύουν τα δεδομένα των επαφών σας. Οι κακόβουλες εφαρμογές ενδέχεται να μοιράζονται τα δεδομένα επαφών χωρίς να το γνωρίζετε."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Επιτρέπει στην εφαρμογή να διαβάζει δεδομένα σχετικά με τις επαφές σας που έχουν αποθηκευτεί στη συσκευή σας Android TV. Οι εφαρμογές θα έχουν επίσης πρόσβαση στους λογαριασμούς στη συσκευή σας Android TV, οι οποίοι έχουν δημιουργήσει επαφές. Σε αυτούς ενδέχεται να περιλαμβάνονται λογαριασμοί που δημιουργήθηκαν από εφαρμογές που έχετε εγκαταστήσει. Αυτή η άδεια δίνει τη δυνατότητα στις εφαρμογές να αποθηκεύουν τα δεδομένα των επαφών σας. Οι κακόβουλες εφαρμογές ενδέχεται να μοιράζονται τα δεδομένα επαφών χωρίς να το γνωρίζετε."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Επιτρέπει στην εφαρμογή να διαβάζει δεδομένα σχετικά με τις επαφές σας που έχουν αποθηκευτεί στο τηλέφωνό σας. Οι εφαρμογές θα έχουν επίσης πρόσβαση στους λογαριασμούς στο τηλέφωνό σας, οι οποίοι έχουν δημιουργήσει επαφές. Σε αυτούς ενδέχεται να περιλαμβάνονται λογαριασμοί που δημιουργήθηκαν από εφαρμογές που έχετε εγκαταστήσει. Αυτή η άδεια δίνει τη δυνατότητα στις εφαρμογές να αποθηκεύουν τα δεδομένα των επαφών σας. Οι κακόβουλες εφαρμογές ενδέχεται να μοιράζονται τα δεδομένα επαφών χωρίς να το γνωρίζετε."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"τροποποιεί τις επαφές σας"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Επιτρέπει στην εφαρμογή την τροποποίηση των δεδομένων σχετικά με τις επαφές σας που είναι αποθηκευμένες στο tablet σας, συμπεριλαμβανομένης της συχνότητας με την οποία έχετε καλέσει συγκεκριμένες επαφές ή έχετε επικοινωνήσει μαζί τους μέσω ηλεκτρονικού ταχυδρομείου ή άλλου τρόπου. Αυτή η άδεια δίνει τη δυνατότητα σε εφαρμογές να διαγράφουν δεδομένα επαφών."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Επιτρέπει στην εφαρμογή να τροποποιεί τα δεδομένα που αποθηκεύονται στη συσκευή Android TV σχετικά με τις επαφές σας, συμπεριλαμβανομένης της συχνότητας με την οποία κάνετε κλήσεις, στέλνετε μηνύματα ηλεκτρονικού ταχυδρομείου ή επικοινωνείτε με άλλους τρόπους με συγκεκριμένες επαφές. Αυτή η άδεια επιτρέπει στις εφαρμογές να διαγράφουν δεδομένα επαφών."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Επιτρέπει στην εφαρμογή την τροποποίηση των δεδομένων σχετικά με τις επαφές σας που είναι αποθηκευμένες στο τηλέφωνό σας, συμπεριλαμβανομένης της συχνότητας με την οποία έχετε καλέσει συγκεκριμένες επαφές ή έχετε επικοινωνήσει μαζί τους μέσω ηλεκτρονικού ταχυδρομείου ή άλλου τρόπου. Αυτή η άδεια δίνει τη δυνατότητα σε εφαρμογές να διαγράφουν δεδομένα επαφών."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Επιτρέπει στην εφαρμογή να τροποποιεί δεδομένα σχετικά με τις επαφές σας που έχουν αποθηκευτεί στο tablet. Αυτή η άδεια επιτρέπει στις εφαρμογές να διαγράφουν δεδομένα επαφών."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Επιτρέπει στην εφαρμογή να τροποποιήσει τα δεδομένα σχετικά με τις επαφές σας που έχουν αποθηκευτεί στη συσκευή σας Android TV. Αυτή η άδεια επιτρέπει στις εφαρμογές να διαγράφουν δεδομένα επαφών."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Επιτρέπει στην εφαρμογή να τροποποιεί τα δεδομένα σχετικά με τις επαφές σας που έχουν αποθηκευτεί στο tablet. Αυτή η άδεια επιτρέπει στις εφαρμογές να διαγράφουν δεδομένα επαφών."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"διαβάζει το αρχείο καταγραφής κλήσεων"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Αυτή η εφαρμογή μπορεί να διαβάσει το ιστορικό κλήσεων."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"εγγράφει αρχείο καταγραφής κλήσεων"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"έχει πρόσβαση σε επιπλέον εντολές παρόχου τοποθεσίας"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Επιτρέπει στην εφαρμογή την πρόσβαση σε επιπλέον εντολές παρόχου τοποθεσίας. Αυτό μπορεί να δώσει τη δυνατότητα στην εφαρμογή να παρέμβει στη λειτουργία του GPS ή άλλων πηγών τοποθεσίας."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"πρόσβαση στην ακριβή τοποθεσία μόνο στο προσκήνιο"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την ακριβή τοποθεσία σας όταν βρίσκεται στο προσκήνιο. Αυτές οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στο τηλέφωνό σας, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή. Με την ενεργοποίηση αυτής της ρύθμισης, μπορεί να αυξηθεί η κατανάλωση μπαταρίας."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"πρόσβαση στην κατά προσέγγιση τοποθεσία (βάσει δικτύου) μόνο στο προσκήνιο"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την τοποθεσία σας βάσει πηγών δικτύου, όπως κεραίες κινητής τηλεφωνίας και δίκτυα Wi-Fi, αλλά μόνο όταν η εφαρμογή βρίσκεται στο προσκήνιο. Αυτές οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στο tablet που χρησιμοποιείτε, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την τοποθεσία σας βάσει πηγών δικτύου, όπως οι κεραίες κινητής τηλεφωνίας και τα δίκτυα Wi-Fi, αλλά μόνο όταν η εφαρμογή βρίσκεται στο προσκήνιο. Αυτές οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στη συσκευή Android TV, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την τοποθεσία σας βάσει πηγών δικτύου, όπως κεραίες κινητής τηλεφωνίας και δίκτυα Wi-Fi, αλλά μόνο όταν η εφαρμογή βρίσκεται στο προσκήνιο. Αυτές οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στο τηλέφωνό σας, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την ακριβή τοποθεσία σας μόνο όταν βρίσκεται στο προσκήνιο. Οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στη συσκευή σας, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή. Με την ενεργοποίηση αυτής της ρύθμισης, μπορεί να αυξηθεί η κατανάλωση μπαταρίας."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"πρόσβαση στην κατά προσέγγιση τοποθεσία μόνο στο προσκήνιο"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Αυτή η εφαρμογή έχει πρόσβαση στην τοποθεσία κατά προσέγγιση, μόνο όταν βρίσκεται στο προσκήνιο. Οι υπηρεσίες τοποθεσίας πρέπει να έχουν ενεργοποιηθεί και να είναι διαθέσιμες στη συσκευή σας, για να μπορεί να τις χρησιμοποιήσει η εφαρμογή."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"πρόσβαση στην τοποθεσία στο παρασκήνιο"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Εάν εκχωρηθεί επιπρόσθετα σε μια καταπροσέγγιση ή ακριβή πρόσβαση τοποθεσίας, η εφαρμογή μπορεί να έχει πρόσβαση στην τοποθεσία κατά την εκτέλεση στο παρασκήνιο."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Εκτός από την πρόσβαση τοποθεσίας ενώ βρίσκεται στο προσκήνιο, αυτή η εφαρμογή μπορεί να αποκτήσει πρόσβαση στην τοποθεσία ενώ εκτελείται στο παρασκήνιο."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"αλλάζει τις ρυθμίσεις ήχου"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Επιτρέπει στην εφαρμογή την τροποποίηση καθολικών ρυθμίσεων ήχου, όπως η ένταση και ποιο ηχείο χρησιμοποιείται για έξοδο."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"εγγράφει ήχο"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Επιτρέπει στην εφαρμογή να προβάλλει τη διαμόρφωση του Bluetooth στο tablet, καθώς και να πραγματοποιεί και να αποδέχεται συνδέσεις με συνδεδεμένες συσκευές."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Επιτρέπει στην εφαρμογή να βλέπει τη διαμόρφωση του Bluetooth στη συσκευή Android TV και να κάνει και να αποδέχεται συνδέσεις με συζευγμένες συσκευές."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Επιτρέπει στην εφαρμογή να προβάλλει τη διαμόρφωση του Bluetooth στο τηλέφωνο, καθώς και να πραγματοποιεί και να αποδέχεται συνδέσεις με συνδεδεμένες συσκευές."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ελέγχει την Επικοινωνία κοντινού πεδίου (FNC)"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Επιτρέπει στην εφαρμογή την επικοινωνία με ετικέτες, κάρτες και αναγνώστες της Επικοινωνίας κοντινού πεδίου (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"απενεργοποιεί το κλείδωμα οθόνης"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Συνδέθηκε με το <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Πατήστε για να δείτε τα αρχεία"</string>
<string name="pin_target" msgid="8036028973110156895">"Καρφίτσωμα"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Ξεκαρφίτσωμα"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Πληροφορίες εφαρμογής"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Έναρξη επίδειξης…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Ενημέρωση αυτών των στοιχείων "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> και <xliff:g id="TYPE_2">%3$s</xliff:g>;"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Αποθήκευση"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Όχι, ευχαριστώ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Όχι τώρα"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Ποτέ"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Ενημέρωση"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Συνέχεια"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"κωδικός πρόσβασης"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Εναλλαγή διαχωρισμού οθόνης"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Οθόνη κλειδώματος"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Στιγμιότυπο οθόνης"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> σε αναδυόμενο παράθυρο."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Γραμμή υποτίτλων για την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 8d2f805..c92ea6d 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your admin for assistance."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make your Android TV device slow or unstable by causing it to use too much memory."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the phone slow or unstable by causing it to use too much memory."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"read your contacts"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Allows the app to read data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Allows the app to read data about your contacts stored on your Android TV device, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Allows the app to read data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Allows the app to read data about your contacts stored on your tablet. Apps will also have access to the accounts on your tablet that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Allows the app to read data about your contacts stored on your Android TV device. Apps will also have access to the accounts on your Android TV device that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Allows the app to read data about your contacts stored on your phone. Apps will also have access to the accounts on your phone that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modify your contacts"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Allows the app to modify the data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Allows the app to modify the data about your contacts stored on your Android TV device, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Allows the app to modify the data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Allows the app to modify the data about your contacts stored on your tablet. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Allows the app to modify the data about your contacts stored on your Android TV device. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Allows the app to modify the data about your contacts stored on your phone. This permission allows apps to delete contact data."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"read call log"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"This app can read your call history."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"write call log"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"access extra location provider commands"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"access precise location only in the foreground"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"This app can get your exact location only when it is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"access approximate location (network-based) only in the foreground"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your Android TV device for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"This app can get your exact location only when it is in the foreground. Location Services must be turned on and available on your device for the app to be able to use them. This may increase battery consumption."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"access approximate location only in the foreground"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"This app can get your approximate location only when it is in the foreground. Location Services must be turned on and available on your device for the app to be able to use them."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"access location in the background"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"If this is granted additionally to the approximate or precise location access, the app can access the location while running in the background."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"This app can access location while running in the background, in addition to foreground location access."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Allows the app to view the configuration of Bluetooth on the tablet and to make and accept connections with paired devices."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Allows the app to view the configuration of Bluetooth on your Android TV device and to make and accept connections with paired devices."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Allows the app to view the configuration of the Bluetooth on the phone and to make and accept connections with paired devices."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"disable your screen lock"</string>
@@ -1862,7 +1863,9 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Tap to view files"</string>
<string name="pin_target" msgid="8036028973110156895">"Pin"</string>
+ <string name="pin_specific_target" msgid="7824671240625957415">"Pin <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="unpin_target" msgid="3963318576590204447">"Unpin"</string>
+ <string name="unpin_specific_target" msgid="3859828252160908146">"Unpin <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="app_info" msgid="6113278084877079851">"App info"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Starting demo…"</string>
@@ -1905,6 +1908,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Update these items in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> and <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Save"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"No, thanks"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Not now"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Never"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Update"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continue"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"password"</string>
@@ -2000,5 +2005,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Toggle Split Screen"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> app in pop-up window."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index e538587..ea6a702 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your admin for assistance."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make your Android TV device slow or unstable by causing it to use too much memory."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the phone slow or unstable by causing it to use too much memory."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"read your contacts"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Allows the app to read data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Allows the app to read data about your contacts stored on your Android TV device, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Allows the app to read data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Allows the app to read data about your contacts stored on your tablet. Apps will also have access to the accounts on your tablet that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Allows the app to read data about your contacts stored on your Android TV device. Apps will also have access to the accounts on your Android TV device that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Allows the app to read data about your contacts stored on your phone. Apps will also have access to the accounts on your phone that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modify your contacts"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Allows the app to modify the data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Allows the app to modify the data about your contacts stored on your Android TV device, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Allows the app to modify the data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Allows the app to modify the data about your contacts stored on your tablet. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Allows the app to modify the data about your contacts stored on your Android TV device. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Allows the app to modify the data about your contacts stored on your phone. This permission allows apps to delete contact data."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"read call log"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"This app can read your call history."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"write call log"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"access extra location provider commands"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"access precise location only in the foreground"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"This app can get your exact location only when it is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"access approximate location (network-based) only in the foreground"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your Android TV device for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"This app can get your exact location only when it is in the foreground. Location Services must be turned on and available on your device for the app to be able to use them. This may increase battery consumption."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"access approximate location only in the foreground"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"This app can get your approximate location only when it is in the foreground. Location Services must be turned on and available on your device for the app to be able to use them."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"access location in the background"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"If this is granted additionally to the approximate or precise location access, the app can access the location while running in the background."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"This app can access location while running in the background, in addition to foreground location access."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Allows the app to view the configuration of Bluetooth on the tablet and to make and accept connections with paired devices."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Allows the app to view the configuration of Bluetooth on your Android TV device and to make and accept connections with paired devices."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Allows the app to view the configuration of the Bluetooth on the phone and to make and accept connections with paired devices."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"disable your screen lock"</string>
@@ -1862,7 +1863,9 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Tap to view files"</string>
<string name="pin_target" msgid="8036028973110156895">"Pin"</string>
+ <string name="pin_specific_target" msgid="7824671240625957415">"Pin <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="unpin_target" msgid="3963318576590204447">"Unpin"</string>
+ <string name="unpin_specific_target" msgid="3859828252160908146">"Unpin <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="app_info" msgid="6113278084877079851">"App info"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Starting demo…"</string>
@@ -1905,6 +1908,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Update these items in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> and <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Save"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"No, thanks"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Not now"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Never"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Update"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continue"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"password"</string>
@@ -2000,5 +2005,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Toggle Split Screen"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> app in pop-up window."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 8d2f805..c92ea6d 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your admin for assistance."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make your Android TV device slow or unstable by causing it to use too much memory."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the phone slow or unstable by causing it to use too much memory."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"read your contacts"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Allows the app to read data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Allows the app to read data about your contacts stored on your Android TV device, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Allows the app to read data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Allows the app to read data about your contacts stored on your tablet. Apps will also have access to the accounts on your tablet that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Allows the app to read data about your contacts stored on your Android TV device. Apps will also have access to the accounts on your Android TV device that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Allows the app to read data about your contacts stored on your phone. Apps will also have access to the accounts on your phone that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modify your contacts"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Allows the app to modify the data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Allows the app to modify the data about your contacts stored on your Android TV device, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Allows the app to modify the data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Allows the app to modify the data about your contacts stored on your tablet. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Allows the app to modify the data about your contacts stored on your Android TV device. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Allows the app to modify the data about your contacts stored on your phone. This permission allows apps to delete contact data."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"read call log"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"This app can read your call history."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"write call log"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"access extra location provider commands"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"access precise location only in the foreground"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"This app can get your exact location only when it is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"access approximate location (network-based) only in the foreground"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your Android TV device for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"This app can get your exact location only when it is in the foreground. Location Services must be turned on and available on your device for the app to be able to use them. This may increase battery consumption."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"access approximate location only in the foreground"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"This app can get your approximate location only when it is in the foreground. Location Services must be turned on and available on your device for the app to be able to use them."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"access location in the background"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"If this is granted additionally to the approximate or precise location access, the app can access the location while running in the background."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"This app can access location while running in the background, in addition to foreground location access."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Allows the app to view the configuration of Bluetooth on the tablet and to make and accept connections with paired devices."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Allows the app to view the configuration of Bluetooth on your Android TV device and to make and accept connections with paired devices."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Allows the app to view the configuration of the Bluetooth on the phone and to make and accept connections with paired devices."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"disable your screen lock"</string>
@@ -1862,7 +1863,9 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Tap to view files"</string>
<string name="pin_target" msgid="8036028973110156895">"Pin"</string>
+ <string name="pin_specific_target" msgid="7824671240625957415">"Pin <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="unpin_target" msgid="3963318576590204447">"Unpin"</string>
+ <string name="unpin_specific_target" msgid="3859828252160908146">"Unpin <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="app_info" msgid="6113278084877079851">"App info"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Starting demo…"</string>
@@ -1905,6 +1908,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Update these items in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> and <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Save"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"No, thanks"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Not now"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Never"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Update"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continue"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"password"</string>
@@ -2000,5 +2005,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Toggle Split Screen"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> app in pop-up window."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 8d2f805..c92ea6d 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your admin for assistance."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make your Android TV device slow or unstable by causing it to use too much memory."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the phone slow or unstable by causing it to use too much memory."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"read your contacts"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Allows the app to read data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Allows the app to read data about your contacts stored on your Android TV device, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Allows the app to read data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Allows the app to read data about your contacts stored on your tablet. Apps will also have access to the accounts on your tablet that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Allows the app to read data about your contacts stored on your Android TV device. Apps will also have access to the accounts on your Android TV device that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Allows the app to read data about your contacts stored on your phone. Apps will also have access to the accounts on your phone that have created contacts. This may include any accounts created by apps that you have installed. This permission allows any apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modify your contacts"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Allows the app to modify the data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Allows the app to modify the data about your contacts stored on your Android TV device, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Allows the app to modify the data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Allows the app to modify the data about your contacts stored on your tablet. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Allows the app to modify the data about your contacts stored on your Android TV device. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Allows the app to modify the data about your contacts stored on your phone. This permission allows apps to delete contact data."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"read call log"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"This app can read your call history."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"write call log"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"access extra location provider commands"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"access precise location only in the foreground"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"This app can get your exact location only when it is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"access approximate location (network-based) only in the foreground"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your Android TV device for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"This app can get your exact location only when it is in the foreground. Location Services must be turned on and available on your device for the app to be able to use them. This may increase battery consumption."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"access approximate location only in the foreground"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"This app can get your approximate location only when it is in the foreground. Location Services must be turned on and available on your device for the app to be able to use them."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"access location in the background"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"If this is granted additionally to the approximate or precise location access, the app can access the location while running in the background."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"This app can access location while running in the background, in addition to foreground location access."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Allows the app to view the configuration of Bluetooth on the tablet and to make and accept connections with paired devices."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Allows the app to view the configuration of Bluetooth on your Android TV device and to make and accept connections with paired devices."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Allows the app to view the configuration of the Bluetooth on the phone and to make and accept connections with paired devices."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"disable your screen lock"</string>
@@ -1862,7 +1863,9 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Tap to view files"</string>
<string name="pin_target" msgid="8036028973110156895">"Pin"</string>
+ <string name="pin_specific_target" msgid="7824671240625957415">"Pin <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="unpin_target" msgid="3963318576590204447">"Unpin"</string>
+ <string name="unpin_specific_target" msgid="3859828252160908146">"Unpin <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="app_info" msgid="6113278084877079851">"App info"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Starting demo…"</string>
@@ -1905,6 +1908,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Update these items in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> and <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Save"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"No, thanks"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Not now"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Never"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Update"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continue"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"password"</string>
@@ -2000,5 +2005,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Toggle Split Screen"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> app in pop-up window."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 1436692..c386e6e 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your admin for assistance."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Your organization manages this device and may monitor network traffic. Tap for details."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make your Android TV device slow or unstable by causing it to use too much memory."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the phone slow or unstable by causing it to use too much memory."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"read your contacts"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Allows the app to read data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Allows the app to read data about your contacts stored on your Android TV device, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Allows the app to read data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Allows the app to read data about your contacts stored on your tablet. Apps will also have access to the accounts on your tablet that have created contacts. This may include accounts created by apps you have installed. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Allows the app to read data about your contacts stored on your Android TV device. Apps will also have access to the accounts on your Android TV device that have created contacts. This may include accounts created by apps you have installed. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Allows the app to read data about your contacts stored on your phone. Apps will also have access to the accounts on your phone that have created contacts. This may include accounts created by apps you have installed. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modify your contacts"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Allows the app to modify the data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Allows the app to modify the data about your contacts stored on your Android TV device, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Allows the app to modify the data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed, or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Allows the app to modify the data about your contacts stored on your tablet. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Allows the app to modify the data about your contacts stored on your Android TV device. This permission allows apps to delete contact data."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Allows the app to modify the data about your contacts stored on your phone. This permission allows apps to delete contact data."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"read call log"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"This app can read your call history."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"write call log"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"access extra location provider commands"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"access precise location only in the foreground"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"This app can get your exact location only when it is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"access approximate location (network-based) only in the foreground"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"This app can get your location based on network sources such as cell towers and Wi-Fi networks, but only when when the app is in the foreground. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"This app can get your location based on network sources such as cell towers and Wi-Fi networks, but only when when the app is in the foreground. These location services must be turned on and available on your Android TV device for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"This app can get your location based on network sources such as cell towers and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"This app can get your exact location only when it is in the foreground. Location services must be turned on and available on your device for the app to be able to use them. This may increase battery consumption."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"access approximate location only in the foreground"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"This app can get your approximate location only when it is in the foreground. Location services must be turned on and available on your device for the app to be able to use them."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"access location in the background"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"If this is granted additionally to the approximate or precise location access the app can access the location while running in the background."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"This app can access location while running in the background, in addition to foreground location access."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"change your audio settings"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"record audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Allows the app to view the configuration of Bluetooth on the tablet, and to make and accept connections with paired devices."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Allows the app to view the configuration of Bluetooth on your Android TV device, and to make and accept connections with paired devices."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Allows the app to view the configuration of the Bluetooth on the phone, and to make and accept connections with paired devices."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"control Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Allows the app to communicate with Near Field Communication (NFC) tags, cards, and readers."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"disable your screen lock"</string>
@@ -1862,7 +1863,9 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Tap to view files"</string>
<string name="pin_target" msgid="8036028973110156895">"Pin"</string>
+ <string name="pin_specific_target" msgid="7824671240625957415">"Pin <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="unpin_target" msgid="3963318576590204447">"Unpin"</string>
+ <string name="unpin_specific_target" msgid="3859828252160908146">"Unpin <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="app_info" msgid="6113278084877079851">"App info"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Starting demo…"</string>
@@ -1905,6 +1908,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Update these items in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, and <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Save"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"No thanks"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Not now"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Never"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Update"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continue"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"password"</string>
@@ -2000,5 +2005,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Toggle Split Screen"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> app in Pop-up window."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar of <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index b04882a..ec758d5 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"La app de administración de perfil de trabajo no se encuentra o está dañada. Por lo tanto, se borraron tu perfil de trabajo y los datos relacionados. Para obtener asistencia, comunícate con el administrador."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Tu perfil de trabajo ya no está disponible en este dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Demasiados intentos para ingresar la contraseña"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"El administrador no permite hacer un uso personal del dispositivo"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Dispositivo administrado"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Tu organización administra este dispositivo y es posible que controle el tráfico de red. Presiona para obtener más información."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Se borrarán los datos del dispositivo"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permite que la app envíe transmisiones persistentes que permanecen después de que finaliza la emisión. Un uso excesivo podría ralentizar el dispositivo Android TV o forzarlo a utilizar demasiada memoria, lo que generaría un funcionamiento inestable."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permite que la aplicación envíe transmisiones persistentes que permanecen después de que finaliza la transmisión. Un uso excesivo podría ralentizar el dispositivo o hacer que funcione de manera inestable al forzarlo a utilizar mucha memoria."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"leer tus contactos"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Permite que la aplicación consulte información sobre los contactos almacenados en la tablet, incluida la frecuencia con la que los has llamado, les has enviado correos o te has puesto en contacto con ellos de otro modo. Las aplicaciones pueden utilizar este permiso para guardar los datos de los contactos, y las aplicaciones malintencionadas podrían compartirlos sin tu consentimiento."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Permite que la app lea datos sobre los contactos almacenados en el dispositivo Android TV, incluida la frecuencia con la que llamaste a una persona específica, le enviaste correos electrónicos o te comunicaste con ella de cualquier otra manera. Las apps pueden utilizar este permiso para guardar los datos de los contactos, y aquellas apps maliciosas podrían compartir esa información sin tu conocimiento."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Permite que la aplicación consulte información sobre contactos almacenados en el dispositivo, incluida la frecuencia con la que los has llamado, les has enviado correos o te has puesto en contacto con ellos de otro modo. Las aplicaciones pueden utilizar este permiso para guardar los datos de los contactos, y las aplicaciones malintencionadas podrían compartirlos sin tu consentimiento."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permite que la app lea datos sobre los contactos almacenados en la tablet. Las apps también tendrán acceso a las cuentas de tu tablet en las que se hayan creado contactos. Pueden incluirse cuentas creadas por apps que hayas instalado. Las apps pueden utilizar este permiso para guardar los datos de los contactos, y las apps maliciosas podrían compartir esa información sin tu conocimiento."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permite que la app lea datos sobre los contactos almacenados en el dispositivo Android TV. Las apps también tendrán acceso a las cuentas de tu dispositivo Android TV en las que se hayan creado contactos. Pueden incluirse cuentas creadas por apps que hayas instalado. Las apps pueden utilizar este permiso para guardar los datos de los contactos, y las apps maliciosas podrían compartir esa información sin tu conocimiento."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permite que la app lea datos sobre los contactos almacenados en el teléfono. Las apps también tendrán acceso a las cuentas de tu teléfono en las que se hayan creado contactos. Pueden incluirse cuentas creadas por apps que hayas instalado. Las apps pueden utilizar este permiso para guardar los datos de los contactos, y las apps maliciosas podrían compartir esa información sin tu conocimiento."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modificar tus contactos"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Permite que la aplicación modifique los datos de los contactos almacenados en la tablet, incluida la frecuencia con la que los has llamado, les has enviado correos o te has puesto en contacto con ellos de otro modo. Las aplicaciones pueden utilizar este permiso para eliminar datos de contactos."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Permite que la app modifique datos sobre los contactos almacenados en el dispositivo Android TV, incluida la frecuencia con la que llamaste a una persona específica, le enviaste correos electrónicos o te comunicaste con ella de cualquier otra manera. Las apps pueden utilizar este permiso para borrar los datos de los contactos."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Permite que la aplicación modifique los datos de los contactos almacenados en el dispositivo, incluida la frecuencia con la que los has llamado, les has enviado correos o te has puesto en contacto con ellos de otro modo. Las aplicaciones pueden utilizar este permiso para eliminar datos de contactos."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permite que la app modifique datos sobre los contactos almacenados en la tablet. Las apps pueden utilizar este permiso para borrar los datos de los contactos."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permite que la app modifique datos sobre los contactos almacenados en el dispositivo Android TV. Las apps pueden utilizar este permiso para borrar los datos de los contactos."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permite que la app modifique datos sobre los contactos almacenados en el teléfono. Las apps pueden utilizar este permiso para borrar los datos de los contactos."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"leer el registro de llamadas"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Esta app puede leer tu historial de llamadas."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"escribir en el registro de llamadas"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acceder a comandos adicionales del proveedor del lugar"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que la aplicación acceda a comandos adicionales del proveedor de ubicación. Esto puede permitirle a la aplicación interferir con el funcionamiento del GPS o de otras fuentes de ubicación."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"acceder a la ubicación exacta solo en primer plano"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Esta app puede obtener tu ubicación exacta solo cuando está en primer plano. Los servicios de ubicación deben estar activados y disponibles en el teléfono para que la app pueda usarlos. Es posible que aumente el consumo de batería."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"acceso a la ubicación aproximada (mediante red) solo en primer plano"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Esta app puede obtener tu ubicación desde fuentes de red, como torres de telefonía celular y redes Wi-Fi, pero solo en primer plano. Los servicios de ubicación deben estar activados y disponibles en tu tablet para que la app pueda usarlos."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Esta app puede obtener tu ubicación desde fuentes de red, como torres de telefonía celular y redes Wi-Fi, pero solo cuando está en primer plano. Los servicios de ubicación deben estar activados y disponibles en el dispositivo Android TV para que pueda usarlos la app."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Esta app puede obtener tu ubicación desde fuentes de red, como torres de telefonía celular y redes Wi-Fi, pero solo en primer plano. Los servicios de ubicación deben estar activados y disponibles en tu teléfono para que la app pueda usarlos."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Esta app puede obtener tu ubicación exacta solo cuando está en primer plano. Los servicios de ubicación deben estar activados y disponibles en el dispositivo para que la app pueda usarlos. Es posible que aumente el consumo de batería."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acceder a la ubicación aproximada solo en primer plano"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Esta app puede obtener tu ubicación aproximada únicamente cuando está en primer plano. Los servicios de ubicación deben estar activados y disponibles en el dispositivo para que la app pueda usarlos."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"acceder a la ubicación en segundo plano"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Si este permiso se otorga de manera adicional para aproximar o precisar el acceso a la ubicación, la app podrá acceder a la ubicación mientras se ejecuta en segundo plano."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Esta app puede acceder a una ubicación mientras se ejecuta en segundo plano, además de proporcionar acceso a la ubicación en primer plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"cambiar tu configuración de audio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permite que la aplicación modifique la configuración de audio global, por ejemplo, el volumen y el altavoz de salida."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"grabar audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permite que la aplicación vea la configuración de Bluetooth de la tablet y que cree y acepte conexiones con los dispositivos sincronizados."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permite que la app vea la configuración de Bluetooth del dispositivo Android TV, así como que cree y acepte conexiones con los dispositivos sincronizados."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permite que la aplicación vea la configuración de Bluetooth del dispositivo y que cree y acepte conexiones con los dispositivos sincronizados."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"controlar la Transmisión de datos en proximidad"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Permite que la aplicación se comunique con lectores, tarjetas y etiquetas de Comunicación de campo cercano (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"desactivar el bloqueo de pantalla"</string>
@@ -1298,7 +1299,7 @@
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"Cargando el dispositivo conectado mediante USB"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"Se activó la transferencia de archivos mediante USB"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"Se activó el modo PTP mediante USB"</string>
- <string name="usb_tether_notification_title" msgid="8828527870612663771">"Se activó la conexión mediante dispositivo portátil por USB"</string>
+ <string name="usb_tether_notification_title" msgid="8828527870612663771">"Se activó la conexión mediante dispositivo móvil por USB"</string>
<string name="usb_midi_notification_title" msgid="7404506788950595557">"Se activó el modo MIDI mediante USB"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"Accesorio USB conectado"</string>
<string name="usb_notification_message" msgid="4715163067192110676">"Presiona para ver más opciones."</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Presiona para ver archivos"</string>
<string name="pin_target" msgid="8036028973110156895">"Fijar"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"No fijar"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Información de apps"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Iniciando demostración…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"¿Quieres actualizar estos elementos en "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> y <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Guardar"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"No, gracias"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ahora no"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nunca"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Actualizar"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continuar"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"contraseña"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activar o desactivar pantalla dividida"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Bloquear pantalla"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de pantalla"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"App de <xliff:g id="APP_NAME">%1$s</xliff:g> en una ventana emergente."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de subtítulos de <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 81f210b..22599b0 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Falta la aplicación de administración del perfil de trabajo o está dañada. Por ello, se han eliminado tu perfil de trabajo y los datos relacionados. Ponte en contacto con el administrador para obtener ayuda."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Tu perfil de trabajo ya no está disponible en este dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Has fallado demasiadas veces al introducir la contraseña"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"El administrador no permite hacer un uso personal del dispositivo"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"El dispositivo está administrado"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Tu organización administra este dispositivo y puede supervisar el tráfico de red. Toca la notificación para obtener más información."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Tu dispositivo se borrará"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permite que la aplicación envíe emisiones que permanecen en el dispositivo una vez finalizadas. Si esta función se utiliza en exceso, podría ralentizar tu dispositivo Android TV o volverlo inestable al hacer que se ocupe demasiada memoria."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permite que la aplicación envíe emisiones que permanecen en el dispositivo una vez que la emisión ha finalizado. Un uso excesivo podría ralentizar el teléfono o volverlo inestable al hacer que use demasiada memoria."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"consultar tus contactos"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Permite que la aplicación consulte información sobre contactos almacenados en el tablet, incluida la frecuencia con la que los has llamado, les has enviado un correo electrónico o te has puesto en contacto con ellos de otro modo. Este permiso permite guardar los datos de los contactos, y las aplicaciones malintencionadas pueden utilizarlo para compartir datos de contactos del usuario sin su consentimiento."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Permite que la aplicación consulte los datos de los contactos almacenados en tu dispositivo Android TV, incluida la frecuencia con la que los has llamado, les has enviado un correo electrónico o te has puesto en contacto de cualquier otro modo con cada uno. Las aplicaciones que tengan este permiso pueden guardar los datos de tus contactos, y las aplicaciones maliciosas puede que compartan estos datos sin tu conocimiento."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Permite que la aplicación consulte información sobre contactos almacenados en el teléfono, incluida la frecuencia con la que los has llamado, les has enviado un correo electrónico o te has puesto en contacto con ellos de otro modo. Este permiso permite guardar los datos de los contactos, y las aplicaciones malintencionadas pueden utilizarlo para compartir datos de contactos del usuario sin su consentimiento."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permite que la aplicación consulte datos de los contactos almacenados en tu tablet. Las aplicaciones también podrán acceder a las cuentas de tu tablet que hayan creado contactos, y quizá tengan acceso a las cuentas creadas por aplicaciones que hayas descargado. Las aplicaciones que tengan este permiso pueden guardar los datos de tus contactos, y las aplicaciones maliciosas puede que compartan estos datos sin que lo sepas."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permite que la aplicación consulte datos de los contactos almacenados en tu dispositivo Android TV. Las aplicaciones también podrán acceder a las cuentas de tu dispositivo Android TV que hayan creado contactos, y quizá tengan acceso a las cuentas creadas por aplicaciones que hayas descargado. Las aplicaciones que tengan este permiso pueden guardar los datos de tus contactos, y las aplicaciones maliciosas puede que compartan estos datos sin que lo sepas."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permite que la aplicación consulte datos de los contactos almacenados en tu teléfono. Las aplicaciones también podrán acceder a las cuentas de tu teléfono que hayan creado contactos, y quizá tengan acceso a las cuentas creadas por aplicaciones que hayas descargado. Las aplicaciones que tengan este permiso pueden guardar los datos de tus contactos, y las aplicaciones maliciosas puede que compartan estos datos sin que lo sepas."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modificar tus contactos"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Permite que la aplicación modifique los datos de los contactos almacenados en el tablet, incluida la frecuencia con la que los has llamado, les has enviado un correo electrónico o te has puesto en contacto con ellos de otro modo. Las aplicaciones pueden utilizar este permiso para eliminar datos de contactos."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Permite que la aplicación cambie los datos de los contactos almacenados en tu dispositivo Android TV, incluida la frecuencia con la que los has llamado, les has enviado un correo electrónico o te has puesto en contacto de cualquier otro modo con cada uno. Las aplicaciones que tengan este permiso pueden eliminar datos de contactos."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Permite que la aplicación modifique los datos de los contactos almacenados en el teléfono, incluida la frecuencia con la que los has llamado, les has enviado un correo electrónico o te has puesto en contacto con ellos de otro modo. Las aplicaciones pueden utilizar este permiso para eliminar datos de contactos."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permite que la aplicación cambie los datos de los contactos almacenados en tu tablet. Las aplicaciones que tengan este permiso pueden eliminar datos de contactos."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permite que la aplicación cambie los datos de los contactos almacenados en tu dispositivo Android TV. Las aplicaciones que tengan este permiso pueden eliminar datos de contactos."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permite que la aplicación cambie los datos de los contactos almacenados en tu teléfono. Las aplicaciones que tengan este permiso pueden eliminar datos de contactos."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"leer el registro de llamadas"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Esta aplicación puede leer tu historial de llamadas."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"escribir en el registro de llamadas"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acceder a comandos de proveedor de ubicación adicional"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que la aplicación acceda a otros comandos del proveedor de ubicación. De esta forma, la aplicación podrá interferir en el funcionamiento del GPS o de otras fuentes de ubicación."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"acceder a la ubicación exacta solo en primer plano"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Esta aplicación solo puede obtener tu ubicación exacta cuando está en primer plano. Estos servicios de ubicación deben estar activados y disponibles en tu teléfono para que la aplicación pueda utilizarlos. Es posible que aumente el consumo de batería."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"acceder a la ubicación aproximada (a partir de la red) solo en primer plano"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Esta aplicación puede obtener tu ubicación a partir de fuentes de red como las antenas de telefonía móvil y las redes Wi‑Fi, pero únicamente si la aplicación está en primer plano. Estos servicios de ubicación deben estar activados y disponibles en el tablet para que la aplicación pueda usarlos."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Esta aplicación puede obtener tu ubicación a partir de fuentes de red como las antenas de telefonía móvil y las redes Wi‑Fi, pero únicamente si la aplicación está en primer plano. Estos servicios de ubicación deben estar activados y disponibles en tu dispositivo Android TV para que la aplicación pueda usarlos."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Esta aplicación puede obtener tu ubicación a partir de fuentes de red como las antenas de telefonía móvil y las redes Wi‑Fi, pero únicamente si la aplicación está en primer plano. Estos servicios de ubicación deben estar activados y disponibles en el teléfono para que la aplicación pueda usarlos."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Esta aplicación solo puede obtener tu ubicación exacta cuando está en primer plano. Los servicios de ubicación deben estar activados y disponibles en tu dispositivo para que la aplicación pueda utilizarlos. Es posible que aumente el consumo de batería."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acceder a la ubicación aproximada solo al estar en primer plano"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Esta aplicación puede obtener tu ubicación aproximada solo cuando está en primer plano. Para que la aplicación pueda utilizar los servicios de ubicación, deben estar activados y disponibles en tu dispositivo."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"acceder a la ubicación en segundo plano"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Si se concede este permiso además del acceso a la ubicación exacta o aproximada, la aplicación podrá acceder a la ubicación mientras se ejecuta en segundo plano."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Esta aplicación puede acceder a la ubicación tanto cuando se ejecuta en segundo plano como cuando está en primer plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"cambiar la configuración de audio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permite que la aplicación modifique la configuración de audio global (por ejemplo, el volumen y el altavoz de salida)."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"grabar sonido"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permite que la aplicación acceda a la configuración de Bluetooth del tablet y que establezca y acepte conexiones con los dispositivos sincronizados."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permite que la aplicación vea la configuración de Bluetooth de tu dispositivo Android TV y que cree y acepte conexiones con los dispositivos vinculados."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permite que la aplicación acceda a la configuración de Bluetooth del teléfono y que establezca y acepte conexiones con los dispositivos sincronizados."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicación de campo cercano (NFC)"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Permite que la aplicación se comunique con lectores, tarjetas y etiquetas de Comunicación de campo cercano (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"inhabilitar el bloqueo de pantalla"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Toca para ver archivos"</string>
<string name="pin_target" msgid="8036028973110156895">"Fijar"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"No fijar"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Acerca de la aplicación"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Iniciando demostración…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"¿Actualizar estos elementos en "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" (<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> y <xliff:g id="TYPE_2">%3$s</xliff:g>)?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Guardar"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"No, gracias"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ahora no"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nunca"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Actualizar"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continuar"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"contraseña"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activar o desactivar la pantalla dividida"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Pantalla de bloqueo"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de pantalla"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"La aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> se muestra en una ventana emergente."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de subtítulos de <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 61b18bb..9fdc8e0 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Tööprofiili administraatori rakendus puudub või on rikutud. Seetõttu on teie tööprofiil ja seotud andmed kustutatud. Abi saamiseks võtke ühendust administraatoriga."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Teie tööprofiil pole selles seadmes enam saadaval"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Liiga palju paroolikatseid"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administraator keelas seadme isikliku kasutamise"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Seade on hallatud"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Teie organisatsioon haldab seda seadet ja võib jälgida võrguliiklust. Puudutage üksikasjade vaatamiseks."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Seade kustutatakse"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Võimaldab rakendusel saata püsivaid teadaandeid, mis jäävad pärast ülekande lõppemist alles. Ülemäärane kasutamine võib muuta teie Android TV seadme aeglaseks või ebastabiilseks, põhjustades selle liiga suure mälukasutuse."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Võimaldab rakendusel saata püsivaid edastusi, mis jäävad pärast saate lõppemist alles. Ülemäärane kasutamine võib muuta telefoni aeglaseks või ebastabiilseks, põhjustades selle liiga suure mälukasutuse."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"Kontaktide lugemine"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Võimaldab rakendusel lugeda andmeid teie tahvelarvutisse salvestatud kontaktide kohta, näiteks seda, kui tihti te kellelegi helistate, meilite või nendega muul viisil suhtlete. See luba võimaldab rakendustel salvestada teie kontaktandmeid ja pahatahtlikud rakendused võivad teie teadmata kontaktandmeid jagada."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Lubab rakendusel lugeda kõikide Android TV seadmesse salvestatud kontaktide andmeid, sh seda, kui sageli olete nendele isikutele helistanud, meili saatnud või nendega muul viisil suhelnud. See luba võimaldab rakendustel salvestada teie kontaktandmeid ja pahatahtlikud rakendused võivad teie teadmata kontaktandmeid jagada."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Võimaldab rakendusel lugeda andmeid teie telefoni salvestatud kontaktide kohta, näiteks seda, kui tihti te kellelegi helistate, meilite või nendega muul viisil suhtlete. See luba võimaldab rakendustel salvestada teie kontaktandmeid ja pahatahtlikud rakendused võivad teie teadmata kontaktandmeid jagada."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Lubab rakendusel lugeda tahvelarvutisse salvestatud kontaktide andmeid. Rakendustel on ka juurdepääs teie tahvelarvutis olevatele kontodele, millel on loodud kontakte. See võib hõlmata kontosid, mille lõid teie installitud rakendused. See luba võimaldab rakendustel salvestada teie kontaktandmeid ja pahatahtlikud rakendused võivad teie teadmata kontaktandmeid jagada."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Lubab rakendusel lugeda Android TV seadmesse salvestatud kontaktide andmeid. Rakendustel on ka juurdepääs teie Android TV seadmes olevatele kontodele, millel on loodud kontakte. See võib hõlmata kontosid, mille lõid teie installitud rakendused. See luba võimaldab rakendustel salvestada teie kontaktandmeid ja pahatahtlikud rakendused võivad teie teadmata kontaktandmeid jagada."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Lubab rakendusel lugeda telefoni salvestatud kontaktide andmeid. Rakendustel on ka juurdepääs teie telefonis olevatele kontodele, millel on loodud kontakte. See võib hõlmata kontosid, mille lõid teie installitud rakendused. See luba võimaldab rakendustel salvestada teie kontaktandmeid ja pahatahtlikud rakendused võivad teie teadmata kontaktandmeid jagada."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"muutke oma kontakte"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Võimaldab rakendusel muuta tahvelarvutisse salvestatud kontaktide andmeid, sealhulgas seda, kui tihti olete konkreetsetele kontaktidele helistanud, meilinud või nendega muul viisil suhelnud. See luba võimaldab rakendustel kustutada kontaktandmeid."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Lubab rakendusel muuta kõikide Android TV seadmesse salvestatud kontaktide andmeid, sh seda, kui sageli olete nendele kontaktidele helistanud, meili saatnud või nendega muul viisil suhelnud. See luba võimaldab rakendustel kontaktandmeid kustutada."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Võimaldab rakendusel muuta telefoni salvestatud kontaktide andmeid, sealhulgas seda, kui tihti olete konkreetsetele kontaktidele helistanud, meilinud või nendega muul viisil suhelnud. See luba võimaldab rakendustel kustutada kontaktandmeid."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Lubab rakendusel muuta tahvelarvutisse salvestatud kontaktide andmeid. See luba võimaldab rakendustel kontaktandmeid kustutada."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Lubab rakendusel muuta Android TV seadmesse salvestatud kontaktide andmeid. See luba võimaldab rakendustel kontaktandmeid kustutada."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Lubab rakendusel muuta telefoni salvestatud kontaktide andmeid. See luba võimaldab rakendustel kontaktandmeid kustutada."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"kõnelogi lugemine"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"See rakendus saab teie kõneajalugu lugeda."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"kõnelogi kirjutamine"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"juurdepääs asukohapakkuja lisakäskudele"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Võimaldab rakendusel juurde pääseda asukohapakkuja erikäskudele. See võib lubada rakendusel mõjutada GPS-i või muude asukohaallikate tööd."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"juurdepääs täpsele asukohale ainult esiplaanil"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"See rakendus hangib teie täpse asukoha ainult siis, kui see töötab esiplaanil. Need asukohateenused peavad olema sisse lülitatud ja teie telefonis saadaval, et rakendus saaks neid kasutada. See võib suurendada akutoite tarbimist."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"pääseda juurde ligikaudsele asukohale (võrgupõhiselt) ainult esiplaanil"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"See rakendus näeb võrguallikate (nt mobiilimastid ja WiFi-võrgud) abil teie asukohta, kuid ainult siis, kui rakendus töötab esiplaanil. Need asukohateenused peavad olema sisse lülitatud ja teie tahvelarvutis saadaval, et rakendus saaks neid kasutada."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"See rakendus näeb võrguallikate (nt mobiilimastid ja WiFi-võrgud) abil teie asukohta, kuid ainult siis, kui rakendus töötab esiplaanil. Need asukohateenused peavad olema sisse lülitatud ja teie Android TV seadmes saadaval, et rakendus saaks neid kasutada."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"See rakendus näeb võrguallikate (nt mobiilimastid ja WiFi-võrgud) abil teie asukohta, kuid ainult siis, kui rakendus töötab esiplaanil. Need asukohateenused peavad olema sisse lülitatud ja teie telefonis saadaval, et rakendus saaks neid kasutada."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"See rakendus hangib teie täpse asukoha ainult siis, kui see töötab esiplaanil. Asukohateenused peavad olema sisse lülitatud ja teie seadmes saadaval, et rakendus saaks neid kasutada. See võib suurendada akutoite tarbimist."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"juurdepääs ligikaudsele asukohale ainult esiplaanil"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"See rakendus hangib teie ligikaudse asukoha ainult siis, kui see töötab esiplaanil. Asukohateenused peavad olema sisse lülitatud ja teie seadmes saadaval, et rakendus saaks neid kasutada."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"juurdepääs asukohale taustal"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Kui see on antud ka umbkaudsele või täpsele asukohale juurdepääsu puhul, saab rakendus taustal käitamisel juurdepääsu asukohale."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"See rakendus pääseb asukohale lisaks esiplaanil töötamise ajal juurde ka taustal töötamise ajal."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"muuda heliseadeid"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Võimaldab rakendusel muuta üldiseid heliseadeid, näiteks helitugevust ja seda, millist kõlarit kasutatakse väljundiks."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"salvesta heli"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Võimaldab rakendusel vaadata tahvelarvuti Bluetooth-konfiguratsiooni ning luua ja heaks kiita ühendusi seotud seadmetega."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Võimaldab rakendusel vaadata Android TV seadme Bluetoothi seadistust ning luua ja vastu võtta ühendusi seotud seadmetega."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Võimaldab rakendusel vaadata telefoni Bluetooth-konfiguratsiooni ning luua ja heaks kiita ühendusi seotud seadmetega."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"lähiväljaside juhtimine"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Võimaldab rakendusel suhelda lähiväljaside (NFC) märgendite, kaartide ja lugeritega."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"keelake ekraanilukk"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Ühendatud seadmega <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Failide vaatamiseks puudutage"</string>
<string name="pin_target" msgid="8036028973110156895">"Kinnita"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Vabasta"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Rakenduse teave"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Demo käivitamine …"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Kas värskendada teenuses "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" neid üksusi: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ja <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Salvesta"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Tänan, ei"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Hiljem"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Mitte kunagi"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Värskenda"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Jätka"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"parool"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Vaheta jagatud ekraanikuva"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lukustuskuva"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekraanipilt"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> on hüpikaknas."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> pealkirjariba."</string>
</resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index fda8565..c5e09ae 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Laneko profila administratzeko aplikazioa falta da edo hondatuta dago. Ondorioz, ezabatu egin dira laneko profila bera eta harekin erlazionatutako datuak. Laguntza lortzeko, jarri administratzailearekin harremanetan."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Laneko profila ez dago erabilgarri gailu honetan"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Gehiegitan saiatu zara pasahitza idazten"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Erabilera pertsonalerako utzi du gailua administratzaileak"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Jabeak kudeatzen du gailua"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Erakundeak kudeatzen du gailua eta baliteke sareko trafikoa gainbegiratzea. Sakatu hau xehetasunak ikusteko."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Gailuko datuak ezabatu egingo dira"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Igorpen iraunkorrak egiteko baimena ematen die aplikazioei. Igorpena amaitu ondoren ere igortzen jarraitzen dute igorpen iraunkorrek. Gehiegi erabiliz gero, Android TV gailua motel edo ezegonkor ibiliko da, memoria gehiago erabiliko delako."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Igorpen iraunkorrak emateko baimena ematen die; horiek igorpena amaitu ondoren mantentzen dira. Gehiegi erabiliz gero, telefonoa motel edo ezegonkor ibiliko da, memoria gehiago erabiliko delako."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"irakurri kontaktuak"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Tabletan gordetako kontaktuei buruzko datuak irakurtzeko baimena ematen die aplikazioei, besteak beste, pertsona zehatzei zer maiztasunekin deitu diezun, mezu elektronikoak bidali dizkiezun edo haiekin harremanetan beste modutara nola jarri zaren. Baimen horrekin, aplikazioek kontaktuen datuak gorde ditzakete, eta aplikazio gaiztoek haiek parteka ditzakete zuk jakin gabe."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Android TV gailuan gordetako kontaktuei buruzko datuak irakurtzeko baimena ematen die aplikazioei; besteak beste, pertsona zehatzei zer maiztasunekin deitu diezun edo bidali dizkiezun mezu elektronikoak, edo haiekin zer beste modutara jarri zaren harremanetan. Baimen horrekin, aplikazioek kontaktuen datuak gorde ditzakete, eta baliteke aplikazio gaiztoek zuk jakin gabe partekatzea datu horiek."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Telefonoan gordetako kontaktuei buruzko datuak irakurtzeko baimena ematen die aplikazioei, besteak beste, pertsona zehatzei zer maiztasunekin deitu diezun, mezu elektronikoak bidali dizkiezun edo haiekin harremanetan beste modutara nola jarri zaren. Baimen horrekin, aplikazioek kontaktuen datuak gorde ditzakete, eta aplikazio gaiztoek haiek parteka ditzakete zuk jakin gabe."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Tabletan gordetako kontaktuei buruzko datuak irakurtzeko baimena ematen dio aplikazioari. Kontaktuak sortu dituzten tabletako kontuak ere atzitu ahalko dituzte aplikazioek. Horrek barnean hartuko ditu instalatutako aplikazioek sortutako kontuak, agian. Baimen horrekin, kontaktuen datuak gorde ditzakete aplikazioek, eta baliteke aplikazio gaiztoek zuk jakin gabe partekatzea datu horiek."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Android TV gailuan gordetako kontaktuei buruzko datuak irakurtzeko baimena ematen dio aplikazioari. Kontaktuak sortu dituzten Android TV gailuko kontuak ere atzitu ahalko dituzte aplikazioek. Horrek barnean hartuko ditu instalatutako aplikazioek sortutako kontuak, agian. Baimen horrekin, kontaktuen datuak gorde ditzakete aplikazioek, eta baliteke aplikazio gaiztoek zuk jakin gabe partekatzea datu horiek."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Telefonoan gordetako kontaktuei buruzko datuak irakurtzeko baimena ematen dio aplikazioari. Kontaktuak sortu dituzten telefonoko kontuak ere atzitu ahalko dituzte aplikazioek. Horrek barnean hartuko ditu instalatutako aplikazioek sortutako kontuak, agian. Baimen horrekin, kontaktuen datuak gorde ditzakete aplikazioek, eta baliteke aplikazio gaiztoek zuk jakin gabe partekatzea datu horiek."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"aldatu kontaktuak"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Tabletan gordetako kontaktuei buruzko datuak aldatzeko baimena ematen die aplikazioei, besteak beste, kontatu zehatzei zer maiztasunekin deitu diezun, mezu elektronikoak bidali dizkiezun edo haiekin harremanetan beste modutara nola jarri zaren. Baimen horrekin, aplikazioek kontaktuen datuak ezaba ditzakete."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Android TV gailuan gordetako kontaktuei buruzko datuak aldatzeko baimena ematen die aplikazioei; besteak beste, kontaktu zehatzei zer maiztasunekin deitu diezun edo bidali dizkiezun mezu elektronikoak, edo haiekin harremanetan zer beste modutara jarri zaren. Baimen horrekin, kontaktuen datuak ezaba ditzakete aplikazioek."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Telefonoan gordetako kontaktuei buruzko datuak aldatzeko baimena ematen die aplikazioei, besteak beste, kontatu zehatzei zer maiztasunekin deitu diezun, mezu elektronikoak bidali dizkiezun edo haiekin harremanetan beste modutara nola jarri zaren. Baimen horrekin, aplikazioek kontaktuen datuak ezaba ditzakete."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Tabletan gordetako kontaktuei buruzko datuak aldatzeko baimena ematen dio aplikazioari. Baimen horrekin, aplikazioek kontaktuen datuak ezaba ditzakete."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Android TV gailuan gordetako kontaktuei buruzko datuak aldatzeko baimena ematen dio aplikazioari. Baimen horrekin, aplikazioek kontaktuen datuak ezaba ditzakete."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Telefonoan gordetako kontaktuei buruzko datuak aldatzeko baimena ematen dio aplikazioari. Baimen horrekin, aplikazioek kontaktuen datuak ezaba ditzakete."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"irakurri deien erregistroa"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Aplikazioak deien historia irakur dezake."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"idatzi deien erregistroan"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"atzitu kokapen-hornitzaileen komando gehigarriak"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Kokapen-hornitzailearen agindu gehigarriak atzitzeko baimena ematen die aplikazioei. Horrela, agian aplikazioek GPSaren edo bestelako kokapenaren iturburuen funtzionamenduan eragina izan dezakete."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"lortu kokapen zehatza aurreko planoan bakarrik"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Aplikazioak zure kokapen zehatza lor dezake aurreko planoan funtzionatzen duenean bakarrik. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telefonoan, aplikazioak erabil ditzan. Baliteke bateria gehiago erabiltzea."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"Atzitu sarean oinarritutako gutxi gorabeherako kokapena aurreko planoan bakarrik"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Aplikazioa aurreko planoan dagoenean, zure kokapenaren berri izan dezake sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu tabletan, aplikazioak erabil ditzan."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Aurreko planoan daudenean, aplikazioek zure kokapenaren berri izan dezakete sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta wifi-sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu Android TV gailuan, aplikazioek erabil ditzaten."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Aplikazioa aurreko planoan dagoenean, zure kokapenaren berri izan dezake sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telefonoan, aplikazioak erabil ditzan."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Aplikazioak aurreko planoan funtzionatzen duenean bakarrik lor dezake zure kokapen zehatza. Kokapen-zerbitzuak aktibatuta eta erabilgarri eduki behar dituzu gailuan, aplikazioak erabil ditzan. Baliteke bateria gehiago erabiltzea."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"atzitu gutxi gorabeherako kokapena aurreko planoan bakarrik"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Aplikazioak aurreko planoan funtzionatzen duenean bakarrik lor dezake zure gutxi gorabeherako kokapena. Kokapen-zerbitzuak aktibatuta eta erabilgarri eduki behar dituzu gailuan, aplikazioak erabil ditzan."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"Atzitu kokapena atzeko planoan"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Baimen hau ematen bada kokapen zehatz edo gutxi gorabeherakorako sarbideaz gain, atzeko planoan abian den bitartean atzitu ahalko du aplikazioak kokapena."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Aurreko planoan egotean bezala, aplikazioak kokapena atzi dezake atzeko planoan egotean."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"aldatu audio-ezarpenak"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Audio-ezarpen orokorrak aldatzeko baimena ematen dio; besteak beste, bolumena eta irteerarako zer bozgorailu erabiltzen den."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"grabatu audioa"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Tabletaren Bluetooth konfigurazioa ikusteko eta parekatutako gailuekin konexioak egiteko eta onartzeko baimena ematen die aplikazioei."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Android TV gailuaren Bluetooth konexioaren konfigurazioa ikusteko eta parekatutako gailuekin konexioak sortzeko eta onartzeko baimena ematen die aplikazioei."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Telefonoaren Bluetooth konfigurazioa ikusteko eta parekatutako gailuekin konexioak egiteko eta onartzeko baimena ematen die aplikazioei."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolatu Near Field Communication komunikazioa"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Near Field Communication (NFC) etiketekin, txartelekin eta irakurgailuekin komunikatzea baimentzen die aplikazioei."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"desgaitu pantailaren blokeoa"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> zerbitzura konektatuta"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Sakatu fitxategiak ikusteko"</string>
<string name="pin_target" msgid="8036028973110156895">"Ainguratu"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Kendu aingura"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Aplikazioari buruzko informazioa"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Demoa abiarazten…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" zerbitzuan eguneratu nahi dituzu <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> eta <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Gorde"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Ez, eskerrik asko"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Orain ez"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Inoiz ez"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Eguneratu"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Egin aurrera"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"pasahitza"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Aktibatu/Desaktibatu pantaila zatitua"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Pantaila blokeatua"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Pantaila-argazkia"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioa dago leiho gainerakor batean"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioko azpitituluen barra."</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 433d4f3..96efcab 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"برنامه سرپرست نمایه کاری یا وجود ندارد یا خراب است. در نتیجه، نمایه کاری شما و دادههای مرتبط با آن حذف شده است. برای دریافت راهنمایی با سرپرست سیستم تماس بگیرید."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"نمایه کاری شما دیگر در این دستگاه دردسترس نیست"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"تلاشهای بسیار زیادی برای وارد کردن گذرواژه انجام شده است"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"سرپرست از این دستگاه برای استفاده شخصی چشمپوشی کرد"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"دستگاه مدیریت میشود"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"سازمانتان این دستگاه را مدیریت میکند و ممکن است ترافیک شبکه را پایش کند. برای اطلاع از جزئیات، ضربه بزنید."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"دستگاهتان پاک خواهد شد"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"به برنامه اجازه میدهد همهفرستیهای چسبان ارسال کند که پس از اتمام همهفرستی باقی میمانند. استفاده بیشازحد از این مجوز میتواند باعث استفاده خیلی زیاد از حافظه شود که به کندی یا ناپایداری Android TV منجر میشود."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"به برنامه اجازه میدهد تا پخشهای ماندگار را که پس از اتمام پخش باقی میمانند ارسال کند. استفاده بیش از حد این ویژگی ممکن است باعث مصرف بیش از حد حافظه و در نتیجه کندی یا ناپایداری تلفن شود."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"خواندن مخاطبین شما"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیره شده در رایانهٔ لوحی شما را بخواند از جمله، تعداد دفعات تماسهایی که برقرار کردهاید، ایمیلهایی که ارسال کردهاید یا به روشهای دیگری به افراد خاصی ارتباط برقرار کردهاید. این با برنامهها امکان میدهد دادههای مخاطب شما را ذخیره کنند و برنامههای مخرب ممکن است دادههای مخاطب را بدون اطلاع شما به اشتراک بگذارند."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیرهشده در دستگاه Android TV شما را بخواند، ازجمله تعداد دفعاتی که با افراد خاصی تماس گرفتهاید، برایشان ایمیل ارسال کردهاید، یا به روشهای دیگری با آنها ارتباط برقرار کردهاید. این مجوز به برنامهها اجازه میدهد دادههای مخاطب شما را ذخیره کنند، و ممکن است برنامههای مخرب بدون اطلاع شما دادههای مخاطب را همرسانی کنند."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیره شده در تلفن شما را بخواند از جمله، تعداد دفعات تماسهایی که برقرار کردهاید، ایمیلهایی که ارسال کردهاید یا به روشهای دیگری با افراد خاصی ارتباط برقرار کردهاید. این به برنامهها امکان میدهد دادههای مخاطب شما را ذخیره کنند و برنامههای مخرب ممکن است دادههای مخاطب را بدون اطلاع شما به اشتراک بگذارند."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیرهشده در رایانه لوحی شما را بخواند. برنامهها همچنین به حسابهای موجود در رایانه لوحی که مخاطبین ایجاد کردهاند دسترسی خواهند داشت. میتواند شامل حسابهایی باشد که توسط برنامههایی که نصب کردهاید، ایجاد شده است. این مجوز به برنامهها اجازه میدهد دادههای مخاطب شما را ذخیره کنند، و ممکن است برنامههای مخرب بدون اطلاع شما دادههای مخاطب را همرسانی کنند."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیرهشده در دستگاه Android TV شما را بخواند. برنامهها همچنین به حسابهای موجود در دستگاه Android TV که مخاطبین ایجاد کردهاند دسترسی خواهد داشت. میتواند شامل حسابهایی باشد که توسط برنامههایی که نصب کردهاید، ایجاد شده است. این مجوز به برنامهها اجازه میدهد دادههای مخاطب شما را ذخیره کنند، و ممکن است برنامههای مخرب بدون اطلاع شما دادههای مخاطب را همرسانی کنند."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیرهشده در تلفن را بخواند. برنامهها همچنین به حسابهای موجود در تلفن که مخاطبین ایجاد کردهاند دسترسی خواهند داشت. میتواند شامل حسابهایی باشد که توسط برنامههایی که نصب کردهاید، ایجاد شده است. این مجوز به برنامهها اجازه میدهد دادههای مخاطب شما را ذخیره کنند، و ممکن است برنامههای مخرب بدون اطلاع شما دادههای مخاطب را همرسانی کنند."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"تغییر مخاطبین"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیره شده در رایانهٔ لوحی شما را از جمله تعداد تماسهایی که برقرار کردهاید، ایمیلهایی که ارسال کردهاید یا ارتباطاتی را که به هر شکل با مخاطبین خاصی برقرار کردید تغییر دهد. این مجوز به برنامه اجازه میدهد دادههای مخاطب را حذف نماید."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیرهشده در دستگاه Android TV شما را تغییر دهد، ازجمله تعداد دفعاتی که با مخاطبین خاصی تماس گرفتهاید، برایشان ایمیل ارسال کردهاید، یا به روشهای دیگری با آنها ارتباط برقرار کردهاید. این مجوز به برنامهها اجازه میدهد دادههای مخاطب را حذف کنند."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیره شده در تلفن شما را از جمله تعداد تماسهایی که برقرار کردهاید، ایمیلهایی که ارسال کردهاید یا ارتباطاتی را که به هر شکل با مخاطبین خاصی برقرار کردید تغییر دهد. این مجوز به برنامه اجازه میدهد دادههای مخاطب را حذف نماید."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیرهشده در رایانه لوحی شما را تغییر دهد. این مجوز به برنامهها اجازه میدهد دادههای مخاطب را حذف کنند."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیرهشده در دستگاه Android TV شما را تغییر دهد. این مجوز به برنامهها اجازه میدهد دادههای مخاطب را حذف کنند."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"به برنامه اجازه میدهد دادههای مربوط به مخاطبین ذخیرهشده در تلفنتان را تغییر دهد. این مجوز به برنامهها اجازه میدهد دادههای مخاطب را حذف کنند."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"خواندن گزارش تماس"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"این برنامه میتواند سابقه تماس شما را بخواند."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"نوشتن گزارش تماس"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"دسترسی به فرمانهای بیشتر ارائه دهنده مکان"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"به برنامه اجازه میدهد به دستورات ارائهدهنده مکان تکمیلی دسترسی داشته باشد. این کار ممکن است به برنامه امکان دهد با کارکرد GPS یا منابع دیگر مکان تداخل داشته باشد."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"دسترسی به مکان دقیق فقط در پیشزمینه"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"این برنامه فقط زمانی میتواند موقعیت مکانی دقیق شما را دریافت کند که در پیشزمینه باشد. برای اینکه برنامه بتواند از خدمات مکان استفاده کند، این خدمات باید در تلفنتان روشن و دردسترس باشد. ممکن است با این کار مصرف باتری افزایش یابد."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"دسترسی به مکان تقریبی (مبتنی بر شبکه) فقط در پیشزمینه"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"این برنامه میتواند براساس منابع شبکه مانند دکلهای مخابراتی و شبکههای Wi-Fi، مکانتان را تشخیص دهد، اما فقط درصورتیکه برنامه در پیشزمینه باشد. این خدمات مکان باید روشن و در رایانه لوحی شما دردسترس باشند تا برنامه بتواند از آنها استفاده کند."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"این برنامه میتواند براساس منابع شبکه، مانند دکلهای مخابراتی و شبکههای Wi-Fi، مکانتان را تشخیص دهد، اما فقط درصورتیکه برنامه در پیشزمینه باشد. این خدمات مکان باید در دستگاه Android TV شما روشن و دردسترس باشد تا برنامه بتواند از آنها استفاده کند."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"این برنامه میتواند براساس منابع شبکه مانند دکلهای مخابراتی و شبکههای Wi-Fi، مکانتان را تشخیص دهد، اما فقط درصورتیکه برنامه در پیشزمینه است. این خدمات مکان باید روشن و در تلفن شما دردسترس باشند تا برنامه بتواند از آنها استفاده کند."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"این برنامه فقط زمانی میتواند موقعیت مکانی دقیق شما را دریافت کند که در پیشزمینه باشد. برای اینکه برنامه بتواند از خدمات مکان استفاده کند، این خدمات باید در دستگاهتان روشن و در دسترس باشد. ممکن است با این کار مصرف باتری افزایش یابد."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"دسترسی به مکان تقریبی فقط در پیشزمینه"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"این برنامه فقط هنگامیکه در پیشزمینه است میتواند مکان تقریبی شما را دریافت کند. برای اینکه برنامه بتواند از خدمات مکان استفاده کند، این خدمات باید روشن و در دستگاهتان در دسترس باشند."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"دسترسی به مکان در پسزمینه"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"اگر این مجوز نیز برای دسترسی دقیق یا تقریبی به مکان داده شود، برنامه میتواند درحین اجرا در پسزمینه به مکان دسترسی پیدا کند."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"این برنامه علاوهبر دسترسی به مکان در پیشزمینه، میتواند هنگام اجرا در پسزمینه نیز به مکان دسترسی داشته باشد."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"تغییر تنظیمات صوتی"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"به برنامه امکان میدهد تنظیمات صوتی کلی مانند میزان صدا و بلندگوی مورد استفاده برای پخش صدا را تغییر دهد."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ضبط صدا"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"به برنامه اجازه میدهد تا پیکربندی بلوتوث در رایانهٔ لوحی را مشاهده کند و اتصال با دستگاههای مرتبط را برقرار کرده و بپذیرد."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"به برنامه اجازه میدهد پیکربندی بلوتوث را در دستگاه Android TV شما ببیند، و اتصالات با دستگاههای مرتبطشده را بپذیرد یا این اتصالات را برقرار کند."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"به برنامه اجازه میدهد تا پیکربندی بلوتوث در تلفن را مشاهده کند، و اتصالات دستگاههای مرتبط را برقرار کرده و بپذیرد."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"کنترل ارتباط راه نزدیک"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"به برنامه اجازه میدهد تا با تگهای «ارتباط میدان نزدیک» (NFC)، کارتها و فایلخوان ارتباط برقرار کند."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"غیرفعال کردن قفل صفحه شما"</string>
@@ -1177,7 +1178,7 @@
<string name="screen_compat_mode_scale" msgid="8627359598437527726">"مقیاس"</string>
<string name="screen_compat_mode_show" msgid="5080361367584709857">"همیشه نشان داده شود"</string>
<string name="screen_compat_mode_hint" msgid="4032272159093750908">"در تنظیمات سیستم >برنامهها > مورد بارگیری شده آن را دوباره فعال کنید."</string>
- <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> از تنظیم فعلی اندازه نمایشگر پشتیبانی نمیکند و ممکن است رفتار غیرمنتظرهای داشته باشد."</string>
+ <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> از تنظیم فعلی اندازه نمایش پشتیبانی نمیکند و ممکن است رفتار غیرمنتظرهای داشته باشد."</string>
<string name="unsupported_display_size_show" msgid="980129850974919375">"همیشه نشان داده شود"</string>
<string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> برای نسخه ناسازگار سیستمعامل Android ساخته شده است و ممکن است رفتاری برخلاف انتظار داشته باشد. ممکن است نسخه بهروزی از برنامه در دسترس باشد."</string>
<string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"همیشه نشان داده شود"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"به <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> متصل شد"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"برای دیدن فایلها، ضربه بزنید"</string>
<string name="pin_target" msgid="8036028973110156895">"پین کردن"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"برداشتن پین"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"اطلاعات برنامه"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"در حال شروع نسخه نمایشی…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"این موارد در "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>، <xliff:g id="TYPE_1">%2$s</xliff:g> و <xliff:g id="TYPE_2">%3$s</xliff:g> بهروزرسانی شود؟"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"ذخیره"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"نه سپاسگزارم"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"حالا نه"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"هیچوقت"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"بهروزرسانی"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"ادامه"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"گذرواژه"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"تغییر وضعیت صفحهٔ دونیمه"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"صفحه قفل"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"عکس صفحهنمایش"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"برنامه <xliff:g id="APP_NAME">%1$s</xliff:g> در پنجره بالاپر."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"نوار شرح <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 0c7bd77..f7a54fb 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Työprofiilin hallintasovellus puuttuu tai se on vioittunut. Tästä syystä työprofiilisi ja siihen liittyvät tiedot on poistettu. Pyydä ohjeita järjestelmänvalvojaltasi."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Työprofiilisi ei ole enää käytettävissä tällä laitteella."</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Liikaa salasanayrityksiä"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Järjestelmänvalvoja luovutti laitteen henkilökohtaiseen käyttöön"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Hallinnoitu laite"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organisaatiosi hallinnoi tätä laitetta ja voi tarkkailla verkkoliikennettä. Katso lisätietoja napauttamalla."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Laitteen tiedot poistetaan"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Antaa sovelluksen lähettää pysyviä lähetyksiä, jotka säilyvät lähetyksen päätyttyä. Liiallinen käyttö voi tehdä Android TV ‑laitteesta hitaan tai epävakaan lisäämällä sen muistinkäyttöä liikaa."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Antaa sovelluksen lähettää pysyviä lähetyksiä, jotka säilyvät lähetyksen päätyttyä. Liiallinen käyttö voi tehdä puhelimesta hitaan tai epävakaan kasvattamalla sen muistinkäyttöä liikaa."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"lue yhteystietoja"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Antaa sovelluksen lukea tablet-laitteeseesi tallennettuja kontaktitietoja sekä tarkastella, kuinka usein olet soittanut, lähettänyt sähköpostia tai muuten viestinyt tiettyjen kontaktien kanssa. Tämän luvan saaneet sovellukset voivat tallentaa kontaktitietoja. Haitalliset sovellukset voivat jakaa kontaktitietoja ilman lupaasi."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Antaa sovelluksen lukea Android TV ‑laitteeseen tallennettuja kontaktitietoja sekä nähdä, kuinka usein olet soitellut, lähettänyt sähköpostia tai muuten viestinyt tiettyjen kontaktien kanssa. Tämän luvan saaneet sovellukset voivat tallentaa kontaktitietoja. Haitalliset sovellukset voivat jakaa kontaktitietoja ilman lupaasi."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Antaa sovelluksen lukea puhelimeesi tallennettuja kontaktitietoja sekä tarkastella, kuinka usein olet soittanut, lähettänyt sähköpostia tai muuten viestinyt tiettyjen kontaktien kanssa. Tämän luvan saaneet sovellukset voivat tallentaa kontaktitietoja. Haitalliset sovellukset voivat jakaa kontaktitietoja ilman lupaasi."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Antaa sovelluksen lukea tabletille tallennettujen kontaktien tietoja. Sovellukset saavat myös pääsyn tablettisi tileille, joilla on luotu kontaktitietoja. Tilit voivat olla myös asentamiesi sovellusten luomia. Tämän luvan saaneet sovellukset voivat tallentaa kontaktitietoja. Haitalliset sovellukset voivat jakaa kontaktitietoja ilman lupaasi."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Antaa sovelluksen lukea Android TV ‑laitteelle tallennettujen kontaktien tietoja. Sovellukset saavat myös pääsyn Android TV ‑laitteesi tileille, joilla on luotu kontaktitietoja. Tilit voivat olla myös asentamiesi sovellusten luomia. Tämän luvan saaneet sovellukset voivat tallentaa kontaktitietoja. Haitalliset sovellukset voivat jakaa kontaktitietoja ilman lupaasi."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Antaa sovelluksen lukea puhelimelle tallennettujen kontaktien tietoja. Sovellukset saavat myös pääsyn puhelimen tileille, joilla on luotu kontaktitietoja. Tilit voivat olla myös asentamiesi sovellusten luomia. Tämän luvan saaneet sovellukset voivat tallentaa kontaktitietoja. Haitalliset sovellukset voivat jakaa kontaktitietoja ilman lupaasi."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"muokkaa yhteystietoja"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Antaa sovelluksen muokata tablet-laitteeseesi tallennettuja kontaktitietoja sekä tarkastella, kuinka usein olet soittanut, lähettänyt sähköpostia tai muuten viestinyt tiettyjen kontaktien kanssa. Tämän luvan saaneet sovellukset voivat poistaa kontaktitietoja."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Antaa sovelluksen muokata Android TV ‑laitteeseen tallennettujen kontaktiesi dataa sekä nähdä, kuinka usein olet soitellut, lähettänyt sähköpostia tai muuten viestinyt tiettyjen kontaktien kanssa. Tämän luvan saaneet sovellukset voivat poistaa kontaktitietoja."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Antaa sovelluksen muokata puhelimeesi tallennettuja kontaktitietoja sekä tarkastella, kuinka usein olet soittanut, lähettänyt sähköpostia tai muuten viestinyt tiettyjen kontaktien kanssa. Tämän luvan saaneet sovellukset voivat poistaa kontaktitietoja."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Antaa sovelluksen muokata tabletille tallennettujen kontaktien tietoja. Käyttöluvan saaneet sovellukset voivat myös poistaa kontaktitietoja."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Antaa sovelluksen muokata Android TV ‑laitteelle tallennettujen kontaktien tietoja. Käyttöluvan saaneet sovellukset voivat myös poistaa kontaktitietoja."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Antaa sovelluksen muokata puhelimelle tallennettujen kontaktien tietoja. Käyttöluvan saaneet sovellukset voivat myös poistaa kontaktitietoja."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"lue puhelulokia"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Tämä sovellus voi lukea puheluhistoriaasi."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"kirjoita puhelulokiin"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"käytä lisää sijainnintarjoajakomentoja"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Antaa sovelluksen käyttää ylimääräisiä sijaintipalvelukomentoja. Sovellus saattaa tällöin häiritä GPS:n tai muiden sijaintilähteiden toimintaa."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"käyttää tarkkaa sijaintia vain etualalla"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Tämä sovellus saa tarkat sijaintitietosi käyttöönsä vain etualalla. Näiden sijaintipalveluiden tulee olla käytössä ja käytettävissä puhelimellasi, jotta sovellus voi käyttää niitä. Tämä voi lisätä akun kulutusta."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"käyttää karkeaa verkkoon perustuvaa sijaintia vain etualalla"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Tämä sovellus voi määrittää sijaintisi matkapuhelinverkon tukiasemien, Wi-Fi-verkkojen ja muiden verkkolähteiden perusteella vain jos sovellus on etualalla. Näiden sijaintipalveluiden tulee olla päällä ja käytettävissä tabletilla, jotta sovellus voi käyttää niitä."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Tämä sovellus voi määrittää sijaintisi matkapuhelinverkon tukiasemien, Wi-Fi-verkkojen ja muiden verkkolähteiden perusteella vain jos sovellus on etualalla. Näiden sijaintipalveluiden tulee olla päällä ja käytettävissä Android TV ‑laitteessa, jotta sovellus voi käyttää niitä."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Tämä sovellus voi määrittää sijaintisi matkapuhelinverkon tukiasemien, Wi-Fi-verkkojen ja muiden verkkolähteiden perusteella vain jos sovellus on etualalla. Näiden sijaintipalveluiden tulee olla päällä ja käytettävissä puhelimessa, jotta sovellus voi käyttää niitä."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Tämä sovellus saa tarkat sijaintitietosi käyttöönsä vain etualalla. Sijaintipalveluiden tulee olla päällä ja käytettävissä laitteella, jotta sovellus voi käyttää niitä. Tämä voi lisätä akun kulutusta."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"käyttää karkeaa sijaintia vain etualalla"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Tämä sovellus saa karkean sijaintisi käyttöönsä vain ollessaan etualalla. Sijaintipalveluiden tulee olla päällä ja käytettävissä laitteellasi, jotta sovellus voi käyttää niitä."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"käytä sijaintia taustalla"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Jos tämä myönnetään karkean tai tarkan sijainnin käyttöoikeuden lisäksi, sovellus voi käyttää sijaintia toimiessaan taustalla."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Tämä sovellus voi käyttää sijaintia taustalla ja etualalla."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"muuta ääniasetuksia"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Antaa sovelluksen muokata yleisiä ääniasetuksia, kuten äänenvoimakkuutta ja käytettävää kaiutinta."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"tallentaa ääntä"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Antaa sovelluksen tarkastella tablet-laitteen Bluetooth-asetuksia sekä muodostaa ja hyväksyä laitepariyhteyksiä."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Antaa sovelluksen nähdä Android TV ‑laitteen Bluetooth-asetukset sekä muodostaa ja hyväksyä laitepariyhteyksiä."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Antaa sovelluksen tarkastella puhelimen Bluetooth-asetuksia sekä muodostaa ja hyväksyä laitepariyhteyksiä muihin laitteisiin."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"hallitse Near Field Communication -tunnistusta"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Antaa sovelluksen kommunikoida NFC (Near Field Communication) -tagien, -korttien ja -lukijoiden kanssa."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"poista näytön lukitus käytöstä"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> yhdistetty"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Näytä tiedostot koskettamalla"</string>
<string name="pin_target" msgid="8036028973110156895">"Kiinnitä"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Irrota"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Sovelluksen tiedot"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Aloitetaan esittelyä…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Päivitetäänkö nämä ("<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"): <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ja <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Tallenna"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Ei kiitos"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ei nyt"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Ei koskaan"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Muuta"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Jatka"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"salasana"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Jaettu näyttö päälle/pois"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lukitusnäyttö"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Kuvakaappaus"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Sovellus (<xliff:g id="APP_NAME">%1$s</xliff:g>) ponnahdusikkunassa"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Tekstityspalkki: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 3c8f75f..e7eafa7 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Le profil professionnel de l\'application d\'administration est manquant ou corrompu. Votre profil professionnel et ses données connexes ont donc été supprimés. Communiquez avec votre administrateur pour obtenir de l\'assistance."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Votre profil professionnel n\'est plus accessible sur cet appareil"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Trop de tentatives d\'entrée du mot de passe"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrateur a libéré l\'appareil pour un usage personnel"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"L\'appareil est géré"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Touchez ici pour obtenir plus d\'information."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Le contenu de votre appareil sera effacé"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permet à l\'application d\'envoyer des intentions de diffusion persistantes, qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir votre appareil Android TV ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir le téléphone ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"lire vos contacts"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre tablette, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des courriels ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre appareil Android TV, y compris la fréquence à laquelle vous avez appelé certaines personnes, leur avez envoyé des courriels ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre téléphone, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des courriels ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre tablette. Les applications auront aussi accès aux comptes sur votre tablette qui ont créé des contacts. Cela peut comprendre des comptes créés par des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre appareil Android TV. Les applications auront aussi accès aux comptes sur votre appareil Android TV qui ont créé des contacts. Cela peut comprendre des comptes créés par des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre téléphone. Les applications auront aussi accès aux comptes sur votre téléphone qui ont créé des contacts. Cela peut comprendre des comptes créés par des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modifier vos contacts"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre tablette, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des courriels ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications de supprimer ces données."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre appareil Android TV, y compris la fréquence à laquelle vous avez appelé certaines personnes, leur avez envoyé des courriels ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications de supprimer ces données."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre téléphone, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des courriels ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications de supprimer ces données."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre tablette. Cette autorisation permet aux applications de supprimer des données relatives aux contacts."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre appareil Android TV. Cette autorisation permet aux applications de supprimer des données relatives aux contacts."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre téléphone. Cette autorisation permet aux applications de supprimer des données relatives aux contacts."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"lire le journal d\'appels"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Cette application peut lire votre historique d\'appel."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"modifier le journal d\'appels"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"accéder aux commandes de fournisseur de position géographique supplémentaires"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permet à l\'application d\'accéder à des commandes de localisation supplémentaires offertes par le fournisseur. Elle est ainsi susceptible d\'interférer avec le bon fonctionnement du GPS ou de toute autre source de localisation."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"accéder à votre position précise seulement en avant-plan"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Cette application peut obtenir votre position exacte seulement lorsqu\'elle fonctionne en avant-plan. Ces services de localisation doivent être activés et accessibles sur votre téléviseur pour que l\'application puisse les utiliser. Cela peut entraîner une utilisation accrue de la pile."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"accéder à la position approximative (selon les données réseau), mais uniquement lorsque l\'application s\'exécute au premier plan"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Cette application peut déterminer votre position à l\'aide de différentes sources de localisation sur le réseau, comme les tours de téléphonie cellulaire et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et accessibles sur votre tablette pour que l\'application puisse les utiliser."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Cette application peut déterminer votre position à l\'aide de différentes sources de localisation sur le réseau, comme les tours de téléphonie cellulaire et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et accessibles sur votre appareil Android TV pour que l\'application puisse les utiliser."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Cette application peut déterminer votre position à l\'aide de différentes sources de localisation sur le réseau, comme les tours de téléphonie cellulaire et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et accessibles sur votre téléphone pour que l\'application puisse les utiliser."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Cette application peut obtenir votre position exacte seulement lorsqu\'elle fonctionne en avant-plan. Les services de localisation doivent être activés et accessibles sur votre appareil pour que l\'application puisse les utiliser. Cela peut entraîner une utilisation accrue de la pile."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"accéder à votre position approximative seulement en avant-plan"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Cette application peut seulement obtenir votre position approximative lorsqu\'elle fonctionne en avant-plan. Les services de localisation doivent être activés et accessibles sur votre appareil pour que l\'application puisse les utiliser."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"accès à la localisation en arrière-plan"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Si cette autorisation est accordée en plus de l\'accès approximatif ou précis à la localisation, alors l\'application peut accéder à la localisation lorsqu\'elle fonctionne en arrière-plan."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Cette application peut accéder à la position en arrière-plan, en plus d\'en avant-plan."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"modifier vos paramètres audio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permet à l\'application de modifier les paramètres audio généraux, tels que le volume et la sortie audio utilisée."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"enregistrer des fichiers audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur la tablette, et d\'établir et accepter des connexions avec les appareils associés."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permet à l\'application d\'afficher la configuration du Bluetooth sur votre appareil Android TV, de se connecter à des appareils associés et d\'accepter leur connexion."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur le téléphone, et d\'établir et accepter des connexions avec les appareils associés."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"gérer la communication en champ proche"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Permet à l\'application de communiquer avec des bornes, des cartes et des lecteurs compatibles avec la technologie NFC (communication en champ proche)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"désactiver le verrouillage de l\'écran"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Connecté à <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Touchez ici pour afficher les fichiers"</string>
<string name="pin_target" msgid="8036028973110156895">"Épingler"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Annuler l\'épinglage"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Détails de l\'application"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Démarrage de la démonstration en cours…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Mettre à jour ces éléments sous "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" : <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> et <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Enregistrer"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Non, merci"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Pas maintenant"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Jamais"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Mettre à jour"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continuer"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"mot de passe"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Basculer l\'écran partagé"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Écran de verrouillage"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Capture d\'écran"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Application <xliff:g id="APP_NAME">%1$s</xliff:g> dans une fenêtre contextuelle."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barre de légende de l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 1b53bd9..f9ec0c2 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"L\'application d\'administration du profil professionnel est manquante ou endommagée. Par conséquent, votre profil professionnel et toutes les données associées ont été supprimés. Pour obtenir de l\'aide, contactez l\'administrateur."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Votre profil professionnel n\'est plus disponible sur cet appareil"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Trop de tentatives de saisie du mot de passe"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrateur a mis l\'appareil à disposition pour un usage personnel"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"L\'appareil est géré"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Appuyez ici pour obtenir plus d\'informations."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Les données de votre appareil vont être effacées"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permet à l\'application d\'envoyer des diffusions \"persistantes\", qui perdurent une fois la diffusion effectuée. Une utilisation excessive peut ralentir votre appareil Android TV ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir le téléphone ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"Voir les contacts"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre tablette, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des e-mails ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Permet à l\'application de lire les données liées aux contacts stockés sur votre appareil Android TV, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des e-mails ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Des applications malveillantes peuvent exploiter cette fonctionnalité pour partager ces données à votre insu."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre téléphone, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des e-mails ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permet à l\'application de lire les données liées aux contacts stockés sur votre tablette. Les applications auront également accès aux comptes de votre tablette pour lesquels des contacts ont été créés. Cela peut inclure les comptes créés via des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer les données liées à vos contacts. Des applications malveillantes peuvent exploiter cette fonctionnalité pour partager ces données à votre insu."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permet à l\'application de lire les données liées aux contacts stockés sur votre appareil Android TV. Les applications auront également accès aux comptes de votre appareil Android TV pour lesquels des contacts ont été créés. Cela peut inclure les comptes créés via des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer les données liées à vos contacts. Des applications malveillantes peuvent exploiter cette fonctionnalité pour partager ces données à votre insu."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permet à l\'application de lire les données liées aux contacts stockés sur votre téléphone. Les applications auront également accès aux comptes de votre téléphone pour lesquels des contacts ont été créés. Cela peut inclure les comptes créés via des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer les données liées à vos contacts. Des applications malveillantes peuvent exploiter cette fonctionnalité pour partager ces données à votre insu."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modifier les contacts"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre tablette, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des e-mails ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications de supprimer ces données."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Permet à l\'application de modifier les données liées aux contacts stockés sur votre appareil Android TV, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des e-mails ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications de supprimer ces données."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre téléphone, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des e-mails ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications de supprimer ces données."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permet à l\'application de modifier les données liées aux contacts stockés sur votre tablette. Cette autorisation permet aux applications de supprimer ces données."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permet à l\'application de modifier les données liées aux contacts stockés sur votre appareil Android TV. Cette autorisation permet aux applications de supprimer ces données."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permet à l\'application de modifier les données liées aux contacts stockés sur votre téléphone. Cette autorisation permet aux applications de supprimer ces données."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"lire le journal d\'appels"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Cette application peut lire l\'historique de vos appels."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"modifier le journal d\'appels"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"Accès aux commandes de fournisseur de position géographique supplémentaires"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permet à l\'application d\'accéder à des commandes de localisation supplémentaires offertes par le fournisseur. Elle est ainsi susceptible d\'interférer avec le bon fonctionnement du GPS ou de toute autre source de localisation."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"accéder à la position exacte au premier plan uniquement"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Cette application peut obtenir votre position exacte uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et disponibles sur votre téléphone pour que l\'application puisse les utiliser. Ceci peut réduire l\'autonomie de la batterie."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"accéder à la position approximative (à l\'aide des réseaux) au premier plan uniquement"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Cette application peut obtenir votre position à l\'aide de sources de réseau telles que les antennes-relais et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et disponibles sur votre tablette pour que l\'application puisse les utiliser."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Cette application peut obtenir votre position à l\'aide de sources de réseau telles que les antennes-relais et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et disponibles sur votre appareil Android TV pour que l\'application puisse les utiliser."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Cette application peut obtenir votre position à l\'aide de sources de réseau telles que les antennes-relais et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et disponibles sur votre téléphone pour que l\'application puisse les utiliser."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Cette application peut obtenir votre position exacte uniquement lorsqu\'elle s\'exécute au premier plan. Les services de localisation doivent être activés et disponibles sur votre appareil pour que l\'application puisse les utiliser. Ceci peut réduire l\'autonomie de la batterie."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"accéder à la position approximative au premier plan uniquement"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Cette application peut obtenir votre position approximative uniquement lorsqu\'elle s\'exécute au premier plan. Les services de localisation doivent être activés et disponibles sur votre appareil pour que l\'application puisse les utiliser."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"accéder à la position en arrière-plan"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Si vous lui accordez cette autorisation en plus de l\'accès à la position approximative ou précise, l\'application peut accéder à votre position lorsqu\'elle est s\'exécute en arrière-plan."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"En plus de l\'accès à la position en premier plan, cette application peut y accéder lorsqu\'elle s\'exécute en arrière-plan."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"modifier vos paramètres audio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permet à l\'application de modifier les paramètres audio généraux, tels que le volume et la sortie audio utilisée."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"enregistrer des fichiers audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur la tablette, et d\'établir et accepter des connexions avec les appareils associés."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permet à l\'application d\'afficher la configuration du Bluetooth sur votre appareil Android TV, de se connecter à des appareils associés et d\'accepter leur connexion."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur le téléphone, et d\'établir et accepter des connexions avec les appareils associés."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"contrôler la communication en champ proche"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Permet à l\'application de communiquer avec des tags, des cartes et des lecteurs compatibles avec la technologie NFC (communication en champ proche)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"Désactiver le verrouillage de l\'écran"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Connecté à <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Appuyez ici pour voir les fichiers."</string>
<string name="pin_target" msgid="8036028973110156895">"Épingler"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Retirer"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Infos sur l\'appli"</string>
<string name="negative_duration" msgid="1938335096972945232">"− <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Lancement de la démo…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Mettre à jour les éléments <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> et <xliff:g id="TYPE_2">%3$s</xliff:g> dans "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Enregistrer"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Non, merci"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Pas maintenant"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Jamais"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Mettre à jour"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continuer"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"mot de passe"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activer/Désactiver l\'écran partagé"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Verrouiller l\'écran"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Capture d\'écran"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Application <xliff:g id="APP_NAME">%1$s</xliff:g> dans la fenêtre pop-up."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barre de légende de l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 4572db7..4ddce8b 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Falta a aplicación de administración do perfil de traballo ou ben está danada. Como resultado, eliminouse o teu perfil de traballo e os datos relacionados. Para obter asistencia, contacta co administrador."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"O teu perfil de traballo xa non está dispoñible neste dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Demasiados intentos de introdución do contrasinal"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador renunciou ao dispositivo para uso persoal"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo está xestionado"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"A túa organización xestiona este dispositivo e pode controlar o tráfico de rede. Toca para obter máis detalles."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Borrarase o teu dispositivo"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permite que a aplicación envíe emisións permanentes que continúan unha vez finalizada a emisión. Un uso excesivo pode provocar que o dispositivo Android TV funcione con lentitude ou de forma inestable debido á necesidade de utilizar demasiada memoria."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permite á aplicación enviar difusións permanentes que continúan unha vez finalizada a difusión. Un uso excesivo pode provocar que o teléfono funcione con lentitude ou de forma inestable debido á necesidade de utilizar demasiada memoria."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"ler os teus contactos"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Permite á aplicación ler datos acerca dos teus contactos almacenados na tableta, incluída a frecuencia coa que os chamaches, lles enviaches un correo electrónico ou te comunicaches con individuos específicos doutras formas. Con este permiso as aplicacións poden gardar os teus datos de contacto e as aplicacións maliciosas poden compartir os datos de contacto sen o teu coñecemento."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Permite que a aplicación lea datos acerca dos contactos que tes almacenados no dispositivo Android TV, incluída a frecuencia coa que lles chamaches, lles enviaches un correo electrónico ou te comunicaches con individuos específicos doutras formas. Con este permiso as aplicacións poden gardar os teus datos de contacto e as aplicacións maliciosas poden compartir os datos de contacto sen o teu coñecemento."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Permite á aplicación ler datos acerca dos teus contactos almacenados no teléfono, incluída a frecuencia coa que os chamaches, lles enviaches un correo electrónico ou te comunicaches con individuos específicos doutras formas. Con este permiso as aplicacións poden gardar os teus datos de contacto e as aplicacións maliciosas poden compartir os datos de contacto sen o teu coñecemento."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permite que a aplicación lea datos sobre os contactos almacenados na túa tableta. As aplicacións tamén terán acceso ás contas da túa tableta que creasen contactos, entre as que se poden incluír as creadas polas aplicacións que instalases. Con este permiso as aplicacións poden gardar os teus datos de contacto e as aplicacións maliciosas poden compartir os datos mencionados sen o teu coñecemento."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permite que a aplicación lea datos sobre os contactos almacenados no teu dispositivo Android TV. As aplicacións tamén terán acceso ás contas do teu dispositivo Android TV que creasen contactos, entre as que se poden incluír as creadas polas aplicacións que instalases. Con este permiso as aplicacións poden gardar os teus datos de contacto e as aplicacións maliciosas poden compartir os datos mencionados sen o teu coñecemento."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permite que a aplicación lea datos sobre os contactos almacenados no teu teléfono. As aplicacións tamén terán acceso ás contas do teu teléfono que creasen contactos, entre as que se poden incluír as creadas polas aplicacións que instalases. Con este permiso as aplicacións poden gardar os teus datos de contacto e as aplicacións maliciosas poden compartir os datos mencionados sen o teu coñecemento."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modificar os teus contactos"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Permite á aplicación modificar os datos acerca dos teus contactos almacenados na tableta, incluído a frecuencia coa que os chamaches, lles enviaches un correo electrónico ou te comunicaches con contactos específicos doutras formas. Con este permiso as aplicacións poden eliminar datos de contactos."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Permite que a aplicación modifique os datos sobre os contactos almacenados no dispositivo Android TV, incluída a frecuencia coa que lles chamaches, lles enviaches un correo electrónico ou te comunicaches con eles doutra forma. Con este permiso as aplicacións poden eliminar datos de contactos."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Permite á aplicación modificar os datos acerca dos teus contactos almacenados no teléfono, incluída a frecuencia coa que chamaches, enviaches correos electrónicos ou te comunicaches doutras maneiras con contactos específicos. Con este permiso as aplicacións poden eliminar datos de contactos."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permite que a aplicación modifique datos sobre os contactos almacenados na túa tableta. Con este permiso as aplicacións poden eliminar datos de contactos."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permite que a aplicación modifique datos sobre os contactos almacenados no teu dispositivo Android TV. Con este permiso as aplicacións poden eliminar datos de contactos."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permite que a aplicación modifique datos sobre os contactos almacenados no teu teléfono. Con este permiso as aplicacións poden eliminar datos de contactos."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"ler rexistro de chamadas"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Esta aplicación pode ler o teu historial de chamadas."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"escribir no rexistro de chamadas"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acceder a comandos adicionais do provedor de localización"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite á aplicación acceder a comandos adicionais de fornecedor de localizacións. É posible que isto provoque que a aplicación interfira co funcionamento do GPS ou doutras fontes da localización."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"acceder á localización exacta só en primeiro plano"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Esta aplicación pode obter a túa localización exacta só cando se atope en primeiro plano. É necesario activar estes servizos de localización e deben estar dispoñibles no teléfono para que a aplicación poida utilizalos. Ademais, poden supoñer un aumento do consumo de batería."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"acceder á localización aproximada a partir de fontes de rede só en primeiro plano"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Esta aplicación pode obter a túa localización a partir de fontes de rede, como torres de telecomunicacións e redes wifi, pero só mentres está en primeiro plano. Para que a aplicación poida utilizar os servizos de localización, deben estar activados e dispoñibles na túa tableta."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Esta aplicación pode obter a túa localización a partir de fontes de rede, como antenas de telefonía móbil e redes wifi, pero só mentres está en primeiro plano. É necesario activar estes servizos de localización e deben estar dispoñibles no dispositivo Android TV para que a aplicación poida utilizalos."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Esta aplicación pode obter a túa localización a partir de fontes de rede, como torres de telecomunicacións e redes wifi, pero só mentres está en primeiro plano. Para que a aplicación poida utilizar os servizos de localización, deben estar activados e dispoñibles no teu teléfono."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Esta aplicación pode obter a túa localización exacta só cando se atope en primeiro plano. É necesario activar os servizos de localización e deben estar dispoñibles no teléfono para que a aplicación poida utilizalos. Ademais, poden supoñer un aumento do consumo de batería."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acceder á localización aproximada só en primeiro plano"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Esta aplicación pode obter a túa localización aproximada, pero só mentres está en primeiro plano. Para que a aplicación poida utilizar os servizos de localización, deben estar activados e dispoñibles no teu dispositivo."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"acceder á localización en segundo plano"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Se a aplicación ten acceso á localización aproximada ou exacta e lle concedes este permiso, poderá consultar onde te atopas cando estea en segundo plano."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Esta aplicación pode acceder á localización mentres se executa en segundo plano, ademais de acceder á localización en primeiro plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"cambiar a configuración de son"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permite á aplicación modificar a configuración de audio global, como o volume e que altofalante se utiliza para a saída."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"gravar audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permite á aplicación ver a configuración do Bluetooth na tableta e efectuar e aceptar conexións con dispositivos sincronizados."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permite que a aplicación consulte a configuración do Bluetooth no dispositivo Android TV, e efectúe e acepte conexións con dispositivos vinculados."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permite á aplicación ver a configuración do Bluetooth no teléfono e efectuar e aceptar conexións con dispositivos sincronizados."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Permite á aplicación comunicarse con etiquetas, tarxetas e lectores Near Field Communication (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"desactivar o bloqueo da pantalla"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Toca para ver os ficheiros"</string>
<string name="pin_target" msgid="8036028973110156895">"Fixar"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Deixar de fixar"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Info. da aplicación"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Iniciando demostración…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Queres actualizar <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g> en "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Gardar"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Non, grazas"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Agora non"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nunca"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Actualizar"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continuar"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"contrasinal"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activar/desactivar pantalla dividida"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Pantalla de bloqueo"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de pantalla"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> nunha ventá emerxente."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de subtítulos de <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 5e4f753..fdaddc1 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"કાર્ય પ્રોફાઇલ વ્યવસ્થાપક ઍપ્લિકેશન ખૂટે છે અથવા તો દૂષિત છે. પરિણામે, તમારી કાર્યાલયની પ્રોફાઇલ અને તે સંબંધિત ડેટા કાઢી નાખવામાં આવ્યો છે. સહાયતા માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"આ ઉપકરણ પર તમારી કાર્યાલયની પ્રોફાઇલ હવે ઉપલબ્ધ નથી"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"પાસવર્ડના ઘણા વધુ પ્રયત્નો"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"વ્યવસ્થાપકે ડિવાઇસ વ્યક્તિગત ઉપયોગ માટે આપી દીધું છે"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"ઉપકરણ સંચાલિત છે"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"તમારી સંસ્થા આ ઉપકરણનું સંચાલન કરે છે અને નેટવર્ક ટ્રાફિફનું નિયમન કરી શકે છે. વિગતો માટે ટૅપ કરો."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"તમારું ઉપકરણ કાઢી નાખવામાં આવશે"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"ઍપને સ્ટીકી બ્રોડકાસ્ટ મોકલવાની મંજૂરી આપે છે, જે બ્રોડકાસ્ટ સમાપ્ત થયા પછી પણ રહે છે. અતિશય ઉપયોગ તમારા Android TV ડિવાઇસને વધુ પડતી મેમરીનો ઉપયોગ કરવાને કારણે તેને ધીમું અથવા અસ્થિર બનાવી શકે છે."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"એપ્લિકેશનને સ્ટિકી બ્રોડકાસ્ટ્સ મોકલવાની મંજૂરી આપે છે, જે બ્રોડકાસ્ટ્સ સમાપ્ત થયા પછી પણ રહે છે. અતિરિક્ત ઉપયોગ ફોનને વધુ પડતી મેમરીનો ઉપયોગ કરવાને કારણે તેને ધીમું અથવા અસ્થિર બનાવી શકે છે."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"તમારા સંપર્કો વાંચો"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"એપ્લિકેશનને તમે કઈ આવૃત્તિ પર કૉલ કર્યો, ઇમેઇલ કરી અથવા વિશિષ્ટ વ્યક્તિઓ સાથે અન્ય રીતે સંચાર કર્યો તે સહિત તમારા ટેબ્લેટ પર સંગ્રહિત તમારા સંપર્કો વિશેનો ડેટા વાંચવાની મંજૂરી આપે છે. આ પરવાનગી ઍપ્લિકેશનોને તમારો સંપર્ક ડેટા સાચવવાની મંજૂરી આપે છે અને દુર્ભાવનાપૂર્ણ ઍપ્લિકેશનો તમારી જાણ વગર સંપર્ક ડેટાને શેર કરી શકે છે."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"ઍપને તમે કઈ આવૃત્તિ પર કૉલ કર્યો, ઇમેઇલ કર્યો અથવા વિશિષ્ટ વ્યક્તિઓ સાથે અન્ય રીતે સંચાર કર્યો તે સહિત તમારા Android TV ડિવાઇસ પર સંગ્રહિત તમારા સંપર્કો વિશેનો ડેટા વાંચવાની મંજૂરી આપે છે. આ પરવાનગી ઍપને તમારો સંપર્ક ડેટા સાચવવાની મંજૂરી આપે છે અને દુર્ભાવનાપૂર્ણ ઍપ તમારી જાણ વગર સંપર્ક ડેટા શેર કરી શકે છે."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"એપ્લિકેશનને તમે કઈ આવૃત્તિ પર કૉલ કર્યો, ઇમેઇલ કરી અથવા વિશિષ્ટ વ્યક્તિઓ સાથે અન્ય રીતે સંચાર કર્યો તે સહિત તમારા ફોન પર સંગ્રહિત તમારા સંપર્કો વિશેનો ડેટા વાંચવાની મંજૂરી આપે છે. આ પરવાનગી ઍપ્લિકેશનોને તમારો સંપર્ક ડેટા સાચવવાની મંજૂરી આપે છે અને દુર્ભાવનાપૂર્ણ ઍપ્લિકેશનો તમારી જાણ વગર સંપર્ક ડેટાને શેર કરી શકે છે."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"ઍપને તમારા ટૅબ્લેટમાં સ્ટોર કરેલા તમારા સંપર્કો વિશેનો ડેટા વાંચવાની મંજૂરી આપે છે. ઍપને તમારા ટૅબ્લેટ પર સંપર્કો બનાવનારાં એકાઉન્ટનો પણ ઍક્સેસ રહેશે. તેમાં તમે ઇન્સ્ટૉલ કરેલી ઍપ દ્વારા બનાવાયેલાં એકાઉન્ટનો પણ સમાવેશ થઈ શકે છે. આ પરવાનગી ઍપને તમારા સંપર્કનો ડેટા સાચવવાની મંજૂરી આપે છે અને દુર્ભાવનાપૂર્ણ ઍપ તમારી જાણ બહાર સંપર્કનો ડેટા શેર કરે તેમ બની શકે છે."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"ઍપને તમારા Android TV ડિવાઇસમાં સ્ટોર કરેલા તમારા સંપર્કો વિશેનો ડેટા વાંચવાની મંજૂરી આપે છે. ઍપને તમારા Android TV ડિવાઇસ પર સંપર્કો બનાવનારાં એકાઉન્ટનો પણ ઍક્સેસ રહેશે. તેમાં તમે ઇન્સ્ટૉલ કરેલી ઍપ દ્વારા બનાવાયેલાં એકાઉન્ટનો પણ સમાવેશ થઈ શકે છે. આ પરવાનગી ઍપને તમારા સંપર્કનો ડેટા સાચવવાની મંજૂરી આપે છે અને દુર્ભાવનાપૂર્ણ ઍપ તમારી જાણ બહાર સંપર્કનો ડેટા શેર કરે તેમ બની શકે છે."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ઍપને તમારા ફોનમાં સ્ટોર કરેલા તમારા સંપર્કો વિશેનો ડેટા વાંચવાની મંજૂરી આપે છે. ઍપને તમારા ફોન પર સંપર્કો બનાવનારાં એકાઉન્ટનો પણ ઍક્સેસ રહેશે. તેમાં તમે ઇન્સ્ટૉલ કરેલી ઍપ દ્વારા બનાવાયેલાં એકાઉન્ટનો પણ સમાવેશ થઈ શકે છે. આ પરવાનગી ઍપને તમારા સંપર્કનો ડેટા સાચવવાની મંજૂરી આપે છે અને દુર્ભાવનાપૂર્ણ ઍપ તમારી જાણ બહાર સંપર્કનો ડેટા શેર કરે તેમ બની શકે છે."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"તમારા સંપર્કો સંશોધિત કરો"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"એપ્લિકેશનને તમે કઈ આવૃત્તિ પર કૉલ કર્યો, ઇમેઇલ કરી અથવા વિશિષ્ટ સંપર્કો સાથે અન્ય રીતે સંચાર કર્યો તે સહિત તમારા ટેબ્લેટ પર સંગ્રહિત તમારા સંપર્કો વિશેનો ડેટા સંશોધિત કરવાની મંજૂરી આપે છે. આ પરવાનગી એપ્લિકેશન્સને સંપર્ક ડેટા કાઢી નાખવાની મંજૂરી આપે છે."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"ઍપને તમે કઈ આવૃત્તિ પર કૉલ કર્યો, ઇમેઇલ કર્યો અથવા વિશિષ્ટ સંપર્કો સાથે અન્ય રીતે સંચાર કર્યો તે સહિત તમારા Android TV ડિવાઇસ પર સંગ્રહિત તમારા સંપર્કો વિશેનો ડેટા સંશોધિત કરવાની મંજૂરી આપે છે. આ પરવાનગી ઍપને સંપર્ક ડેટા ડિલીટ કરવાની મંજૂરી આપે છે."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"એપ્લિકેશનને તમે કઈ આવૃત્તિ પર કૉલ કર્યો, ઇમેઇલ કરી અથવા વિશિષ્ટ સંપર્કો સાથે અન્ય રીતે સંચાર કર્યો તે સહિત તમારા ફોન પર સંગ્રહિત તમારા સંપર્કો વિશેનો ડેટા સંશોધિત કરવાની મંજૂરી આપે છે. આ પરવાનગી એપ્લિકેશન્સને સંપર્ક ડેટા કાઢી નાખવાની મંજૂરી આપે છે."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"ઍપને તમારા ટૅબ્લેટ પર સ્ટોર કરેલા તમારા સંપર્કો વિશેનો ડેટા સંશોધિત કરવાની મંજૂરી આપે છે. આ પરવાનગી ઍપને સંપર્ક ડેટા ડિલીટ કરવાની મંજૂરી આપે છે."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"ઍપને તમારા Android TV ડિવાઇસ પર સ્ટોર કરેલા તમારા સંપર્કો વિશેનો ડેટા સંશોધિત કરવાની મંજૂરી આપે છે. આ પરવાનગી ઍપને સંપર્ક ડેટા ડિલીટ કરવાની મંજૂરી આપે છે."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"ઍપને તમારા ફોનમાં સ્ટોર કરેલા તમારા સંપર્કો વિશેનો ડેટા સંશોધિત કરવાની મંજૂરી આપે છે. આ પરવાનગી ઍપને સંપર્ક ડેટા ડિલીટ કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"કૉલ લૉગ વાંચો"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"આ ઍપ્લિકેશન, તમારો કૉલ ઇતિહાસ વાંચી શકે છે."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"કૉલ લૉગ લખો"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"વધારાના સ્થાન પ્રદાતા આદેશોને ઍક્સેસ કરો"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"એપ્લિકેશનને વધારાના સ્થાન પ્રદાતા આદેશોને ઍક્સેસ કરવાની મંજૂરી આપે છે. આ એપ્લિકેશનને GPS અથવા અન્ય સ્થાન સ્રોતોના ઓપરેશનમાં દખલ કરવાની મંજૂરી આપી શકે છે."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"ફૉરગ્રાઉન્ડમાં ફક્ત ચોક્કસ સ્થાન ઍક્સેસ કરો"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"આ ઍપ ફક્ત બૅકગ્રાઉન્ડમાં હોય ત્યારે જ તમારું ચોક્કસ સ્થાન મેળવી શકે છે. ઍપ આ સ્થાન સેવાઓનો ઉપયોગ કરી શકે તે માટે તમારા ફોન પર આ સેવાઓ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે. આ બૅટરી વપરાશ વધારી શકે છે."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"અંદાજિત જગ્યાને (નેટવર્ક આધારિત) માત્ર ફૉરગ્રાઉન્ડમાંથી ઍક્સેસ કરો"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"સેલ ટાવર અને વાઇ-ફાઇ નેટવર્ક જેવા નેટવર્ક સૉર્સનો ઉપયોગ કરીને આ અૅપ તમારી જગ્યા જાણી શકે છે, પરંતુ આ માત્ર ત્યારે શક્ય છે જ્યારે આ અૅપ ફૉરગ્રાઉન્ડમાં ચાલુ હોય. ઍપ આ જગ્યાની સેવાઓનો ઉપયોગ કરી શકે તે માટે તમારા ટૅબ્લેટ પર આ સેવાઓ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"સેલ ટાવર અને વાઇ-ફાઇ નેટવર્ક જેવા નેટવર્ક સૉર્સનો ઉપયોગ કરીને આ ઍપ તમારું સ્થાન જાણી શકે છે, પરંતુ આ માત્ર ત્યારે શક્ય છે જ્યારે આ ઍપ ફૉરગ્રાઉન્ડમાં ચાલુ હોય. ઍપ આ સ્થાન સેવાઓનો ઉપયોગ કરી શકે તે માટે તમારા Android TV ડિવાઇસ પર આ સેવાઓ ઉપલબ્ધ અને ચાલુ હોવી જરૂરી છે."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"સેલ ટાવર અને વાઇ-ફાઇ નેટવર્ક જેવા નેટવર્ક સૉર્સનો ઉપયોગ કરીને આ અૅપ તમારી જગ્યા જાણી શકે છે, પરંતુ આ માત્ર ત્યારે શક્ય છે જ્યારે આ અૅપ ફૉરગ્રાઉન્ડમાં ચાલુ હોય. ઍપ આ જગ્યાની સેવાઓનો ઉપયોગ કરી શકે તે માટે તમારા ફોન પર આ સેવાઓ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"આ ઍપ ફક્ત ફૉરગ્રાઉન્ડમાંમાં હોય ત્યારે જ તમારું ચોક્કસ સ્થાન મેળવી શકે છે. ઍપ આ સ્થાન સેવાઓનો ઉપયોગ કરી શકે તે માટે તે સેવાઓ ચાલુ કરેલી અને તમારા ડિવાઇસમાં ઉપલબ્ધ હોવી જોઈએ. આ બૅટરી વપરાશ વધારી શકે છે."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"ફૉરગ્રાઉન્ડમાં ફક્ત અંદાજિત સ્થાન ઍક્સેસ કરો"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"આ ઍપ ફોરગ્રાઉન્ડમાં હોય, ત્યારે જ તે તમારું અંદાજિત સ્થાન મેળવી શકે છે. ઍપ આ સ્થાન સેવાઓનો ઉપયોગ કરી શકે તે માટે તે સેવાઓ ચાલુ કરેલી અને તમારા ડિવાઇસમાં ઉપલબ્ધ હોવી જોઈએ."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"બૅકગ્રાઉન્ડમાં સ્થાન ઍક્સેસ કરો"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"જો અંદાજિત અથવા ચોક્કસ સ્થાનના ઍક્સેસ ઉપરાંત આને પરવાનગી આપવામાં આવી હશે, તો ઍપ બૅકગ્રાઉન્ડમાં ચાલતી હોય ત્યારે સ્થાનને ઍક્સેસ કરી શકશે."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"આ ઍપ ફૉરગ્રાઉન્ડમાં સ્થાનને ઍક્સેસ કરવા ઉપરાંત બૅકગ્રાઉન્ડમાં ચાલતી હોય ત્યારે પણ સ્થાનને ઍક્સેસ કરી શકે છે."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"તમારી ઑડિઓ સેટિંગ્સ બદલો"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"એપ્લિકેશનને વૈશ્વિક ઑડિઓ સેટિંગ્સને સંશોધિત કરવાની મંજૂરી આપે છે, જેમ કે વૉલ્યૂમ અને આઉટપુટ માટે કયા સ્પીકરનો ઉપયોગ કરવો."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ઑડિઓ રેકોર્ડ કરવાની"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"એપ્લિકેશનને ટેબ્લેટ પર બ્લૂટૂથ ની ગોઠવણી જોવાની અને જોડી કરેલ ઉપકરણો સાથે કનેક્શન્સ કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"ઍપને તમારા Android TV ડિવાઇસ પર બ્લૂટૂથની ગોઠવણી જોવાની અને જોડાણ કરેલા ડિવાઇસની સાથે કનેક્શન કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"એપ્લિકેશનને ફોન પર બ્લૂટૂથ ની ગોઠવણી જોવાની અને જોડી કરેલ ઉપકરણો સાથે કનેક્શન્સ કરવાની અને સ્વીકારવાની મંજૂરી આપે છે."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"નિઅર ફીલ્ડ કમ્યુનિકેશન નિયંત્રિત કરો"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"ઍપ્લિકેશનને નિઅર ફીલ્ડ કમ્યુનિકેશન (NFC) ટૅગ, કાર્ડ અને રીડર સાથે સંચાર કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"તમારું સ્ક્રીન લૉક અક્ષમ કરો"</string>
@@ -900,7 +901,7 @@
<string name="factorytest_no_action" msgid="339252838115675515">"FACTORY_TEST ક્રિયા પ્રદાન કરનાર કોઈ પૅકેજ મળ્યું નહોતું."</string>
<string name="factorytest_reboot" msgid="2050147445567257365">"રીબૂટ કરો"</string>
<string name="js_dialog_title" msgid="7464775045615023241">"\"<xliff:g id="TITLE">%s</xliff:g>\" પરનું પૃષ્ઠ કહે છે કે:"</string>
- <string name="js_dialog_title_default" msgid="3769524569903332476">"Javascript"</string>
+ <string name="js_dialog_title_default" msgid="3769524569903332476">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="7012587995876771246">"નેવિગેશનની પુષ્ટિ કરો"</string>
<string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"આ પૃષ્ઠ છોડો"</string>
<string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"આ પૃષ્ઠ પર રહો"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> થી કનેક્ટ કરેલું છે"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ફાઇલો જોવા માટે ટૅપ કરો"</string>
<string name="pin_target" msgid="8036028973110156895">"પિન"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"અનપિન કરો"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"ઍપ્લિકેશન માહિતી"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ડેમો પ્રારંભ કરી રહ્યાં છે…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"માંની: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> અને <xliff:g id="TYPE_2">%3$s</xliff:g> બાબતોને અપડેટ કરીએ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"સાચવો"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"ના, આભાર"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"હમણાં નહીં"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"ક્યારેય નહીં"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"અપડેટ કરો"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"ચાલુ રાખો"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"પાસવર્ડ"</string>
@@ -1972,7 +1979,7 @@
<string name="mime_type_audio" msgid="4933450584432509875">"ઑડિયો"</string>
<string name="mime_type_audio_ext" msgid="2615491023840514797">"<xliff:g id="EXTENSION">%1$s</xliff:g> ઑડિયો"</string>
<string name="mime_type_video" msgid="7071965726609428150">"વીડિયો"</string>
- <string name="mime_type_video_ext" msgid="185438149044230136">"<xliff:g id="EXTENSION">%1$s</xliff:g> વીડિઓ"</string>
+ <string name="mime_type_video_ext" msgid="185438149044230136">"<xliff:g id="EXTENSION">%1$s</xliff:g> વીડિયો"</string>
<string name="mime_type_image" msgid="2134307276151645257">"છબી"</string>
<string name="mime_type_image_ext" msgid="5743552697560999471">"<xliff:g id="EXTENSION">%1$s</xliff:g> છબી"</string>
<string name="mime_type_compressed" msgid="8737300936080662063">"આર્કાઇવ"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"સ્ક્રીનને વિભાજિત કરવાની ક્રિયા ટૉગલ કરો"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"લૉક સ્ક્રીન"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"સ્ક્રીનશૉટ"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"પૉપ-અપ વિંડોમાં <xliff:g id="APP_NAME">%1$s</xliff:g> ઍપ."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>નું કૅપ્શન બાર."</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index eecfd5b..407e9de 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"वर्क प्रोफ़ाइल व्यवस्थापक ऐप्लिकेशन या तो मौजूद नहीं है या वह खराब हो गया है. परिणामस्वरूप, आपकी वर्क प्रोफ़ाइल और उससे जुड़े डेटा को हटा दिया गया है. सहायता के लिए अपने व्यवस्थापक से संपर्क करें."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"आपकी वर्क प्रोफ़ाइल अब इस डिवाइस पर उपलब्ध नहीं है"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"कई बार गलत पासवर्ड डाला गया"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"एडमिन ने निजी इस्तेमाल के लिए डिवाइस दे दिया है"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"डिवाइस प्रबंधित है"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"आपका संगठन इस डिवाइस का प्रबंधन करता है और वह नेटवर्क ट्रैफ़िक की निगरानी भी कर सकता है. विवरण के लिए टैप करें."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"आपके डिवाइस को मिटा दिया जाएगा"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"यह ऐप्लिकेशन को स्टिकी ब्रॉडकास्ट भेजने की अनुमति देता है जो ब्रॉडकास्ट खत्म होने के बाद भी बने रहते हैं. इस सुविधा के ज़्यादा इस्तेमाल से आपके Android TV डिवाइस की मेमोरी कम हो सकती है जिससे टीवी की परफ़ॉर्मेंस पर असर पड़ सकता है और उसे इस्तेमाल करने में समस्याएं आ सकती हैं."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ऐप्स को स्टिकी प्रसारण भेजने देता है, जो प्रसारण खत्म होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, फ़ोन की बहुत ज़्यादा मेमोरी का उपयोग करके उसे धीमा या अस्थिर कर सकता है."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"अपने संपर्क पढ़ें"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"ऐप को आपके टैबलेट पर मौजूद आपके संपर्कों का डेटा पढ़ने देती है, जिसमें ये भी शामिल है कि आपने कुछ ख़ास लोगों से कितनी बार कॉल, ईमेल, या कुछ और तरीकों से बातचीत की. यह अनुमति ऐप को आपका संपर्क डेटा सेव करने देती है और धोखा देने वाले ऐप संपर्क डेटा को आपकी जानकारी के बिना शेयर कर सकते हैं."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"यह ऐप्लिकेशन को आपके Android TV डिवाइस पर सेव किए हुए संपर्कों के डेटा में बदलाव करने की अनुमति देता है. साथ ही, संपर्क में शामिल कुछ खास लोगों को आप कितना कॉल करते हैं, कितने ईमेल भेजते हैं या संपर्क करने के दूसरे तरीकों का कितना इस्तेमाल करते हैं, इससे जुड़ी जानकारी भी हासिल कर सकता है. यह अनुमति देने के बाद ऐप्लिकेशन आपके संपर्क का डेटा सेव कर सकता है. हालांकि, नुकसान पहुंचाने वाले ऐप्लिकेशन, बिना आपको बताए संपर्क से जुड़ा डेटा शेयर कर सकते हैं."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"ऐप को आपके फ़ोन पर मौजूद आपके संपर्कों का डेटा पढ़ने देती है, जिसमें ये भी शामिल है कि आपने कुछ ख़ास लोगों से कितनी बार कॉल, ईमेल, या कुछ और तरीकों से बातचीत की. यह अनुमति ऐप को आपका संपर्क डेटा सेव करने देती है और धोखा देने वाले ऐप, संपर्क डेटा को आपकी जानकारी के बिना शेयर कर सकते हैं."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"यह ऐप्लिकेशन को आपके टैबलेट पर मौजूद संपर्कों का डेटा देखने की अनुमति देता है. ऐप्लिकेशन को आपके टैबलेट पर मौजूद उन खातों को ऐक्सेस करने की अनुमति भी होगी जिनसे संपर्क बनाए गए हैं. इसमें वे खाते भी शामिल हो सकते हैं जिन्हें आपके इंस्टॉल किए हुए ऐप्लिकेशन ने बनाया है. इस अनुमति के बाद, ऐप्लिकेशन आपके संपर्कों का डेटा सेव कर सकते हैं. हालांकि, नुकसान पहुंचाने वाले ऐप्लिकेशन, आपको बताए बिना ही संपर्कों का डेटा शेयर कर सकते हैं."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"यह ऐप्लिकेशन को आपके Android TV डिवाइस पर सेव किए संपर्कों का डेटा देखने की अनुमति देता है. ऐप्लिकेशन को आपके Android TV डिवाइस पर मौजूद उन खातों को ऐक्सेस करने की अनुमति भी होगी जिनसे संपर्क बनाए गए हैं. इसमें वे खाते भी शामिल हो सकते हैं जिन्हें आपके इंस्टॉल किए हुए ऐप्लिकेशन ने बनाया है. इस अनुमति के बाद, ऐप्लिकेशन आपके संपर्कों का डेटा सेव कर सकते हैं. हालांकि, नुकसान पहुंचाने वाले ऐप्लिकेशन, आपको बताए बिना ही संपर्कों का डेटा शेयर कर सकते हैं."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"यह ऐप्लिकेशन को आपके फ़ोन पर मौजूद संपर्कों का डेटा देखने की अनुमति देता है. ऐप्लिकेशन को आपके फ़ोन पर मौजूद उन खातों को ऐक्सेस करने की अनुमति भी होगी जिनसे संपर्क बनाए गए हैं. इसमें वे खाते भी शामिल हो सकते हैं जिन्हें आपके इंस्टॉल किए हुए ऐप्लिकेशन ने बनाया है. इस अनुमति के बाद, ऐप्लिकेशन आपके संपर्कों का डेटा सेव कर सकते हैं. हालांकि, नुकसान पहुंचाने वाले ऐप्लिकेशन, आपको बताए बिना ही संपर्कों का डेटा शेयर कर सकते हैं."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"अपने संपर्क बदलें"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"ऐप्स को आपके टैबलेट में संग्रहित संपर्कों के डेटा को, साथ ही विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्य तरीके से डॉयलॉग करने की आवृत्ति को संशोधित करने देता है. यह अनुमति ऐप्स को आपके संपर्क डेटा को हटाने देती है."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"यह ऐप्लिकेशन को आपके Android TV डिवाइस पर सेव किए संपर्कों के डेटा में बदलाव करने की अनुमति देता है. साथ ही, संपर्क में शामिल कुछ खास लोगों को आप कितना कॉल करते हैं, कितने ईमेल भेजते हैं या संपर्क करने के दूसरे तरीकों का कितना इस्तेमाल करते हैं, इससे जुड़ी जानकारी में भी बदलाव कर सकता है. इस अनुमति से, ऐप्लिकेशन आपके संपर्क के डेटा को मिटा सकता है."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"ऐप्स को आपके फ़ोन में संग्रहित संपर्कों के डेटा को, साथ ही विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्य तरीके से डॉयलॉग करने की आवृत्ति को संशोधित करने देता है. यह अनुमति ऐप्स को आपके संपर्क डेटा को हटाने देती है."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"यह ऐप्लिकेशन को आपके टैबलेट पर सेव किए संपर्कों के डेटा में बदलाव करने की अनुमति देता है. इस अनुमति के बाद, ऐप्लिकेशन आपके संपर्कों का डेटा मिटा सकते हैं."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"यह ऐप्लिकेशन को आपके Android TV डिवाइस पर सेव किए संपर्कों के डेटा में बदलाव करने की अनुमति देता है. इस अनुमति के बाद, ऐप्लिकेशन आपके संपर्कों का डेटा मिटा सकते हैं."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"यह ऐप्लिकेशन को आपके फ़ोन पर सेव किए संपर्कों के डेटा में बदलाव करने की अनुमति देता है. इस अनुमति के बाद, ऐप्लिकेशन आपके संपर्कों का डेटा मिटा सकते हैं."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"कॉल लॉग पढ़ें"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"यह ऐप्लिकेशन आपका कॉल इतिहास पढ़ सकता है."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"कॉल लॉग लिखें"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"कुछ और जगह बताने वाले आदेशों तक पहुंच"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"ऐप को कुछ और जगह की जानकारी देने वाले आदेशों की पहुंच पाने देता है. इससे ऐप जीपीएस या जगह की जानकारी देने वाले दूसरे स्रोतों के काम में रोक-टोक कर सकता है."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"ऐप्लिकेशन \'जगह की सटीक जानकारी\' सिर्फ़ सामने खुली होने पर ऐक्सेस करे"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"यह ऐप्लिकेशन सिर्फ़ तब आपकी \'जगह की सटीक जानकारी\' का इस्तेमाल कर सकता है जब यह स्क्रीन पर दिखाई दे रहा हो. यह ज़रूरी है कि \'जगह की जानकारी\' वाली ये सेवाएं आपके फ़ोन में मौजूद हों और चालू की गई हों ताकि ऐप्लिकेशन उनका इस्तेमाल कर पाए. ऐसा करने से ज़्यादा बैटरी खर्च हो सकती है."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"स्क्रीन पर दिखाई देते समय \'जगह की अनुमानित जानकारी\' (नेटवर्क-आधारित) ऐक्सेस करें"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"यह ऐप्लिकेशन सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क स्रोतों के आधार पर आपकी जगह का पता लगा सकता है, लेकिन सिर्फ़ तब, जब ऐप्लिकेशन स्क्रीन पर दिखाई दे रहा हो. यह ज़रूरी है कि \'जगह की जानकारी\' वाली ये सेवाएं आपके टैबलेट में मौजूद हों और चालू की गई हों ताकि ऐप्लिकेशन उनका इस्तेमाल कर पाए."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"यह ऐप्लिकेशन मोबाइल टावर और वाई-फ़ाई नेटवर्क जैसे स्रोतों के आधार पर आपकी जगह की जानकारी ले सकता है. हालांकि, ऐसा तब होगा, जब ऐप्लिकेशन स्क्रीन पर दिखाई दे रहा हो. जगह की जानकारी वाली ये सुविधाएं आपके Android TV डिवाइस पर उपलब्ध होनी चाहिए और चालू स्थिति में होनी चाहिए, ताकि यह ऐप्लिकेशन उनका इस्तेमाल कर सके."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"यह ऐप्लिकेशन सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क स्रोतों के आधार पर आपकी जगह का पता लगा सकता है, लेकिन सिर्फ़ तब, जब ऐप्लिकेशन स्क्रीन पर दिखाई दे रहा हो. यह ज़रूरी है कि \'जगह की जानकारी\' वाली ये सेवाएं आपके फ़ोन में मौजूद हों और चालू की गई हों ताकि ऐप्लिकेशन उनका इस्तेमाल कर पाए."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"यह ऐप्लिकेशन सिर्फ़ तब आपकी जगह की सटीक जानकारी का इस्तेमाल कर सकता है, जब यह स्क्रीन पर खुला हो. यह ज़रूरी है कि जगह की जानकारी वाली ये सुविधाएं आपके फ़ोन में मौजूद हों और चालू की गई हों, ताकि ऐप्लिकेशन उनका इस्तेमाल कर पाए. ऐसा करने से ज़्यादा बैटरी खर्च हो सकती है."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"अनुमानित जगह की जानकारी सिर्फ़ तब ऐक्सेस करें, जब ऐप्लिकेशन स्क्रीन पर खुला हो"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"यह ऐप्लिकेशन आपकी अनुमानित जगह की जानकारी का इस्तेमाल सिर्फ़ तब कर सकता है, जब यह स्क्रीन पर दिखाई दे रहा हो. यह ज़रूरी है कि आपके डिवाइस में, जगह की जानकारी वाली सुविधाएं हों और उन्हें चालू किया गया हो, ताकि ऐप्लिकेशन उनका इस्तेमाल कर पाए."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"बैकग्राउंड में जगह की जानकारी ऐक्सेस करना"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"अनुमानित या बिल्कुल सही जगह की जानकारी का ऐक्सेस करने की अनुमति अलग से दिए जाने पर, बैकग्राउंड में चलने के दौरान ऐप्लिकेशन आपकी जगह की जानकारी ऐक्सेस कर सकता है."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"यह ऐप्लिकेशन स्क्रीन पर खुले होने के साथ-साथ बैकग्राउंड में चलते हुए भी जगह की जानकारी ऐक्सेस कर सकता है."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"अपनी ऑडियो सेटिंग बदलें"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"ऐप्स को वैश्विक ऑडियो सेटिंग, जैसे वॉल्यूम और कौन-सा स्पीकर आउटपुट के लिए उपयोग किया गया, संशोधित करने देता है."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ऑडियो रिकॉर्ड करने"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ऐप्स को टैबलेट पर ब्लूटूथ का कॉन्फ़िगरेशन देखने, और युग्मित डिवाइस के साथ कनेक्शन बनाने और स्वीकार करने देता है."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"यह ऐप्लिकेशन को आपके Android TV डिवाइस पर ब्लूटूथ कॉन्फ़िगरेशन देखने की अनुमति देता है. साथ ही, यह ब्लूटूथ कनेक्शन से दूसरे डिवाइस को जोड़ने की सुविधा भी देता है."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ऐप्स को फ़ोन पर ब्लूटूथ का कॉन्फ़िगरेशन देखने, और युग्मित डिवाइस के साथ कनेक्शन बनाने और स्वीकार करने देता है."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"नियर फ़ील्ड कम्यूनिकेशन नियंत्रित करें"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"ऐप्स को नियर फ़ील्ड कम्यूनिकेशन (NFC) टैग, कार्ड, और रीडर के साथ संचार करने देता है."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"अपना स्क्रीन लॉक अक्षम करें"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> से कनेक्ट किया गया"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"फ़ाइलें देखने के लिए टैप करें"</string>
<string name="pin_target" msgid="8036028973110156895">"पिन करें"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"अनपिन करें"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"ऐप्लिकेशन की जानकारी"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"डेमो प्रारंभ हो रहा है…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"क्या आप "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" में इन आइटम को अपडेट करना चाहते हैं: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, और <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"सेव करें"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"नहीं, धन्यवाद"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"अभी नहीं"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"कभी नहीं"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"अपडेट करें"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"जारी रखें"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"पासवर्ड"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"स्प्लिट स्क्रीन पर टॉगल करें"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"स्क्रीन लॉक करें"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"स्क्रीनशॉट लें"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"पॉप-अप विंडो में <xliff:g id="APP_NAME">%1$s</xliff:g> ऐप्लिकेशन."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> का कैप्शन बार."</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index e8f02b2..0d25a77 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -190,8 +190,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Administratorska aplikacija radnog profila nedostaje ili je oštećena. Zbog toga su radni profil i povezani podaci izbrisani. Za pomoć se obratite svom administratoru."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Vaš radni profil više nije dostupan na ovom uređaju"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Previše pokušaja unosa zaporke"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator je ustupio uređaj za osobnu upotrebu"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Uređaj je upravljan"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja ovim uređajem i može nadzirati mrežni promet. Dodirnite za pojedinosti."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će se izbrisati"</string>
@@ -384,13 +383,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Aplikaciji omogućuje slanje \"ljepljivih\" emitiranja koja se zadržavaju nakon završetka emitiranja. Prekomjerna upotreba može usporiti Android TV uređaj ili ga učiniti nestabilnim uzrokujući pretjeranu upotrebu memorije."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Aplikaciji omogućuje slanje \"ljepljivih\" emitiranja koja se zadržavaju nakon završetka emitiranja. Prekomjerna upotreba može usporiti telefon ili ga učiniti nestabilnim uzrokujući pretjeranu upotrebu memorije."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"čitanje kontakata"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Aplikaciji omogućuje čitanje podataka o vašim kontaktima pohranjenim na tabletnom računalu, uključujući učestalost poziva, e-poruka ili drugih načina komunikacije s određenim pojedincima. Ta dozvola aplikaciji omogućuje spremanje podataka kontakata, a zlonamjerne aplikacije mogu dijeliti podatke kontakata bez vašeg znanja."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Aplikaciji omogućuje čitanje podataka o vašim kontaktima pohranjenima na vašem Android TV uređaju, uključujući učestalost poziva, e-poruka ili drugih načina komunikacije s određenim osobama. To dopuštenje omogućuje aplikaciji spremanje vaših podataka o kontaktima, a zlonamjerne aplikacije mogu dijeliti podatke o kontaktima bez vašeg znanja."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Aplikaciji omogućuje čitanje podataka o vašim kontaktima pohranjenim na telefonu, uključujući učestalost poziva, e-poruka ili drugih načina komunikacije s određenim pojedincima. Ta dozvola aplikaciji omogućuje spremanje podataka kontakata, a zlonamjerne aplikacije mogu dijeliti podatke kontakata bez vašeg znanja."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Aplikaciji omogućuje čitanje podataka o vašim kontaktima pohranjenim na vašem tabletu. Aplikacije će također imati pristup računima na vašem tabletu na kojima su izrađeni kontakti. To može uključivati račune izrađene u aplikacijama koje ste instalirali. To dopuštenje omogućuje aplikacijama spremanje podataka o kontaktima, a zlonamjerne aplikacije mogu dijeliti podatke o kontaktima bez vašeg znanja."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Aplikaciji omogućuje čitanje podataka o vašim kontaktima pohranjenim na vašem Android TV uređaju. Aplikacije će također imati pristup računima na vašem Android TV uređaju na kojima su izrađeni kontakti. To može uključivati račune izrađene u aplikacijama koje ste instalirali. To dopuštenje omogućuje aplikacijama spremanje podataka o kontaktima, a zlonamjerne aplikacije mogu dijeliti podatke o kontaktima bez vašeg znanja."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Aplikaciji omogućuje čitanje podataka o vašim kontaktima pohranjenim na vašem telefonu. Aplikacije će također imati pristup računima na vašem telefonu na kojima su izrađeni kontakti. To može uključivati račune izrađene u aplikacijama koje ste instalirali. To dopuštenje omogućuje aplikacijama spremanje podataka o kontaktima, a zlonamjerne aplikacije mogu dijeliti podatke o kontaktima bez vašeg znanja."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"izmjena kontakata"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Aplikaciji omogućuje izmjenu podataka o vašim kontaktima pohranjenim na tabletnom računalu, uključujući učestalost poziva, e-poruka ili drugih načina komunikacije s određenim kontaktima. Ta dozvola aplikacijama omogućuje brisanje kontaktnih podataka."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Aplikaciji omogućuje izmjenu podataka o vašim kontaktima pohranjenim na Android TV uređaju, uključujući učestalost poziva, e-poruka ili drugih načina komunikacije s određenim kontaktima. To dopuštenje aplikacijama omogućuje brisanje podataka o kontaktima."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Aplikaciji omogućuje izmjenu podataka o vašim kontaktima pohranjenim na telefonu, uključujući učestalost poziva, e-poruka ili drugih načina komunikacije s određenim kontaktima. Ta dozvola aplikacijama omogućuje brisanje kontaktnih podataka."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Aplikaciji omogućuje izmjenu podataka o vašim kontaktima pohranjenim na vašem tabletu. To dopuštenje aplikacijama omogućuje da brišu podatke o kontaktima."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Aplikaciji omogućuje izmjenu podataka o vašim kontaktima pohranjenim na vašem Android TV uređaju. To dopuštenje aplikacijama omogućuje da brišu podatke o kontaktima."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Aplikaciji omogućuje izmjenu podataka o vašim kontaktima pohranjenim na vašem telefonu. To dopuštenje aplikacijama omogućuje da brišu podatke o kontaktima."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"čitanje dnevnika poziva"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Aplikacija može čitati vašu povijest poziva."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"pisanje u dnevnik poziva"</string>
@@ -410,13 +409,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"pristup dodatnim naredbama davatelja lokacije"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Omogućuje aplikaciji pristup dodatnim naredbama davatelja usluga lokacije. To može omogućiti aplikaciji ometanje rada GPS-a ili drugih izvora lokacije."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"pristupiti preciznoj lokaciji samo u prednjem planu"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Aplikacija može dobiti vašu točnu lokaciju samo kada je u prednjem planu. Te usluge lokacije moraju biti uključene i dostupne na telefonu da bi ih aplikacija mogla upotrebljavati. To može pojačati potrošnju baterije."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"pristupiti približnoj lokaciji (na temelju mreže) samo u prednjem planu"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Ova aplikacija može dobiti vašu lokaciju na temelju mrežnih izvora kao što su bazne stanice i Wi-Fi mreže, no samo kad je u prednjem planu. Te usluge lokacije moraju biti uključene i dostupne na vašem tabletu da bi ih aplikacija mogla upotrebljavati."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Ova aplikacija može dobiti vašu lokaciju na temelju mrežnih izvora kao što su bazne stanice i Wi-Fi mreže, no samo kad je u prednjem planu. Te usluge lokacije moraju biti uključene i dostupne na vašem Android TV uređaju da bi ih aplikacija mogla upotrebljavati."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Ova aplikacija može dobiti vašu lokaciju na temelju mrežnih izvora kao što su bazne stanice i Wi-Fi mreže, no samo kad je u prednjem planu. Te usluge lokacije moraju biti uključene i dostupne na vašem telefonu da bi ih aplikacija mogla upotrebljavati."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Aplikacija može dobiti vašu točnu lokaciju samo kad je u prednjem planu. Usluge lokacije moraju biti uključene i dostupne na uređaju da bi ih aplikacija mogla upotrebljavati. To može pojačati potrošnju baterije."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"pristupiti približnoj lokaciji samo u prednjem planu"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Aplikacija može dobiti vašu približnu lokaciju samo kad je u prednjem planu. Usluge lokacije moraju biti uključene i dostupne na uređaju da bi ih aplikacija mogla upotrebljavati."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"pristup lokaciji u pozadini"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Ako se ovo odobrava dodatno za pristup približnoj ili preciznoj lokaciji, aplikacija može pristupiti lokaciji tijekom rada u pozadini."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Ta aplikacija može pristupiti lokaciji dok se izvodi u pozadini, uz pristup lokaciji u prednjem planu."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"promjena postavki zvuka"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Aplikaciji omogućuje izmjenu globalnih postavki zvuka, primjerice glasnoće i zvučnika koji se upotrebljava za izlaz."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"snimanje zvuka"</string>
@@ -497,6 +494,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Aplikaciji omogućuje pregled konfiguracije Bluetootha na tabletnom računalu te uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Aplikaciji omogućuje pregled konfiguracije Bluetootha na Android TV uređaju te uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Aplikaciji omogućuje pregled konfiguracije Bluetootha na telefonu te uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"upravljanje beskontaktnom komunikacijom (NFC)"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Aplikaciji omogućuje komunikaciju s oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"onemogućavanje zaključavanja zaslona"</string>
@@ -1894,7 +1895,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> – veza je uspostavljena"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Dodirnite da biste pregledali datoteke"</string>
<string name="pin_target" msgid="8036028973110156895">"Prikvači"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Otkvači"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Informacije o aplikaciji"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Pokretanje demo-načina..."</string>
@@ -1938,6 +1943,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Želite li ažurirati ove stavke u oznaci "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Spremi"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Ne, hvala"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne sad"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nikad"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Ažuriraj"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Nastavi"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"zaporku"</string>
@@ -2034,5 +2041,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Uključite ili isključite podijeljeni zaslon"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključajte zaslon"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snimka zaslona"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u skočnom prozoru."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Traka naslova aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 1d1b994..df228ed 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"A munkaprofil rendszergazdai alkalmazása hiányzik vagy sérült. A rendszer ezért törölte a munkaprofilt, és az ahhoz kapcsolódó adatokat. Ha segítségre van szüksége, vegye fel a kapcsolatot rendszergazdájával."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Munkaprofilja már nem hozzáférhető ezen az eszközön."</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Túl sok jelszómegadási kísérlet"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Az adminisztrátor átadta az eszközt személyes használatra"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Felügyelt eszköz"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ezt az eszközt szervezete kezeli, és lehetséges, hogy a hálózati forgalmat is figyelik. További részletekért koppintson."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"A rendszer törölni fogja eszközét"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Lehetővé teszi az alkalmazás számára ragadós üzenetek küldését, amelyek az üzenetszórás után is megmaradnak. A túlzott használat nagy mennyiségű memóriát igényel, ezért lelassíthatja vagy instabillá teheti az Android TV eszközt."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Lehetővé teszi az alkalmazás számára ragadós üzenetek küldését, amelyek a sugárzás után is megmaradnak. A túlzott használat lelassíthatja vagy instabillá teheti a telefont a nagymértékű memóriahasználattal."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"saját névjegyek olvasása"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Lehetővé teszi az alkalmazás számára a táblagépen tárolt névjegyekre vonatkozó összes adat -- például az egyes személyekkel telefonon, e-mailben vagy más módon folytatott kommunikáció gyakoriságára vonatkozó adatok -- beolvasását. Az engedéllyel rendelkező alkalmazások menthetik a névjegyadatokat, és a rosszindulatú alkalmazások az Ön tudta nélkül oszthatják meg a névjegyadatokat."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Lehetővé teszi az alkalmazás számára, hogy beolvassa az Android TV eszközön tárolt névjegyek adatait, beleértve az egyes személyekkel kapcsolatos hívások, e-mailek és egyéb kommunikáció gyakoriságára vonatkozó adatokat. Ez az engedély lehetővé teszi az alkalmazások számára a névjegyadatok mentését, így a rosszindulatú alkalmazások az Ön tudta nélkül megoszthatják őket."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Lehetővé teszi az alkalmazás számára a telefonon tárolt névjegyekre vonatkozó összes adat -- például az egyes személyekkel telefonon, e-mailben vagy más módon folytatott kommunikáció gyakoriságára vonatkozó adatok -- beolvasását. Az engedéllyel rendelkező alkalmazások menthetik a névjegyadatokat, és a rosszindulatú alkalmazások az Ön tudta nélkül oszthatják meg a névjegyadatokat."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Lehetővé teszi az alkalmazás számára a táblagépen tárolt névjegyekre vonatkozó adatok olvasását. Az alkalmazások ezenkívül hozzáférnek azokhoz a fiókokhoz is a táblagépen, amelyek létrehoztak névjegyeket. Ebbe beletartozhatnak a telepített alkalmazások által létrehozott fiókok is. Ez az engedély lehetővé teszi az alkalmazások számára a névjegyadatok mentését, így a rosszindulatú alkalmazások az Ön tudta nélkül megoszthatják őket."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Lehetővé teszi az alkalmazás számára az Android TV-n tárolt névjegyekre vonatkozó adatok olvasását. Az alkalmazások ezenkívül hozzáférnek azokhoz a fiókokhoz is az Android TV-eszközön, amelyek létrehoztak névjegyeket. Ebbe beletartozhatnak a telepített alkalmazások által létrehozott fiókok is. Ez az engedély lehetővé teszi az alkalmazások számára a névjegyadatok mentését, így a rosszindulatú alkalmazások az Ön tudta nélkül megoszthatják őket."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Lehetővé teszi az alkalmazás számára a telefonon tárolt névjegyekre vonatkozó adatok olvasását. Az alkalmazások ezenkívül hozzáférnek azokhoz a fiókokhoz is a telefonon, amelyek létrehoztak névjegyeket. Ebbe beletartozhatnak a telepített alkalmazások által létrehozott fiókok is. Ez az engedély lehetővé teszi az alkalmazások számára a névjegyadatok mentését, így a rosszindulatú alkalmazások az Ön tudta nélkül megoszthatják őket."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"kapcsolatok módosítása"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Lehetővé teszi az alkalmazás számára a táblagépen tárolt névjegyekre vonatkozó adatok -- például az egyes személyekkel telefonon, e-mailben vagy más módon folytatott kommunikáció gyakoriságára vonatkozó adatok -- módosítását. Az engedéllyel rendelkező alkalmazás törölheti a névjegyadatokat."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Lehetővé teszi az alkalmazás számára az Android TV eszközön tárolt névjegyekre vonatkozó adatok módosítását – ilyenek például az egyes személyekkel telefonon, e-mailben vagy más módon folytatott kommunikáció gyakoriságára vonatkozó adatok. Ezzel az engedéllyel az alkalmazások törölhetik a névjegyadatokat."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Lehetővé teszi az alkalmazás számára a telefonon tárolt névjegyekre vonatkozó adatok -- például az egyes személyekkel telefonon, e-mailben vagy más módon folytatott kommunikáció gyakoriságára vonatkozó adatok -- módosítását. Az engedéllyel rendelkező alkalmazás törölheti a névjegyadatokat."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Lehetővé teszi az alkalmazás számára a táblagépen tárolt névjegyekre vonatkozó adatok módosítását. Ezzel az engedéllyel az alkalmazások törölhetik a névjegyadatokat."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Lehetővé teszi az alkalmazás számára az Android TV-n tárolt névjegyekre vonatkozó adatok módosítását. Ezzel az engedéllyel az alkalmazások törölhetik a névjegyadatokat."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Lehetővé teszi az alkalmazás számára a telefonon tárolt névjegyekre vonatkozó adatok módosítását. Ezzel az engedéllyel az alkalmazások törölhetik a névjegyadatokat."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"Híváslista beolvasása"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Az alkalmazás olvashatja az Ön híváslistáját."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"Híváslista készítése"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"további helyszolgáltatói parancsok elérése"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Lehetővé teszi az alkalmazás számára további helyszolgáltatói parancsok elérését. Ezáltal az alkalmazás beavatkozhat a GPS vagy más helyforrások működésébe."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"pontos helyadatokhoz való hozzáférés csak előtérben"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Ez az alkalmazás csak akkor férhet hozzá az eszköz pontos helyadataihoz, amikor az előtérben fut. A helyszolgáltatásoknak bekapcsolt és hozzáférhető állapotban kell lenniük a telefonon ahhoz, hogy az alkalmazás használhassa őket. Ez növelheti az akkumulátorhasználatot."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"hozzávetőleges (hálózaton alapuló) helyadatokhoz való hozzáférés csak előtérben"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Ez az alkalmazás hozzáférhet a hálózati forrásokon (például az adótornyokon és a Wi-Fi-hálózatokon) alapuló helyadataihoz, de csak akkor, amikor az előtérben fut. A helyszolgáltatásoknak bekapcsolt és hozzáférhető állapotban kell lenniük a táblagépen ahhoz, hogy az alkalmazás használhassa őket."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Ez az alkalmazás hozzáférhet a hálózati forrásokon (például az adótornyokon és a Wi-Fi-hálózatokon) alapuló helyadataihoz, de csak akkor, amikor az előtérben fut. A helyszolgáltatásoknak bekapcsolt és hozzáférhető állapotban kell lenniük az Android TV eszközön ahhoz, hogy az alkalmazás használhassa őket."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Ez az alkalmazás hozzáférhet a hálózati forrásokon (például az adótornyokon és a Wi-Fi-hálózatokon) alapuló helyadataihoz, de csak akkor, amikor az előtérben fut. A helyszolgáltatásoknak bekapcsolt és hozzáférhető állapotban kell lenniük a telefonon ahhoz, hogy az alkalmazás használhassa őket."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Ez az alkalmazás csak akkor férhet hozzá az eszköz pontos helyadataihoz, amikor az előtérben fut. Az alkalmazás csak akkor használhatja a helyszolgáltatásokat, ha be vannak kapcsolva, és hozzáférhetők az eszköz számára. Ez növelheti az akkumulátorhasználatot."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"megközelítőleges helyadatokhoz való hozzáférés csak előtérben"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Ez az alkalmazás csak akkor férhet hozzá az eszköz megközelítőleges helyadataihoz, amikor az előtérben fut. Az alkalmazás csak akkor használhatja a helyszolgáltatásokat, ha be vannak kapcsolva, és hozzáférhetők az eszköz számára."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"Hozzáférés a helyadatokhoz a háttérben"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Ha engedélyezi ezt a hozzávetőleges vagy pontos helyadatokhoz való hozzáférés mellett, akkor az alkalmazás hozzáférhet a helyadatokhoz, miközben a háttérben fut."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Ez az alkalmazás nem csak akkor férhet hozzá a helyadatokhoz, amikor az előtérben van, hanem akkor is, amikor a háttérben fut."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"hangbeállítások módosítása"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Lehetővé teszi az alkalmazás számára az általános hangbeállítások, például a hangerő és a használni kívánt kimeneti hangszóró módosítását."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"hanganyag rögzítése"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Lehetővé teszi az alkalmazás számára a táblagépen lévő Bluetooth beállításainak megtekintését, valamint kapcsolatok kezdeményezését és fogadását a párosított eszközökkel."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Lehetővé teszi az alkalmazás számára az Android TV eszköz Bluetooth-konfigurációjának megtekintését, valamint párosított eszközökkel való kapcsolatok kezdeményezését és fogadását."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Lehetővé teszi az alkalmazás számára a telefonon lévő Bluetooth beállításainak megtekintését, valamint kapcsolatok kezdeményezését és fogadását a párosított eszközökkel."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"NFC technológia vezérlése"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Lehetővé teszi az alkalmazás számára, hogy NFC (Near Field Communication - kis hatósugarú vezeték nélküli kommunikáció) technológiát használó címkékkel, kártyákkal és leolvasókkal kommunikáljon."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"képernyőzár kikapcsolása"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Csatlakoztatva a(z) <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> eszközhöz"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Koppintson ide a fájlok megtekintéséhez"</string>
<string name="pin_target" msgid="8036028973110156895">"Rögzítés"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Feloldás"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Alkalmazásinformáció"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Bemutató indítása…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Frissíti a(z) "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" szolgáltatásban a következőket: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> és <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Mentés"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nem, köszönöm"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne most"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Soha"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Frissítés"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Tovább"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"jelszó"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Osztott képernyő be- vagy kikapcsolása"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lezárási képernyő"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Képernyőkép"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás előugró ablakban."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás címsora."</string>
</resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 599ce86..5b49ac4 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Աշխատանքային պրոֆիլի ադմինիստրատորի հավելվածը բացակայում է կամ վնասված է: Արդյունքում ձեր աշխատանքային պրոֆիլը և առնչվող տվյալները ջնջվել են: Օգնության համար դիմեք ձեր ադմինիստրատորին:"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Ձեր աշխատանքային պրոֆիլն այս սարքում այլևս հասանելի չէ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Գաղտնաբառը մուտքագրելու չափից շատ փորձեր են կատարվել"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Ադմինիստրատորը տրամադրել է սարքը անձնական օգտագործման համար"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Սարքը կառավարվում է"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ձեր կազմակերպությունը կառավարում է այս սարքը և կարող է վերահսկել ցանցի թրաֆիկը: Հպեք՝ մանրամասները դիտելու համար:"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Ձեր սարքը ջնջվելու է"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Թույլ է տալիս հավելվածին կատարել անընդմեջ հեռարձակումներ, որոնցից հետո տվյալները հասանելի են մնում: Չափից դուրս օգտագործումը կարող է դանդաղեցնել Android TV սարքի աշխատանքը կամ դարձնել այն անկայուն՝ ավելացնելով հիշողության ծախսը:"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Թույլ է տալիս հավելվածին ուղարկել կպչուն հաղորդումներ, որոնք մնում են հաղորդման ավարտից հետո: Չափազանց շատ օգտագործումը կարող է հեռախոսի աշխատանքը դանդաղեցնել կամ դարձնել անկայուն` պատճառ դառնալով չափազանց մեծ հիշողության օգտագործման:"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"կարդալ ձեր կոնտակտները"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Թույլ է տալիս հավելվածին կարդալ ձեր պլանշետում պահված կոնտակտների մասին տվյալները, այդ թվում` ձեր կատարած զանգերի, գրած նամակների կամ որոշակի անհատների հետ այլ եղանակով շփման հաճախականությունը: Այս թույլտվությունը հնարավորություն է տալիս հավելվածներին պահել ձեր կոնտակտային տվյալները, իսկ վնասարար հավելվածները կարող են տարածել կոնտակտային տվյալները` առանց ձեր իմացության:"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Թույլ է տալիս հավելվածին կարդալ Android TV սարքում պահված կոնտակտների տվյալները, այդ թվում նաև՝ թե ինչ հաճախականությամբ եք զանգեր կատարել, օգտվել էլփոստից կամ այլ կերպ հաղորդակցվել որոշակի մարդկանց հետ: Այս թույլտվության միջոցով հավելվածները կարող են պահել ձեր կոնտակտների տվյալները, իսկ վնասարար հավելվածները կարող են օգտագործել դրանք առանց ձեր իմացության:"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Թույլ է տալիս հավելվածին կարդալ ձեր հեռախոսում պահված կոնտակտների մասին տվյալները, այդ թվում` ձեր կատարած զանգերի, գրած նամակների կամ որոշակի անհատների հետ այլ եղանակով շփման հաճախականությունը: Այս թույլտվությունը հնարավորություն է տալիս հավելվածներին պահել ձեր կոնտակտային տվյալները, իսկ վնասարար հավելվածները կարող են տարածել կոնտակտային տվյալները` առանց ձեր իմացության:"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Թույլ է տալիս հավելվածին կարդալ ձեր պլանշետում պահված կոնտակտների մասին տվյալները։ Հավելվածներին նաև հասանելի կլինեն հաշիվները ձեր պլանշետում, որտեղ ստեղծվել են կոնտակտներ։ Այդ հաշիվները կարող են ստեղծված լինել ձեր տեղադրած հավելվածների կողմից։ Այս թույլտվության միջոցով հավելվածները կարող են պահել ձեր կոնտակտների մասին տվյալները, իսկ վնասարար հավելվածները կարող են օգտագործել դրանք առանց ձեր իմացության։"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Թույլ է տալիս հավելվածին կարդալ Android TV սարքում պահված կոնտակտների մասին տվյալները։ Հավելվածներին նաև հասանելի կլինեն հաշիվներն Android TV սարքում, որտեղ ստեղծվել են կոնտակտներ։ Այդ հաշիվները կարող են ստեղծված լինել ձեր տեղադրած հավելվածների կողմից։ Այս թույլտվության միջոցով հավելվածները կարող են պահել ձեր կոնտակտների մասին տվյալները, իսկ վնասարար հավելվածները կարող են օգտագործել դրանք առանց ձեր իմացության։"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Թույլ է տալիս հավելվածին կարդալ ձեր հեռախոսում պահված կոնտակտների մասին տվյալները։ Հավելվածներին նաև հասանելի կլինեն հաշիվները ձեր հեռախոսում, որտեղ ստեղծվել են կոնտակտներ։ Այդ հաշիվները կարող են ստեղծված լինել ձեր տեղադրած հավելվածների կողմից։ Այս թույլտվության միջոցով հավելվածները կարող են պահել ձեր կոնտակտների մասին տվյալները, իսկ վնասարար հավելվածները կարող են օգտագործել դրանք առանց ձեր իմացության։"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"փոփոխել ձեր կոնտակտները"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Թույլ է տալիս հավելվածին փոփոխել ձեր պլանշետում պահված կոնտակտների մասին տվյալները, այդ թվում` ձեր կատարած զանգերի, գրած նամակների կամ որոշակի անհատների հետ այլ եղանակով շփման հաճախականությունը: Այս թույլտվությունը հնարավորություն է տալիս հավելվածներին ջնջել կոնտակտային տվյալները:"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Թույլ է տալիս հավելվածին փոփոխել Android TV սարքում պահված կոնտակտների տվյալները, այդ թվում նաև՝ թե ինչ հաճախականությամբ եք զանգեր կատարել, օգտվել էլփոստից կամ այլ կերպ հաղորդակցվել որոշակի մարդկանց հետ: Այս թույլտվությունը հնարավորություն է տալիս հավելվածներին ջնջել կոնտակտային տվյալները:"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Թույլ է տալիս հավելվածին փոփոխել ձեր պլանշետում պահված կոնտակտների տվյալները, այդ թվում` ձեր կատարած զանգերի, գրած նամակների կամ որոշակի անհատների հետ այլ եղանակով շփման հաճախականությունը: Այս թույլտվությունը հնարավորություն է տալիս հավելվածներին ջնջել կոնտակտային տվյալները:"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Թույլ է տալիս հավելվածին փոփոխել ձեր պլանշետում պահված կոնտակտների մասին տվյալները։ Այս թույլտվությունը հնարավորություն է տալիս հավելվածներին ջնջել կոնտակտների մասին տվյալները։"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Թույլ է տալիս հավելվածին փոփոխել ձեր Android TV սարքում պահված կոնտակտների մասին տվյալները։ Այս թույլտվությունը հնարավորություն է տալիս հավելվածներին ջնջել կոնտակտների մասին տվյալները։"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Թույլ է տալիս հավելվածին փոփոխել ձեր հեռախոսում պահված կոնտակտների մասին տվյալները։ Այս թույլտվությունը հնարավորություն է տալիս հավելվածներին ջնջել կոնտակտների մասին տվյալները։"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"կարդալ զանգերի մատյանը"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Այս հավելվածը կարող է կարդալ ձեր զանգերի պատմությունը:"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"տեսնել զանգերի գրանցամատյանը"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"օգտագործել տեղադրություն տրամադրող հավելվյալ հրամաններ"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Ծրագրին թույլ է տալիս օգտագործել տեղադրության մասին տվյալների աղբյուրների կառավարման լրացուցիչ հրահանգներ: Սա կարող է ծրագրին թույլ տալ միջամտել GPS-ի կամ տեղադրության մասին տվյալների այլ աղբյուրների գործառույթներին:"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"Տեղադրության ճշգրիտ տվյալների հասանելիություն միայն ֆոնային ռեժիմում"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ֆոնային ռեժիմում։ Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր հեռախոսում, որպեսզի հավելվածը կարողանա օգտագործել դրանք: Սա կարող է արագացնել մարտկոցի լիցքի սպառումը:"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"Մոտավոր տեղադրությունը (ցանցային) հասանելի է միայն ֆոնային ռեժիմում"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Այս հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ցանցային տարբեր աղբյուրներից, օրինակ՝ բջջային աշտարակներից և Wi-Fi ցանցերից, սակայն միայն երբ հավելվածն աշխատում է ֆոնային ռեժիմում: Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր պլանշետում, որպեսզի հավելվածը կարողանա օգտագործել դրանք:"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Այս հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ցանցային տարբեր աղբյուրներից, օրինակ՝ բջջային աշտարակներից և Wi-Fi ցանցերից, սակայն միայն երբ հավելվածն աշխատում է ֆոնային ռեժիմում: Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր Android TV սարքում, որպեսզի հավելվածը կարողանա օգտագործել դրանք:"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Այս հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ցանցային տարբեր աղբյուրներից, օրինակ՝ բջջային աշտարակներից և Wi-Fi ցանցերից, սակայն միայն երբ հավելվածն աշխատում է ֆոնային ռեժիմում: Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր հեռախոսում, որպեսզի հավելվածը կարողանա օգտագործել դրանք:"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ակտիվ ռեժիմում։ Տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր սարքում, որպեսզի հավելվածը կարողանա օգտագործել դրանք։ Սա կարող է արագացնել մարտկոցի լիցքի սպառումը։"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"տեղադրության մոտավոր տվյալների հասանելիություն միայն ակտիվ ռեժիմում"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Հավելվածը կարող է ստանալ ձեր մոտավոր տեղադրության տվյալները ակտիվ ռեժիմում։ Տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր սարքում, որպեսզի հավելվածը կարողանա օգտագործել դրանք։"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"տեղադրության մասին տվյալների հասանելիություն ֆոնային ռեժիմում"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Եթե բացի մոտավոր կամ ճշգրիտ տեղորոշման տվյալների հասանելիությունից հավելվածին տրամադրեք այս թույլտվությունը, հավելվածին տեղադրության մասին տվյալները հասանելի կլինեն ֆոնային ռեժիմում։"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Այս հավելվածը ինչպես ակտիվ, այնպես էլ ֆոնային ռեժիմում աշխատելիս կարող է տեսնել տեղադրության տվյալները։"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"փոխել ձեր աուդիո կարգավորումները"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Թույլ է տալիս հավելվածին փոփոխել ձայնանյութի գլոբալ կարգավորումները, ինչպես օրինակ` ձայնը և թե որ խոսափողն է օգտագործված արտածման համար:"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ձայնագրել աուդիո ֆայլ"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Թույլ է տալիս հավելվածին տեսնել Bluetooth-ի կարգավորումը պլանշետի վրա և կապվել ու կապեր ընդունել զուգակցված սարքերի հետ:"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Թույլ է տալիս հավելվածին տեսնել Bluetooth-ի կազմաձևումը Android TV սարքի վրա և կապվել ու թույլ տալ կապակցումները զուգակցված սարքերի հետ:"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Թույլ է տալիս հավելվածին տեսնել Bluetooth-ի կարգավորումը հեռախոսի վրա և կապվել ու կապեր ընդունել զուգակցված սարքերի հետ:"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"վերահսկել Մոտ Տարածությամբ Հաղորդակցումը"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Թույլ է տալիս հավելվածին հաղորդակցվել Մոտ տարածությամբ հաղորդակցման (NFC) պիտակների, քարտերի և ընթերցիչների հետ:"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"անջատել ձեր էկրանի կողպեքը"</string>
@@ -827,7 +828,7 @@
<string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Դադարեցնել"</string>
<string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Հետ փաթաթել"</string>
<string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"Արագ առաջ անցնել"</string>
- <string name="emergency_calls_only" msgid="3057351206678279851">"Միայն արտակարգ իրավիճակների զանգեր"</string>
+ <string name="emergency_calls_only" msgid="3057351206678279851">"Միայն շտապ կանչեր"</string>
<string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Ցանցը կողպված է"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"SIM քարտը PUK-ով կողպված է:"</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Տեսեք Օգտատիրոջ ուղեցույցը կամ դիմեք Բաժանորդների սպասարկման կենտրոն:"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Միացված է <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>-ին"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Հպեք՝ ֆայլերը տեսնելու համար"</string>
<string name="pin_target" msgid="8036028973110156895">"Ամրացնել"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Ապամրացնել"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Հավելվածի տվյալներ"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Ցուցադրական օգտատերը գործարկվում է…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Թարմացնե՞լ տվյալները (<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g>) "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ծառայությունում"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Պահել"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Ոչ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ոչ հիմա"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Երբեք"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Թարմացնել"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Շարունակել"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"գաղտնաբառ"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Միացնել/անջատել էկրանի տրոհումը"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Կողպէկրան"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Սքրինշոթ"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ելնող պատուհանում։"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի ենթագրերի գոտին։"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 1f81eb5..1ee17f4 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikasi admin profil kerja tidak ada atau rusak. Akibatnya, profil kerja dan data terkait telah dihapus. Hubungi admin untuk meminta bantuan."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profil kerja tidak tersedia lagi di perangkat ini"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Terlalu banyak percobaan memasukkan sandi"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin melepaskan perangkat untuk penggunaan pribadi"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Perangkat ini ada yang mengelola"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasi mengelola perangkat ini dan mungkin memantau traffic jaringan. Ketuk untuk melihat detailnya."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Perangkat akan dihapus"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Mengizinkan aplikasi mengirim siaran permanen, yang tetap ada setelah siaran berakhir. Penggunaan yang berlebihan dapat membuat perangkat Android TV menjadi lambat atau tidak stabil dengan memicu penggunaan memori yang terlalu banyak."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Memungkinkan aplikasi mengirim siaran permanen, yang tetap ada setelah siaran berakhir. Penggunaan yang berlebihan dapat membuat ponsel menjadi lambat atau tidak stabil dengan memicu penggunaan memori yang terlalu banyak."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"baca kontak Anda"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Memungkinkan aplikasi membaca data tentang kontak yang disimpan pada tablet Anda, termasuk frekuensi Anda dalam melakukan panggilan, mengirim email, atau berkomunikasi dengan cara lain dengan individu tertentu. Izin ini memungkinkan aplikasi menyimpan data kontak, dan aplikasi berbahaya dapat berbagi data kontak tanpa sepengetahuan Anda."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Mengizinkan aplikasi membaca data tentang kontak yang disimpan di perangkat Android TV, termasuk frekuensi yang Anda gunakan saat melakukan panggilan, mengirim email, atau berkomunikasi dalam cara lain dengan individu tertentu. Izin ini memungkinkan aplikasi menyimpan data kontak, dan aplikasi berbahaya dapat membagikan data kontak tanpa sepengetahuan Anda."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Memungkinkan aplikasi membaca data tentang kontak yang disimpan pada ponsel Anda, termasuk frekuensi Anda dalam melakukan panggilan, mengirim email, atau berkomunikasi dengan cara lain dengan individu tertentu. Izin ini memungkinkan aplikasi menyimpan data kontak, dan aplikasi berbahaya dapat berbagi data kontak tanpa sepengetahuan Anda."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Mengizinkan aplikasi membaca data tentang kontak yang disimpan di tablet Anda. Aplikasi juga akan memiliki akses ke akun di tablet Anda yang telah membuat kontak. Ini mungkin mencakup akun yang dibuat oleh aplikasi yang telah diinstal. Izin ini mengizinkan aplikasi menyimpan data kontak, dan aplikasi berbahaya dapat membagikan data kontak tanpa sepengetahuan Anda."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Mengizinkan aplikasi membaca data tentang kontak yang disimpan di perangkat Android TV Anda. Aplikasi juga akan memiliki akses ke akun di perangkat Android TV Anda yang telah membuat kontak. Ini mungkin mencakup akun yang dibuat oleh aplikasi yang telah diinstal. Izin ini mengizinkan aplikasi menyimpan data kontak, dan aplikasi berbahaya dapat membagikan data kontak tanpa sepengetahuan Anda."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Mengizinkan aplikasi membaca data tentang kontak yang disimpan di ponsel Anda. Aplikasi juga akan memiliki akses ke akun di ponsel Anda yang telah membuat kontak. Ini mungkin mencakup akun yang dibuat oleh aplikasi yang telah diinstal. Izin ini mengizinkan aplikasi menyimpan data kontak, dan aplikasi berbahaya dapat membagikan data kontak tanpa sepengetahuan Anda."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"ubah kontak Anda"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Memungkinkan aplikasi mengubah data tentang kontak yang tersimpan dalam tablet Anda, termasuk frekuensi Anda dalam melakukan panggilan, mengirim email, atau berkomunikasi dalam cara lain dengan kontak tertentu. Izin ini memungkinkan aplikasi menghapus data kontak."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Mengizinkan aplikasi mengubah data tentang kontak yang disimpan di perangkat Android TV Anda, termasuk frekuensi yang Anda gunakan saat melakukan panggilan, mengirim email, atau berkomunikasi dalam cara lain dengan kontak tertentu. Izin ini memungkinkan aplikasi menghapus data kontak."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Memungkinkan aplikasi mengubah data tentang kontak yang tersimpan dalam ponsel Anda, termasuk frekuensi Anda dalam melakukan panggilan, mengirim email, atau berkomunikasi dalam cara lain dengan kontak tertentu. Izin ini memungkinkan aplikasi menghapus data kontak."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Mengizinkan aplikasi mengubah data tentang kontak yang disimpan di tablet Anda. Izin ini mengizinkan aplikasi menghapus data kontak."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Mengizinkan aplikasi mengubah data tentang kontak yang disimpan di perangkat Android TV Anda. Izin ini mengizinkan aplikasi menghapus data kontak."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Mengizinkan aplikasi mengubah data tentang kontak yang disimpan di ponsel Anda. Izin ini mengizinkan aplikasi menghapus data kontak."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"membaca log panggilan"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Aplikasi ini dapat membaca histori panggilan."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"menulis log panggilan"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"akses perintah penyedia lokasi ekstra"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Memungkinkan aplikasi mengakses perintah penyedia lokasi ekstra. Tindakan ini memungkinkan aplikasi mengganggu pengoperasian GPS atau sumber lokasi lain."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"akses lokasi pasti hanya saat di latar depan"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Aplikasi ini bisa mendapatkan lokasi pasti Anda ketika aplikasi berada di latar depan. Fitur layanan lokasi ini harus diaktifkan dan tersedia di ponsel agar dapat digunakan oleh aplikasi. Fitur ini dapat meningkatkan konsumsi baterai."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"akses perkiraan lokasi (berbasis jaringan) hanya di latar depan"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Aplikasi ini dapat mengetahui lokasi berdasarkan sumber jaringan seperti menara seluler dan jaringan Wi-Fi, namun hanya jika aplikasi berada di latar depan. Layanan lokasi tersebut harus diaktifkan dan tersedia di tablet agar aplikasi dapat menggunakannya."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Aplikasi ini dapat mengetahui lokasi Anda berdasarkan sumber jaringan seperti menara seluler dan jaringan Wi-Fi, tetapi hanya jika aplikasi berada di latar depan. Layanan lokasi ini harus diaktifkan dan tersedia di perangkat Android TV agar dapat digunakan oleh aplikasi."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Aplikasi ini dapat mengetahui lokasi berdasarkan sumber jaringan seperti menara seluler dan jaringan Wi-Fi, namun hanya jika aplikasi berada di latar depan. Layanan lokasi tersebut harus diaktifkan dan tersedia di ponsel agar aplikasi dapat menggunakannya."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Aplikasi ini bisa mendapatkan lokasi pasti Anda saat berada di latar depan. Fitur layanan lokasi harus diaktifkan dan tersedia di perangkat agar dapat digunakan oleh aplikasi. Fitur ini dapat meningkatkan konsumsi baterai."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"akses perkiraan lokasi hanya saat berada di latar depan"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Aplikasi ini bisa mendapatkan perkiraan lokasi Anda hanya saat berada di latar depan. Layanan lokasi harus diaktifkan dan tersedia di perangkat agar aplikasi dapat menggunakannya."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"akses lokasi di latar belakang"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Jika aplikasi diberi izin tambahan ke akses lokasi perkiraan atau akurat, aplikasi dapat mengakses lokasi saat bekerja di latar belakang."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Aplikasi ini dapat mengakses lokasi saat berjalan di latar belakang, selain akses lokasi latar depan."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"ubah setelan audio Anda"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Memungkinkan aplikasi mengubah setelan audio global, misalnya volume dan pengeras suara mana yang digunakan untuk keluaran."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"rekam audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Memungkinkan aplikasi melihat konfigurasi Bluetooth di tablet, dan membuat serta menerima sambungan dengan perangkat yang disandingkan."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Mengizinkan aplikasi melihat konfigurasi Bluetooth di perangkat Android TV, serta melakukan dan menerima sambungan dengan perangkat yang tersambung."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Memungkinkan aplikasi melihat konfigurasi Bluetooth di ponsel, dan membuat serta menerima sambungan dengan perangkat yang disandingkan."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"kontrol NFC"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Mengizinkan apl berkomunikasi dengan tag, kartu, dan alat pembaca Komunikasi Nirkabel Jarak Dekat (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"nonaktifkan kunci layar Anda"</string>
@@ -1535,8 +1536,8 @@
<string name="launchBrowserDefault" msgid="6328349989932924119">"Luncurkan Browser?"</string>
<string name="SetupCallDefault" msgid="5581740063237175247">"Terima panggilan?"</string>
<string name="activity_resolver_use_always" msgid="5575222334666843269">"Selalu"</string>
- <string name="activity_resolver_set_always" msgid="4142825808921411476">"Setel untuk selalu membuka"</string>
- <string name="activity_resolver_use_once" msgid="948462794469672658">"Hanya sekali"</string>
+ <string name="activity_resolver_set_always" msgid="4142825808921411476">"Selalu gunakan"</string>
+ <string name="activity_resolver_use_once" msgid="948462794469672658">"Sekali ini saja"</string>
<string name="activity_resolver_app_settings" msgid="6758823206817748026">"Setelan"</string>
<string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s tidak mendukung profil kerja"</string>
<string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"Tablet"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Tersambung ke <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Ketuk untuk melihat file"</string>
<string name="pin_target" msgid="8036028973110156895">"Pasang pin"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Lepas pin"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Info aplikasi"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Memulai demo..."</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Perbarui item-item berikut di "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, dan <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Simpan"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Lain kali"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Lain kali"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Tidak pernah"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Update"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Lanjutkan"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"sandi"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Aktifkan/Nonaktifkan Layar Terpisah"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Layar Kunci"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikasi <xliff:g id="APP_NAME">%1$s</xliff:g> di Jendela pop-up."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Kolom teks <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index d23cf5f..3e67533 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Stjórnunarforrit vinnusniðsins vantar eða er skemmt. Vinnusniðinu og gögnum því tengdu hefur því verið eytt. Hafðu samband við kerfisstjórann til að fá frekari aðstoð."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Vinnusniðið þitt er ekki lengur í boði á þessu tæki"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Of margar tilraunir til að slá inn aðgangsorð"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Kerfisstjóri lét af hendi tæki til einkanota"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Tækinu er stjórnað"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Fyrirtækið þitt stjórnar þessu tæki og kann að fylgjast með netnotkun. Ýttu hér til að fá upplýsingar."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Tækið verður hreinsað"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Leyfir forritinu að senda viðvarandi tilkynningar, sem eru áfram í gangi eftir birtingu. Of mikil notkun þeirra getur hægt á virkni Android TV tækisins eða gert það óstöðugt með því að nota of mikið af minni þess."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Leyfir forriti að senda viðvarandi tilkynningar, sem eru áfram í gangi eftir birtingu. Of mikil notkun þeirra getur hægt á virkni símans eða gert hann óstöðugan með því að nota of mikið af minni hans."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"lesa tengiliði"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Leyfir forriti að lesa gögn um tengiliði sem vistuð eru í spjaldtölvunni, þ. á m. tíðni samskipta þinna við tiltekna tengiliði með símtölum, tölvupósti eða öðrum hætti. Þessi heimild gerir forritum kleift að vista tengiliðagögnin þín og spilliforrit kunna að deila tengiliðaupplýsingum án þinnar vitundar."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Leyfir forriti að lesa gögn um tengiliði sem vistuð eru í Android TV, þ. á m. tíðni samskipta þinna við tiltekna tengiliði með símtölum, tölvupósti eða öðrum hætti. Þessi heimild gerir forritum kleift að vista tengiliðagögnin þín og spilliforrit kunna að deila tengiliðaupplýsingum án þinnar vitundar."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Leyfir forriti að lesa gögn um tengiliði sem vistuð eru í símanum, þ. á m. tíðni samskipta þinna við tiltekna tengiliði með símtölum, tölvupósti eða öðrum hætti. Þessi heimild gerir forritum kleift að vista tengiliðagögnin þín og spilliforrit kunna að deila tengiliðaupplýsingum án þinnar vitundar."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Leyfir forritinu að lesa gögn um tengiliði sem vistuð eru í spjaldtölvunni þinni. Forrit munu einnig hafa aðgang að reikningum í spjaldtölvunni sem hafa búið til tengiliði. Þar á meðal geta verið reikningar sem forrit sem þú hefur sett upp hafa stofnað. Þessi heimild gerir forritum kleift að vista tengiliðagögnin þín og spilliforrit kunna að deila tengiliðaupplýsingum án þinnar vitundar."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Leyfir forritinu að lesa gögn um tengiliði sem vistuð eru í Android TV tækinu. Forrit munu einnig hafa aðgang að reikningum í Android TV tækinu sem hafa búið til tengiliði. Þar á meðal geta verið reikningar sem forrit sem þú hefur sett upp hafa stofnað. Þessi heimild gerir forritum kleift að vista tengiliðagögnin þín og spilliforrit kunna að deila tengiliðaupplýsingum án þinnar vitundar."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Leyfir forritinu að lesa gögn um tengiliði sem vistuð eru í símanum þínum. Forrit munu einnig hafa aðgang að reikningum í símanum sem hafa búið til tengiliði. Þar á meðal geta verið reikningar sem forrit sem þú hefur sett upp hafa stofnað. Þessi heimild gerir forritum kleift að vista tengiliðagögnin þín og spilliforrit kunna að deila tengiliðaupplýsingum án þinnar vitundar."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"breyta tengiliðunum þínum"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Leyfir forriti að breyta gögnum um tengiliði sem vistuð eru í spjaldtölvunni, þ. á m. tíðni samskipta þinna við tiltekna tengiliði með símtölum, tölvupósti eða öðrum hætti. Þessi heimild gerir forritum kleift að eyða tengiliðagögnum."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Leyfir forriti að breyta gögnum um tengiliði sem vistuð eru í Android TV, þ. á m. tíðni samskipta þinna við tiltekna tengiliði með símtölum, tölvupósti eða öðrum hætti. Þessi heimild gerir forritum kleift að eyða tengiliðagögnum."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Leyfir forriti að breyta gögnum um tengiliði sem vistuð eru í símanum, þ. á m. tíðni samskipta þinna við tiltekna tengiliði með símtölum, tölvupósti eða öðrum hætti. Þessi heimild gerir forritum kleift að eyða tengiliðagögnum."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Leyfir forriti að breyta gögnum um tengiliði sem vistuð eru í spjaldtölvunni. Þessi heimild gerir forritum kleift að eyða tengiliðagögnum."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Leyfir forriti að breyta gögnum um tengiliði sem vistuð eru í Android TV tækinu. Þessi heimild gerir forritum kleift að eyða tengiliðagögnum."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Leyfir forriti að breyta gögnum um tengiliði sem vistuð eru í símanum þínum. Þessi heimild gerir forritum kleift að eyða tengiliðagögnum."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"lesa símtalaskrá"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Þetta forrit getur lesið símtalaferilinn þinn."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"skrifa símtalaskrá"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"aðgangur að viðbótarskipunum staðsetningarveitu"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Leyfir forriti að fá aðgang að fleiri skipunum staðsetningarveitu. Þetta getur gert forritinu kleift að hafa áhrif á virkni GPS og annars staðsetningarbúnaðar."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"aðgangur að nákvæmri staðsetningu aðeins í forgrunni"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Þetta forrit getur aðeins séð staðsetningu þína þegar það er í forgrunni. Það verður að vera kveikt á þessari staðsetningarþjónustu og hún þarf að vera aðgengileg í símanum til að forritið geti notað hana. Þetta getur aukið rafhlöðunotkun."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"aðgangur að áætlaðri staðsetningu (út frá netkerfi), aðeins í forgrunni"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Þetta forrit getur séð staðsetningu þína út frá netkerfum á borð við farsímasenda og Wi-Fi net, en þó aðeins þegar það er í forgrunni. Það verður að vera kveikt á þessari staðsetningarþjónustu og hún þarf að vera aðgengileg spjaldtölvunni til að forritið geti notað hana."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Þetta forrit getur séð staðsetningu þína út frá netkerfum á borð við farsímasenda og Wi-Fi net, en þó aðeins þegar það er í forgrunni. Það verður að vera kveikt á þessari staðsetningarþjónustu og hún þarf að vera aðgengileg Android TV tækinu til að forritið geti notað hana."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Þetta forrit getur séð staðsetningu þína út frá netkerfum á borð við farsímasenda og Wi-Fi net, en þó aðeins þegar það er í forgrunni. Það verður að vera kveikt á þessari staðsetningarþjónustu og hún þarf að vera aðgengileg símanum til að forritið geti notað hana."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Þetta forrit getur aðeins séð staðsetningu þína þegar það er í forgrunni. Það verður að vera kveikt á staðsetningarþjónustu og hún þarf að vera tiltæk í tækinu til að forritið geti notað hana. Þetta getur aukið rafhlöðunotkun."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"aðgangur að áætlaðri staðsetningu aðeins í forgrunni"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Þetta forrit getur aðeins séð áætlaða staðsetningu þína þegar það er í forgrunni. Það verður að vera kveikt á staðsetningarþjónustu og hún þarf að vera tiltæk í tækinu til að forritið geti notað hana."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"aðgangur að staðsetningu í bakgrunni"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Ef þetta er veitt til viðbótar við aðgang að áætlaðri eða nákvæmri staðsetningu getur forritið fengið aðgang að staðsetningu á meðan það keyrir í bakgrunni."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Þetta forrit hefur aðgang að staðsetningu þegar það er í gangi í bakgrunni, og auk þess þegar það er í forgrunni."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"breyta hljóðstillingum"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Leyfir forriti að breyta altækum hljóðstillingum, s.s. hljóðstyrk og hvaða hátalari er notaður sem úttak."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"taka upp hljóð"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Leyfir forriti að skoða grunnstillingu Bluetooth í spjaldtölvunni og koma á og samþykkja tengingar við pöruð tæki."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Leyfir forriti að skoða stillingu Bluetooth í Android TV og tengjast og samþykkja tengingar við pöruð tæki."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Leyfir forriti að skoða grunnstillingu Bluetooth í símanum og koma á og samþykkja tengingar við pöruð tæki."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"stjórna nándarsamskiptum (NFC)"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Leyfir forriti að eiga samskipti við NFC-merki, -spjöld og -lesara (nándarsamskipti)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"slökkva á skjálásnum"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Tengt við <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Ýttu til að skoða skrárnar"</string>
<string name="pin_target" msgid="8036028973110156895">"Festa"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Losa"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Forritsupplýsingar"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Byrjar kynningu…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Uppfæra þessi atriði í "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> og <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Vista"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nei, takk"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ekki núna"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Aldrei"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Uppfæra"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Áfram"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"aðgangsorð"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Breyta skjáskiptingu"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lásskjár"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skjámynd"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Forritið <xliff:g id="APP_NAME">%1$s</xliff:g> í sprettiglugga."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Skjátextastika <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 8ebcb0e..2ae9f5f 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -142,7 +142,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Chiamate Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
- <string name="wifi_calling_off_summary" msgid="5626710010766902560">"Off"</string>
+ <string name="wifi_calling_off_summary" msgid="5626710010766902560">"OFF"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Chiamata tramite Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Chiamata su rete mobile"</string>
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Solo Wi-Fi"</string>
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"L\'app di amministrazione dei profili di lavoro manca o è danneggiata. Di conseguenza, il tuo profilo di lavoro e i relativi dati sono stati eliminati. Contatta l\'amministratore per ricevere assistenza."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Il tuo profilo di lavoro non è più disponibile sul dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Troppi tentativi di inserimento della password"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'amministratore ha abbandonato il dispositivo per uso personale"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Il dispositivo è gestito"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Questo dispositivo è gestito dalla tua organizzazione, che potrebbe monitorare il traffico di rete. Tocca per i dettagli."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Il dispositivo verrà resettato"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Consente all\'app di inviare annunci permanenti, che permangono anche al termine dell\'annuncio. Un uso eccessivo potrebbe rendere il dispositivo Android TV lento o instabile causando un uso eccessivo della memoria."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Consente all\'applicazione di inviare broadcast permanenti, che permangono anche al termine del broadcast. Un uso eccessivo potrebbe rendere il telefono lento o instabile causando un uso eccessivo della memoria."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"lettura contatti personali"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Consente all\'applicazione di leggere i dati relativi ai tuoi contatti memorizzati sul tablet, inclusa la frequenza con cui hai effettuato chiamate, inviato email o comunicato in altri modi con individui specifici. Questa autorizzazione consente alle applicazioni di salvare i dati dei tuoi contatti e applicazioni dannose potrebbero condividere i dati dei contatti a tua insaputa."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Consente all\'app di leggere i dati relativi ai contatti memorizzati sul dispositivo Android TV, inclusa la frequenza con cui hai chiamato contatti specifici, hai inviato loro email o hai comunicato con loro in altri modi. Questa autorizzazione consente alle app di salvare i dati dei tuoi contatti e app dannose potrebbero condividere i dati dei contatti a tua insaputa."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Consente all\'applicazione di leggere i dati relativi ai tuoi contatti memorizzati sul telefono, inclusa la frequenza con cui hai effettuato chiamate, inviato email o comunicato in altri modi con individui specifici. Questa autorizzazione consente alle applicazioni di salvare i dati dei tuoi contatti e applicazioni dannose potrebbero condividere i dati dei contatti a tua insaputa."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Consente all\'app di leggere i dati relativi ai contatti memorizzati sul tablet. Le app avranno inoltre accesso agli account memorizzati sul tablet su cui sono stati creati contatti. Potrebbero essere inclusi gli account creati da app installate. Questa autorizzazione consente alle app di salvare i dati dei tuoi contatti e app dannose potrebbero condividere i dati dei contatti a tua insaputa."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Consente all\'app di leggere i dati relativi ai contatti memorizzati sul dispositivo Android TV. Le app avranno inoltre accesso agli account memorizzati sul dispositivo Android TV su cui sono stati creati contatti. Potrebbero essere inclusi gli account creati da app installate. Questa autorizzazione consente alle app di salvare i dati dei tuoi contatti e app dannose potrebbero condividere i dati dei contatti a tua insaputa."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Consente all\'app di leggere i dati relativi ai contatti memorizzati sul telefono. Le app avranno inoltre accesso agli account memorizzati sul telefono su cui sono stati creati contatti. Potrebbero essere inclusi gli account creati da app installate. Questa autorizzazione consente alle app di salvare i dati dei tuoi contatti e app dannose potrebbero condividere i dati dei contatti a tua insaputa."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modifica dei contatti personali"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Consente all\'applicazione di modificare i dati relativi ai contatti memorizzati sul tablet, inclusa la frequenza con cui hai effettuato chiamate, inviato email o comunicato in altri modi con contatti specifici. Questa autorizzazione consente alle applicazioni di eliminare i dati dei contatti."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Consente all\'app di modificare i dati relativi ai contatti memorizzati sul dispositivo Android TV, inclusa la frequenza con cui hai chiamato contatti specifici, hai inviato loro email o hai comunicato con loro in altri modi. Questa autorizzazione consente all\'app di eliminare i dati dei contatti."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Consente all\'applicazione di modificare i dati relativi ai contatti memorizzati sul telefono, inclusa la frequenza con cui hai effettuato chiamate, inviato email o comunicato in altri modi con contatti specifici. Questa autorizzazione consente alle applicazioni di eliminare i dati dei contatti."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Consente all\'app di modificare i dati relativi ai contatti memorizzati sul tablet. Questa autorizzazione consente alle app di eliminare i dati dei contatti."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Consente all\'app di modificare i dati relativi ai contatti memorizzati sul dispositivo Android TV. Questa autorizzazione consente alle app di eliminare i dati dei contatti."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Consente all\'app di modificare i dati relativi ai contatti memorizzati sul telefono. Questa autorizzazione consente alle app di eliminare i dati dei contatti."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"lettura del registro chiamate"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Questa app può leggere la cronologia chiamate."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"scrittura del registro chiamate"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"accesso a comandi aggiuntivi provider di geolocalizz."</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Consente all\'app di accedere a ulteriori comandi del fornitore di posizione. Ciò potrebbe consentire all\'app di interferire con il funzionamento del GPS o di altre fonti di geolocalizzazione."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"accesso alla posizione esatta solo in primo piano"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Questa app può recuperare la tua posizione esatta solo quando è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul telefono affinché l\'app possa usarli. Potrebbe aumentare il consumo della batteria."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"accesso alla posizione approssimativa (in base alla rete) solo in primo piano"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul tablet affinché l\'app possa usarli."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul dispositivo Android TV affinché l\'app possa usarli."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul telefono affinché l\'app possa usarli."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Questa app può recuperare la tua posizione esatta solo quando è in primo piano. I servizi di geolocalizzazione devono essere attivi e disponibili sul dispositivo affinché l\'app possa usarli. Potrebbe aumentare il consumo della batteria."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"Accesso alla posizione approssimativa solo in primo piano"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Questa app può recuperare la tua posizione approssimativa solo quando è in primo piano. I servizi di geolocalizzazione devono essere attivi e disponibili sull\'auto affinché l\'app possa usarli."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"accesso alla posizione in background"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Se concedi l\'autorizzazione insieme all\'accesso alla posizione precisa o approssimativa, l\'app potrà accedere alla posizione mentre viene eseguita in background."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Questa app può accedere alla posizione in background, oltre ad accedervi in primo piano."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"modifica impostazioni audio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Consente all\'applicazione di modificare le impostazioni audio globali, come il volume e quale altoparlante viene utilizzato per l\'uscita."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"registrazione audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Consente all\'applicazione di visualizzare la configurazione del Bluetooth sul tablet e di stabilire e accettare connessioni con dispositivi accoppiati."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Consente all\'app di visualizzare la configurazione del Bluetooth del dispositivo Android TV, nonché di stabilire e accettare connessioni con dispositivi accoppiati."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Consente all\'applicazione di visualizzare la configurazione del Bluetooth sul telefono e di stabilire e accettare connessioni con dispositivi accoppiati."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"controllo Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Consente all\'applicazione di comunicare con tag, schede e lettori NFC (Near Field Communication)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"disattivazione blocco schermo"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Connesso a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Tocca per visualizzare i file"</string>
<string name="pin_target" msgid="8036028973110156895">"Blocca"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Sgancia"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Informazioni app"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Avvio della demo…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Vuoi aggiornare questi elementi su "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Salva"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"No, grazie"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Non ora"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Mai"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Aggiorna"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continua"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"password"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Attiva/disattiva schermo diviso"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Schermata di blocco"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"App <xliff:g id="APP_NAME">%1$s</xliff:g> in una finestra popup."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra del titolo di <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 85d0f3b..395c818 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -192,8 +192,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"אפליקציית הניהול של פרופיל העבודה חסרה או פגומה. כתוצאה מכך, פרופיל העבודה שלך נמחק, כולל כל הנתונים הקשורים אליו. לקבלת עזרה, פנה למנהל המערכת."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"פרופיל העבודה שלך אינו זמין עוד במכשיר הזה"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"בוצעו ניסיונות רבים מדי להזנת סיסמה"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"מנהל המערכת ביטל את המכשיר לצורכי שימוש אישי"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"המכשיר מנוהל"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"הארגון שלך מנהל מכשיר זה ועשוי לנטר את התנועה ברשת. הקש לקבלת פרטים."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"תתבצע מחיקה של המכשיר"</string>
@@ -387,13 +386,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"מאפשרת לאפליקציה לשלוח שידורים \"דביקים\" (sticky), שנותרים לאחר שהשידור מסתיים. בעקבות שימוש מופרז באפשרות זו, שיעור ניצול הזיכרון יהיה גבוה מדי ומכשיר ה-Android TV עלול לפעול בצורה איטית או בלתי יציבה."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"מאפשר לאפליקציה לשלוח שידורים דביקים, אשר נותרים לאחר סיום השידור. אפליקציות זדוניות עלולות להאט את פעילות הטלפון או להפוך אותה לבלתי יציבה על ידי אילוץ המכשיר להשתמש ביותר מדי זיכרון."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"קריאת אנשי הקשר שלך"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"מאפשר לאפליקציה לקרוא נתונים לגבי אנשי הקשר שלך המאוחסנים בטאבלט, כולל את התדירות שבה התקשרת, שלחת אימייל או יצרת קשר בדרכים אחרות עם אנשים ספציפיים. אישור זה מתיר לאפליקציות לשמור את נתוני אנשי הקשר שלך. כמו כן, אפליקציות זדוניות עשויות לשתף נתוני אנשי קשר ללא ידיעתך."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"מאפשרת לאפליקציה לקרוא נתונים על אנשי הקשר השמורים במכשיר ה-Android TV, כולל התדירות שבה התקשרת, שלחת אימייל או יצרת קשר בדרכים אחרות עם אנשי קשר ספציפיים. הרשאה זו מאפשרת לאפליקציות לשמור נתונים של אנשי הקשר שלך, ואפליקציות זדוניות עלולות לשתף נתונים של אנשי קשר ללא ידיעתך."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"מאפשר לאפליקציה לקרוא נתונים לגבי אנשי הקשר שלך המאוחסנים בטלפון, כולל את התדירות שבה התקשרת, שלחת אימייל או יצרת קשר בדרכים אחרות עם אנשים ספציפיים. אישור זה מתיר לאפליקציות לשמור את נתוני אנשי הקשר שלך. כמו כן, אפליקציות זדוניות עשויות לשתף נתוני אנשי קשר ללא ידיעתך."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"מאפשרת לאפליקציה לקרוא נתונים על אנשי הקשר השמורים בטאבלט שלך. לאפליקציות תהיה גם גישה לחשבונות בטאבלט שיצרו אנשי קשר. פעולה זו עשויה לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת. הרשאה זו מאפשרת לאפליקציות לשמור נתונים של אנשי הקשר שלך, ואפליקציות זדוניות עלולות לשתף נתונים של אנשי קשר ללא ידיעתך."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"מאפשרת לאפליקציה לקרוא נתונים על אנשי הקשר השמורים במכשיר ה-Android TV שלך. לאפליקציות תהיה גם גישה לחשבונות במכשיר ה-Android TV שיצרו אנשי קשר. פעולה זו עשויה לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת. הרשאה זו מאפשרת לאפליקציות לשמור נתונים של אנשי הקשר שלך, ואפליקציות זדוניות עלולות לשתף נתונים של אנשי קשר ללא ידיעתך."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"מאפשרת לאפליקציה לקרוא נתונים על אנשי הקשר השמורים בטלפון שלך. לאפליקציות תהיה גם גישה לחשבונות בטלפון שיצרו אנשי קשר. פעולה זו עשויה לכלול חשבונות שנוצרו על ידי אפליקציות שהתקנת. הרשאה זו מאפשרת לאפליקציות לשמור נתונים של אנשי הקשר שלך, ואפליקציות זדוניות עלולות לשתף נתונים של אנשי קשר ללא ידיעתך."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"שינוי אנשי הקשר שלך"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"מאפשר לאפליקציה לשנות את הנתונים לגבי אנשי הקשר שלך המאוחסנים בטאבלט, כולל התדירות שבה התקשרת, שלחת אימייל או יצרת קשר בדרכים אחרות עם אנשי קשר ספציפיים. אישור זה מתיר לאפליקציות למחוק נתוני אנשי קשר."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"מאפשרת לאפליקציה לשנות נתונים לגבי אנשי הקשר שלך השמורים במכשיר Android TV, כולל התדירות שבה התקשרת, שלחת אימייל או יצרת קשר בדרכים אחרות עם אנשי קשר ספציפיים. הרשאה זו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"מאפשר לאפליקציה לשנות את הנתונים לגבי אנשי הקשר שלך המאוחסנים בטלפון, כולל התדירות שבה התקשרת, שלחת אימייל או יצרת קשר בדרכים אחרות עם אנשי קשר ספציפיים. אישור זה מתיר לאפליקציות למחוק נתוני אנשי קשר."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים בטאבלט שלך. הרשאה זו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים במכשיר ה-Android TV שלך. הרשאה זו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"מאפשרת לאפליקציה לשנות את הנתונים לגבי אנשי הקשר המאוחסנים בטלפון שלך. הרשאה זו מאפשרת לאפליקציות למחוק נתונים של אנשי קשר."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"קריאת יומן שיחות"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"אפליקציה זו יכולה לקרוא את היסטוריית השיחות שלך."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"כתיבת יומן שיחות"</string>
@@ -413,13 +412,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"גישה לפקודות ספק מיקום נוספות"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"מאפשרת לאפליקציה לגשת לפקודות נוספות של ספק המיקום. הרשאה זו עשויה לאפשר לאפליקציה לשבש את פעולת ה-GPS או מקורות מיקום אחרים."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"קבלת גישה למיקום מדויק בחזית בלבד"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"אפליקציה זו יכולה לזהות את המיקום המדויק שלך רק כאשר היא פועלת בחזית. כדי שהאפליקציה תוכל להשתמש בשירותי המיקום, עליהם להיות מופעלים וזמינים בטלפון. ייתכן שפעולה זו תגביר את צריכת הסוללה."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"קבלת גישה למיקום המשוער (מבוסס-רשת) רק במצב פעיל"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"אפליקציה זו יכולה לזהות את המיקום שלך על סמך מקורות מיקום ברשת, כגון אנטנות סלולריות ורשתות Wi-Fi, אבל רק כשהאפליקציה במצב פעיל. שירותי מיקום אלה חייבים להיות מופעלים וזמינים בטאבלט כדי שהאפליקציה תוכל להשתמש בהם."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"אפליקציה זו יכולה לזהות את המיקום שלך על סמך מקורות מיקום ברשת, כגון אנטנות סלולריות ורשתות Wi-Fi, אבל רק כשהאפליקציה במצב פעיל. שירותי מיקום אלה חייבים להיות מופעלים וזמינים במכשיר ה-Android TV כדי שהאפליקציה תוכל להשתמש בהם."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"אפליקציה זו יכולה לזהות את המיקום שלך על סמך מקורות מיקום ברשת, כגון אנטנות סלולריות ורשתות Wi-Fi, אבל רק כשהאפליקציה במצב פעיל. שירותי מיקום אלה חייבים להיות מופעלים וזמינים בטלפון כדי שהאפליקציה תוכל להשתמש בהם."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"אפליקציה זו יכולה לזהות את המיקום המדויק שלך רק כאשר היא פועלת בחזית. כדי שהאפליקציה תוכל להשתמש בשירותי המיקום, עליהם להיות מופעלים וזמינים במכשיר. ייתכן שפעולה זו תגביר את צריכת הסוללה."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"קבלת גישה למיקום משוער תתבצע בחזית בלבד"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"אפליקציה זו יכולה לזהות את המיקום המשוער שלך רק כאשר היא פועלת בחזית. שירותי מיקום חייבים להיות מופעלים וזמינים במכשיר שלך כדי שהאפליקציה תוכל להשתמש בהם."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"גישה למיקום ברקע"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"אם מתקבל אישור, בנוסף לגישה למיקום משוער או מדויק, תהיה לאפליקציה גישה למיקום גם כשהיא פועלת ברקע."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"האפליקציה הזו יכולה לגשת למיקום כשהיא רצה ברקע, בנוסף לקבלת גישה למיקום בחזית."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"שנה את הגדרות האודיו שלך"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"מאפשר לאפליקציה לשנות הגדרות אודיו גלובליות כמו עוצמת קול ובחירת הרמקול המשמש לפלט."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"הקלט אודיו"</string>
@@ -500,6 +497,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"מאפשר לאפליקציה להציג את תצורת ה-Bluetooth בטאבלט, וכן ליצור ולקבל חיבורים עם מכשירים מותאמים."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"מאפשרת לאפליקציה להציג את הגדרת ה-Bluetooth במכשיר ה-Android TV, וליצור ולקבל חיבורים עם מכשירים מותאמים."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"מאפשר לאפליקציה להציג את תצורת ה-Bluetooth בטלפון, וכן ליצור ולקבל חיבורים עם מכשירים מותאמים."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"שלוט ב-Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"מאפשר לאפליקציה נהל תקשורת עם תגים, כרטיסים וקוראים מסוג \'תקשורת מטווח קצר\'."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"ביטול נעילת המסך שלך"</string>
@@ -543,7 +544,7 @@
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"פעולת טביעת האצבע בוטלה בידי המשתמש."</string>
<string name="fingerprint_error_lockout" msgid="7853461265604738671">"יותר מדי ניסיונות. נסה שוב מאוחר יותר."</string>
<string name="fingerprint_error_lockout_permanent" msgid="3895478283943513746">"יותר מדי ניסיונות. חיישן טביעות האצבע הושבת."</string>
- <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"נסה שוב."</string>
+ <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"כדאי לנסות שוב."</string>
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"לא נרשמו טביעות אצבע."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר זה אין חיישן טביעות אצבע."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
@@ -814,8 +815,8 @@
<string name="lockscreen_emergency_call" msgid="7500692654885445299">"חירום"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"חזרה לשיחה"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"נכון!"</string>
- <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"נסה שוב"</string>
- <string name="lockscreen_password_wrong" msgid="8605355913868947490">"נסה שוב"</string>
+ <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"כדאי לנסות שוב"</string>
+ <string name="lockscreen_password_wrong" msgid="8605355913868947490">"כדאי לנסות שוב"</string>
<string name="lockscreen_storage_locked" msgid="634993789186443380">"בטל את הנעילה לכל התכונות והנתונים"</string>
<string name="faceunlock_multiple_failures" msgid="681991538434031708">"חרגת ממספר הניסיונות המרבי של זיהוי פנים"</string>
<string name="lockscreen_missing_sim_message_short" msgid="1248431165144893792">"אין כרטיס SIM"</string>
@@ -1926,7 +1927,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"מחובר אל <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"הקש כדי להציג קבצים"</string>
<string name="pin_target" msgid="8036028973110156895">"הצמד"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"בטל הצמדה"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"פרטי אפליקציה"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"מתחיל בהדגמה…"</string>
@@ -1971,6 +1976,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"האם לעדכן פריטים אלה ב-"<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ו-<xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"שמירה"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"לא, תודה"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"לא עכשיו"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"אף פעם"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"עדכון"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"המשך"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"סיסמה"</string>
@@ -2068,5 +2075,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"החלפת מצב של מסך מפוצל"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"מסך הנעילה"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"צילום מסך"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> בחלון קופץ."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"סרגל כיתוב של <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index e21035f..da7616c 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"仕事用プロファイルの管理アプリがないか、破損しています。そのため仕事用プロファイルと関連データが削除されました。管理者にサポートをご依頼ください。"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"お使いの仕事用プロファイルはこのデバイスで使用できなくなりました"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"パスワード入力回数が上限を超えました"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"管理者により、デバイスの個人使用が許可されました"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"管理対象のデバイス"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"このデバイスは組織によって管理され、ネットワーク トラフィックが監視される場合があります。詳しくはタップしてください。"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"デバイスのデータが消去されます"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"配信が終了してもメモリに残る sticky ブロードキャストの配信をアプリに許可します。この許可を使用しすぎると、メモリの使用量が増えて Android TV デバイスの動作が遅くなったり不安定になったりすることがあります。"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"配信が終了してもメモリに残るstickyブロードキャストの配信をアプリに許可します。この許可を使用し過ぎると、メモリの使用量が増えてモバイル デバイスの動作が遅くなったり不安定になったりする恐れがあります。"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"連絡先の読み取り"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"タブレットに保存されている連絡先に関するデータの読み取りをアプリに許可します。このデータには、電話、メール、または他の手段で特定の相手と連絡をとった頻度も含まれます。これにより、アプリに連絡先データの保存を許可することになり、悪意のあるアプリによって知らないうちに連絡先データが共有される恐れがあります。"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Android TV デバイスに保存されている連絡先に関するデータの読み取りをアプリに許可します。このデータには、電話、メール、または他の手段で特定の相手と連絡をとった頻度も含まれます。これにより、連絡先データの保存をアプリに許可することになり、悪意のあるアプリによって知らないうちに連絡先データが共有される恐れがあります。"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"モバイル デバイスに保存されている連絡先に関するデータの読み取りをアプリに許可します。このデータには、電話、メール、または他の手段で特定の相手と連絡をとった頻度も含まれます。これにより、アプリに連絡先データの保存を許可することになり、悪意のあるアプリによって知らないうちに連絡先データが共有される恐れがあります。"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"タブレットに保存されている連絡先に関するデータの読み取りをアプリに許可します。また、この読み取りを許可したアプリは、連絡先を作成したタブレット上のアカウントにもアクセスできます。これには、インストールしたアプリによって作成されたアカウントも含まれます。これにより、連絡先データの保存をアプリに許可することになり、悪意のあるアプリによって知らないうちに連絡先データが共有される恐れがあります。"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Android TV デバイスに保存されている連絡先に関するデータの読み取りをアプリに許可します。また、この読み取りを許可したアプリは、連絡先を作成した Android TV デバイス上のアカウントにもアクセスできます。これには、インストールしたアプリによって作成されたアカウントも含まれます。これにより、連絡先データの保存をアプリに許可することになり、悪意のあるアプリによって知らないうちに連絡先データが共有される恐れがあります。"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"スマートフォンに保存されている連絡先に関するデータの読み取りをアプリに許可します。また、この読み取りを許可したアプリは、連絡先を作成したスマートフォン上のアカウントにもアクセスできます。これには、インストールしたアプリによって作成されたアカウントも含まれます。これにより、連絡先データの保存をアプリに許可することになり、悪意のあるアプリによって知らないうちに連絡先データが共有される恐れがあります。"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"連絡先の変更"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"タブレットに保存されている連絡先に関するデータの変更をアプリに許可します。このデータには、電話、メール、または他の手段で特定の相手と連絡をとった頻度も含まれます。これにより、アプリが連絡先データを削除できるようになります。"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Android TV デバイスに保存されている連絡先に関するデータの変更をアプリに許可します。このデータには、電話、メール、または他の手段で特定の相手と連絡をとった頻度も含まれます。これにより、連絡先データの削除をアプリに許可することになります。"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"モバイルデバイスに保存されている連絡先に関するデータの変更をアプリに許可します。このデータには、電話、メール、または他の手段で特定の相手と連絡をとった頻度も含まれます。これにより、アプリが連絡先データを削除できるようになります。"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"タブレットに保存されている連絡先に関するデータの変更をアプリに許可します。これにより、連絡先データの削除をアプリに許可することになります。"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Android TV デバイスに保存されている連絡先に関するデータの変更をアプリに許可します。これにより、連絡先データの削除をアプリに許可することになります。"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"スマートフォンに保存されている連絡先に関するデータの変更をアプリに許可します。これにより、連絡先データの削除をアプリに許可することになります。"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"通話履歴の読み取り"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"このアプリは通話履歴を読み取ることができます。"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"通話履歴の書き込み"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"位置情報提供者の追加コマンドアクセス"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"位置情報提供元の追加のコマンドにアクセスすることをアプリに許可します。許可すると、アプリがGPSなどの位置情報源の動作を妨害する恐れがあります。"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"フォアグラウンドでのみ正確な位置情報にアクセス"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"このアプリは、フォアグラウンド状態でのみユーザーの正確な位置情報を取得できます。この位置情報サービスは ON の状態にして、スマートフォンでアプリがサービスを利用できるようにする必要があります。これにより、電池の消費量が増える可能性があります。"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"フォアグラウンドでのみ(ネットワークに基づく)おおよその位置情報にアクセス"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"このアプリは、フォアグラウンドでのみ、ネットワーク位置情報源(携帯基地局や Wi-Fi ネットワークなど)に基づいて、ユーザーの位置情報を取得できます。これらの位置情報サービスは ON の状態にして、タブレットでアプリがサービスを利用できるようにする必要があります。"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"このアプリは、フォアグラウンドでのみ、ネットワーク位置情報源(携帯基地局や Wi-Fi ネットワークなど)に基づいて、ユーザーの位置情報を取得できます。これらの位置情報サービスは ON の状態にして、Android TV デバイスでアプリがサービスを利用できるようにする必要があります。"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"このアプリは、フォアグラウンドでのみ、ネットワーク位置情報源(携帯基地局や Wi-Fi ネットワークなど)に基づいて、ユーザーの位置情報を取得できます。これらの位置情報サービスは ON の状態にして、スマートフォンでアプリがサービスを利用できるようにする必要があります。"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"このアプリは、フォアグラウンドでのみユーザーの正確な位置情報を取得できます。位置情報サービスを ON にして、デバイスでアプリがサービスを利用できるようにする必要があります。これにより、電池の消費量が増える可能性があります。"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"フォアグラウンドでのみおおよその位置情報にアクセス"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"このアプリは、フォアグラウンドでのみユーザーのおおよその位置情報を取得できます。位置情報サービスを ON にして、デバイスでアプリがサービスを利用できるようにする必要があります。"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"バックグラウンドでの位置情報へのアクセス"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"これが、おおよその位置情報または正確な位置情報へのアクセスの追加権限の場合、アプリはバックグラウンドでの実行中も位置情報にアクセスできます。"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"このアプリは、フォアグラウンドで位置情報にアクセスできるだけでなく、バックグラウンドでの実行中も位置情報にアクセスできます。"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"音声設定の変更"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"音声全般の設定(音量、出力に使用するスピーカーなど)の変更をアプリに許可します。"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"録音"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"タブレットのBluetooth設定を表示すること、ペアのデバイスに接続すること/ペアのデバイスからの接続を受け入れることをアプリに許可します。"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Android TV デバイスの Bluetooth 設定の表示と、ペア設定されたデバイスへの接続の確立、またはペア設定されたデバイスからの接続の受け入れをアプリに許可します。"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"モバイルデバイスのBluetooth設定を表示すること、ペアのデバイスに接続すること/ペアのデバイスからの接続を受け入れることをアプリに許可します。"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"NFCの管理"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"NFCタグ、カード、リーダーとの通信をアプリに許可します。"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"画面ロックの無効化"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> に接続しました"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"タップしてファイルを表示"</string>
<string name="pin_target" msgid="8036028973110156895">"固定"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"固定を解除"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"アプリ情報"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"デモを開始しています…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"<xliff:g id="TYPE_0">%1$s</xliff:g>、<xliff:g id="TYPE_1">%2$s</xliff:g>、<xliff:g id="TYPE_2">%3$s</xliff:g>を "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" で更新しますか?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"はい"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"いいえ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"後で"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"なし"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"更新"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"続行"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"パスワード"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"分割画面の切り替え"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ロック画面"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"スクリーンショット"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> アプリがポップアップ ウィンドウで開きます。"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> のキャプション バーです。"</string>
</resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 941dbbd..78890df 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"სამსახურის პროფილის ადმინისტრატორის აპი მიუწვდომელია ან დაზიანებულია. ამის გამო, თქვენი სამსახურის პროფილი და დაკავშირებული მონაცემები წაიშალა. დახმარებისთვის დაუკავშირდით თქვენს ადმინისტრატორს."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"თქვენი სამსახურის პროფილი აღარ არის ხელმისაწვდომი ამ მოწყობილობაზე"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"დაფიქსირდა პაროლის შეყვანის ზედმეტად ბევრი მცდელობა"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"ადმინისტრატორმა გაათავისუფლა მოწყობილობა პირადი გამოყენებისთვის"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"მოწყობილობა მართულია"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ამ მოწყობილობას თქვენი ორგანიზაცია მართავს და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია. შეეხეთ დამატებითი დეტალებისთვის."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"თქვენი მოწყობილობა წაიშლება"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"ნებას რთავს აპს, გაგზავნოს ფიქსირებული მაუწყებლობა, რომელიც მაუწყებლობის დასრულების შემდეგაც რჩება. ჭარბმა გამოყენებამ, შესაძლოა, თქვენი Android TV მოწყობილობა ნელი ან არასტაბილური გახადოს, რადგან მეტისმეტად დიდი მეხსიერების გამოყენებას აიძულებს მას."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"აპს შეეძლება არასაჩქარო შეტყობინებების გაგზავნა, რომელიც რჩებიან გაგზავნის დასრულების შემდეგაც. მავნე აპლიკაციებს შეუძლიათ თქვენი ტელეფონის მუშაობის შენელება ან შეფერხება ზედმეტად დიდი მოცულობის მეხსიერების გამოყენების შედეგად."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"თქვენი კონტაქტების წაკითხვა"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"აპს შეეძლება, წაიკითხოს თქვენ ტაბლეტზე შენახული კონტაქტების მონაცემები, მათ შორის ინფორმაცია კონკრეტულ ადამიანებთან თქვენი დარეკვის, ელფოსტის გაგზავნის ან კომუნიკაციის სიხშირის შესახებ. ეს ნებართვა უფლებას აძლევს აპებს, შეინახონ თქვენი კონტაქტების მონაცემები და მავნე აპებმა შეიძლება გააზიარონ საკონტაქტო მონაცემები თქვენგან დამოუკიდებლად. "</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"ნებას რთავს აპს, წაიკითხოს Android TV მოწყობილობაში შენახული კონტაქტების მონაცემები, მათ შორის, მონაცემები იმის შესახებ, თუ რა სიხშირით ურეკავდით, ელფოსტას უგზავნიდით, თუ სხვა გზით უკავშირდებოდით კონკრეტულ ადამიანებს. ეს ნებართვა, აპებს საშუალებას აძლევს, შეინახონ თქვენი კონტაქტების მონაცემები, ამის გამო, მავნე აპებს შეეძლებათ გააზიარონ კონტაქტების მონაცემები, ისე რომ თქვენ ამის შესახებ არ იცოდეთ."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"აპს შეეძლება, წაიკითხოს თქვენ ტელეფონზე შენახული კონტაქტების მონაცემები, მათ შორის ინფორმაცია კონკრეტულ ადამიანებთან თქვენი დარეკვის, ელფოსტის გაგზავნის ან კომუნიკაციის სიხშირის შესახებ. ეს ნებართვა უფლებას აძლევს აპებს, შეინახონ თქვენი კონტაქტების მონაცემები და მავნე აპებმა შეიძლება გააზიარონ საკონტაქტო მონაცემები თქვენგან დამოუკიდებლად. "</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"აპს საშუალებას აძლევს, წაიკითხოს თქვენს ტაბლეტზე შენახული კონტაქტების მონაცემები. აპს, ასევე, ექნება წვდომა თქვენს ტაბლეტზე არსებულ ანგარიშებზე, რომლებსაც კონტაქტები აქვთ შექმნილი. ეს შეიძლება მოიცავდეს თქვენ მიერ ინსტალირებული აპების მიერ შექმნილ ანგარიშებს. ეს ნებართვა უფლებას აძლევს აპებს, შეინახონ თქვენი კონტაქტების მონაცემები და მავნე აპებმა შეიძლება თქვენთვის შეუტყობინებლად გააზიარონ საკონტაქტო მონაცემები."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"აპს საშუალებას აძლევს, წაიკითხოს თქვენს Android TV მოწყობილობაზე შენახული კონტაქტების მონაცემები. აპს, ასევე, ექნება წვდომა თქვენს Android TV მოწყობილობებზე არსებულ ანგარიშებზე, რომლებსაც კონტაქტები აქვთ შექმნილი. ეს შეიძლება მოიცავდეს თქვენ მიერ ინსტალირებული აპების მიერ შექმნილ ანგარიშებს. ეს ნებართვა უფლებას აძლევს აპებს, შეინახონ თქვენი კონტაქტების მონაცემები და მავნე აპებმა შეიძლება თქვენთვის შეუტყობინებლად გააზიარონ საკონტაქტო მონაცემები."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"აპს საშუალებას აძლევს, წაიკითხოს თქვენს ტელეფონზე შენახული კონტაქტების მონაცემები. აპს, ასევე, ექნება წვდომა თქვენს ტელეფონზე არსებულ ანგარიშებზე, რომლებსაც კონტაქტები აქვთ შექმნილი. ეს შეიძლება მოიცავდეს თქვენ მიერ ინსტალირებული აპების მიერ შექმნილ ანგარიშებს. ეს ნებართვა უფლებას აძლევს აპებს, შეინახონ თქვენი კონტაქტების მონაცემები და მავნე აპებმა შეიძლება თქვენთვის შეუტყობინებლად გააზიარონ საკონტაქტო მონაცემები."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"თქვენი კონტაქტების შეცვლა"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"აპს შეეძლება, შეცვალოს თქვენ ტაბლეტზე შენახული კონტაქტების მონაცემები, მათ შორის ინფორმაცია კონკრეტულ ინდივიდუალებთან თქვენი დარეკვის, ელფოსტის გაგზავნის ან კომუნიკაციის სიხშირის შესახებ. ეს ნებართვა უფლებას აძლევს აპებს, წაშალოს საკონტაქტო მონაცემები. "</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"ნებას რთავს აპს, შეცვალოს Android TV მოწყობილობაში შენახული კონტაქტების მონაცემები, მათ შორის, მონაცემები იმის შესახებ, თუ რა სიხშირით ურეკავდით, ელფოსტას უგზავნიდით, თუ სხვა გზით უკავშირდებოდით კონკრეტულ კონტაქტებს. ეს ნებართვა აპებს კონტაქტების მონაცემების წაშლის საშუალებას აძლევს."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"აპს შეეძლება, შეცვალოს თქვენ ტელეფონზე შენახული კონტაქტების მონაცემები, მათ შორის ინფორმაცია კონკრეტულ ინდივიდუალებთან თქვენი დარეკვის, ელფოსტის გაგზავნის ან კომუნიკაციის სიხშირის შესახებ. ეს ნებართვა უფლებას აძლევს აპებს, წაშალოს საკონტაქტო მონაცემები. "</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"აპს საშუალებას აძლევს, შეცვალოს თქვენს ტაბლეტზე შენახული კონტაქტების მონაცემები. ეს ნებართვა საშუალებას აძლევს აპებს, წაშალონ კონტაქტის მონაცემები."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"აპს საშუალებას აძლევს, შეცვალოს თქვენს Android TV მოწყობილობაზე შენახული კონტაქტების მონაცემები. ეს ნებართვა საშუალებას აძლევს აპებს, წაშალონ კონტაქტის მონაცემები."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"აპს საშუალებას აძლევს, შეცვალოს თქვენს ტელეფონზე შენახული კონტაქტების მონაცემები. ეს ნებართვა საშუალებას აძლევს აპებს, წაშალონ კონტაქტის მონაცემები."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"ზარების ჟურნალის წაკითხვა"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"ამ აპს შეუძლია თქვენი საუბრის ისტორიის წაკითხვა."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"ზარების ჟურნალში ჩაწერა"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"მდებარეობის პროვაიდერის დამატებით ბრძანებებზე წვდომა"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"აპს შეეძლება წვდომა ჰქონდეს მდებარეობის სერვისის დამატებით ბრძანებებზე. შესაძლოა აპმა ეს გამოიყენოს GPS-ისა და მდებარეობის სხვა წყაროების მუშაობის პროცესში ჩარევისთვის."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"ზუსტ მდებარეობაზე წვდომა მხოლოდ წინა პლანზე"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"ამ აპს შეუძლია თქვენი ზუსტი მდებარეობის შესახებ ინფორმაციის მიღება მხოლოდ მაშინ, როცა გაშვებულია წინა პლანზე. თქვენს ტელეფონზე ჩართული და ხელმისაწვდომი უნდა იყოს მდებარეობის სერვისები, აპმა მათი გამოყენება რომ შეძლოს. ამან შეიძლება გაზარდოს ბატარეის მოხმარება."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"მიახლოებით მდებარეობაზე (ქსელის კოორდინატების მიხედვით) წვდომა მხოლოდ წინა პლანზე"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"ამ აპს შეუძლია თქვენი მდებარეობის შესახებ ინფორმაციის მიღება ისეთი წყაროებიდან, როგორიცაა მობილური კავშირგაბმულობის ანძები და Wi-Fi ქსელები (თუმცა მხოლოდ მაშინ, როცა აპი გაშვებულია წინა პლანზე). მდებარეობის აღნიშნული სერვისები თქვენს ტაბლეტზე ჩართული და ხელმისაწვდომი უნდა იყოს, აპმა მათი გამოყენება რომ შეძლოს."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"ამ აპს შეუძლია თქვენი მდებარეობის შესახებ ინფორმაციის მიღება ისეთი წყაროებიდან, როგორიცაა მობილური კავშირგაბმულობის ანძები და Wi-Fi ქსელები (თუმცა მხოლოდ მაშინ, როცა აპი გაშვებულია წინა პლანზე). მდებარეობის აღნიშნული სერვისები თქვენს Android TV მოწყობილობაზე ჩართული და ხელმისაწვდომი უნდა იყოს, აპმა მათი გამოყენება რომ შეძლოს."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"ამ აპს შეუძლია თქვენი მდებარეობის შესახებ ინფორმაციის მიღება ისეთი წყაროებიდან, როგორიცაა მობილური კავშირგაბმულობის ანძები და Wi-Fi ქსელები (თუმცა მხოლოდ მაშინ, როცა აპი გაშვებულია წინა პლანზე). მდებარეობის აღნიშნული სერვისები თქვენს ტელეფონზე ჩართული და ხელმისაწვდომი უნდა იყოს, აპმა მათი გამოყენება რომ შეძლოს."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"ამ აპს შეუძლია თქვენი ზუსტი მდებარეობის შესახებ ინფორმაციის მიღება მხოლოდ მაშინ, როცა გაშვებულია წინა პლანზე. თქვენს მოწყობილობაზე ჩართული და ხელმისაწვდომი უნდა იყოს მდებარეობის სერვისები, აპმა მათი გამოყენება რომ შეძლოს. ამან შეიძლება გაზარდოს ბატარეის მოხმარება."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"მიახლოებით მდებარეობაზე წვდომა მხოლოდ წინა პლანზე"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"ამ აპს შეუძლია თქვენი მიახლოებითი მდებარეობის შესახებ ინფორმაციის მიღება მხოლოდ მაშინ, როცა გაშვებულია წინა პლანზე. თქვენს მოწყობილობაზე ჩართული და ხელმისაწვდომი უნდა იყოს მდებარეობის სერვისები, აპმა მათი გამოყენება რომ შეძლოს."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"მდებარეობაზე წვდომა ფონურ რეჟიმში"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"ამ ნებართვის მიახლოებით ან ზუსტ მდებარეობაზე წვდომის ნებართვასთან ერთად მინიჭების შემთხვევაში, აპს შეეძლება მდებარეობაზე წვდომა ფონურ რეჟიმში."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"წინა პლანზე ყოფნისას მდებარეობაზე წვდომის გარდა, ამ აპს შეუძლია, ჰქონდეს წვდომა მდებარეობაზე ფონურ რეჟიმში მუშაობისას."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"თქვენი აუდიო პარამეტრების შეცვლა"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"აპს შეეძლება აუდიოს გლობალური პარამეტრების შეცვლა. მაგ.: ხმის სიმაღლე და რომელი დინამიკი გამოიყენება სიგნალის გამოსტანად."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"აუდიოს ჩაწერა"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"აპს შეეძლება, ნახოს Bluetooth-ის კონფიგურაცია ტაბლეტზე, შექმნას და მიიღოს კავშირები დაწყვილებულ მოწყობილობებთან."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"ნებას რთავს აპს, თქვენს Android TV მოწყობილობაზე ნახოს Bluetooth-ის კონფიგურაცია, ასევე, დაამყაროს და მიიღოს კავშირები დაწყვილებულ მოწყობილობებთან."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"აპს შეეძლება, ნახოს Bluetooth-ის კონფიგურაცია ტელეფონზე და შექმნას და მიიღოს კავშირები დაწყვილებულ მოწყობილობებთან."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ახლო მოქმედების რადიოკავშირი (NFC) მართვა"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"აპს შეეძლება ახლო მოქმედების რადიოკავშირის (NFC) მეშვეობით ტეგების, ბარათებისა და წამკითხველების შემცველი მონაცემების მიმოცვლა."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"თქვენი ეკრანის ბლოკის გათიშვა"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"დაკავშირებულია <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>-თან"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"შეეხეთ ფაილების სანახავად"</string>
<string name="pin_target" msgid="8036028973110156895">"ჩამაგრება"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"ჩამაგრების მოხსნა"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"აპის შესახებ"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"მიმდინარეობს დემონსტრაციის დაწყება…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"გსურთ, "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"-ში განაახლოთ <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> და <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"შენახვა"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"არა, გმადლობთ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"ახლა არა"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"არასოდეს"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"განახლება"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"გაგრძელება"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"პაროლი"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"გაყოფილი ეკრანის გადართვა"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ჩაკეტილი ეკრანი"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ეკრანის ანაბეჭდი"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> აპი ამომხტარ ფანჯარაში."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის სუბტიტრების ზოლი."</string>
</resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index b142e58..119b2ae 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Жұмыс профилінің әкімші қолданбасы жоқ немесе бүлінген. Нәтижесінде жұмыс профиліңіз және қатысты деректер жойылды. Көмек алу үшін әкімшіге хабарласыңыз."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Жұмыс профиліңіз осы құрылғыда енді қолжетімді емес"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Құпия сөз көп рет қате енгізілді"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Әкімші құрылғыны жеке пайдалануға ұсынды."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Құрылғы басқарылады"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін. Мәліметтер алу үшін түртіңіз."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Құрылғыңыздағы деректер өшіріледі"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Қолданба трансляция біткеннен кейін сақталатын бекітілген трансляцияларды жібере алатын болады. Тым жиі пайдалансаңыз, жад толып, Android TV құрылғысы баяу немесе тұрақсыз жұмыс істеуі мүмкін."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Қолданбаға хабар тарату аяқталғанда сақталатын жабысқақ хабар тарату мүмкіндігін береді. Тым көп қолдану телефон жұмысын баяулатады немесе жадты көп қолдану арқылы жұмысын тұрақсыздандырады."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"контактілерді оқу"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Қолданбаға планшетте сақталған байланыстар, белгілі тұлғаларға шалынған қоңырау, хаттар немесе басқа байланыс түрінің жиіліктерін қоса, туралы ақпаратты оқу мүмкіндігін береді. Бұл рұқсат қолданбаға байланыстар туралы деректерді сақтау мүмкіндігін береді және залалды қолданбалар байланыстар туралы деректерді сіздің келісіміңізсіз бөлісуі ықтимал."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Қолданба Android TV құрылғыңызда сақталған контактілер туралы деректі оқи алатын болады. Бұл деректерге белгілі бір адамдарға қаншалықты жиі қоңырау шалатыныңыз, электрондық хабар жазатыныңыз немесе басқа жолмен хабарласатыныңыз туралы ақпарат кіреді. Бұл рұқсат арқылы қолданбалар контакт туралы деректерді сақтай алады. Ал зиянды қолданбалар контакт туралы деректерді сіздің рұқсатыңызсыз бөлісуі мүмкін."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Қолданбаға телефонда сақталған байланыстар, белгілі тұлғаларға шалынған қоңырау, хаттар немесе басқа байланыс түрінің жиіліктерін қоса, туралы ақпаратты оқу мүмкіндігін береді. Бұл рұқсат қолданбаға байланыстар туралы деректерді сақтау мүмкіндігін береді және залалды қолданбалар байланыстар туралы деректерді сіздің келісіміңізсіз бөлісуі ықтимал."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Қолданбаға планшетте сақталған контактілеріңіз туралы деректерді оқуға рұқсат етеді. Қолданбалар контактілер жасалған планшеттегі есептік жазбаларды пайдалана алады. Бұған сіз орнатқан қолданбалар арқылы жасалған есептік жазбалар кіруі мүмкін. Бұл рұқсат қолданбаларға контакт деректерін сақтау мүмкіндігін береді және зиянды қолданбалар контакт деректерін сіздің келісіміңізсіз бөлісуі ықтимал."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Қолданбаға Android TV құрылғысында сақталған контактілеріңіз туралы деректерді оқуға рұқсат етеді. Қолданба контактілер жасалған Android TV құрылғысындағы есептік жазбаларды пайдалана алады. Бұған сіз орнатқан қолданбалар арқылы жасалған есептік жазбалар кіруі мүмкін. Бұл рұқсат қолданбаларға контакт деректерін сақтау мүмкіндігін береді және зиянды қолданбалар контакт деректерін сіздің келісіміңізсіз бөлісуі ықтимал."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Қолданбаға телефонда сақталған контактілеріңіз туралы деректерді оқуға рұқсат етеді. Қолданбалар контактілер жасалған телефондағы есептік жазбаларды пайдалана алады. Бұған сіз орнатқан қолданбалар арқылы жасалған есептік жазбалар кіруі мүмкін. Бұл рұқсат қолданбаларға контакт деректерін сақтау мүмкіндігін береді және зиянды қолданбалар контакт деректерін сіздің келісіміңізсіз бөлісуі ықтимал."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"контактілерді өзгерту"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Қолданбаға планшетте сақталған байланыстар, белгілі тұлғаларға шалынған қоңырау, хаттар немесе басқа байланыс түрінің жиіліктерін қоса, туралы ақпаратты өзгерту мүмкіндігін береді. Бұл рұқсат қолданбаға байланыстар туралы деректерді өшіру мүмкіндігін береді."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Қолданба Android TV құрылғыңызда сақталған контактілер туралы деректі өзгерте алатын болады. Бұл деректерге белгілі бір контактіге қаншалықты жиі қоңырау шалатыныңыз, электрондық хабар жазатыныңыз немесе басқа жолмен хабарласатыныңыз туралы ақпарат кіреді. Бұл рұқсаттың көмегімен қолданбалар контакт туралы деректерді жоя алады."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Қолданбаға телефонда сақталған байланыстар, белгілі тұлғаларға шалынған қоңырау, хаттар немесе басқа байланыс түрінің жиіліктерін қоса, туралы ақпаратты өзгерту мүмкіндігін береді. Бұл рұқсат қолданбаға байланыстар туралы деректерді өшіру мүмкіндігін береді."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Қолданбаға планшетте сақталған контактілеріңіз туралы деректерді өзгертуге рұқсат етеді. Бұл рұқсат қолданбаларға контактілер туралы деректерді жоюға рұқсат береді."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Қолданбаға Android TV құрылғысында сақталған контактілеріңіз туралы деректерді өзгертуге рұқсат етеді. Бұл рұқсат қолданбаларға контактілер туралы деректерді жоюға рұқсат береді."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Қолданбаға телефонда сақталған контактілеріңіз туралы деректерді өзгертуге рұқсат етеді. Бұл рұқсат қолданбаларға контактілер туралы деректерді жоюға рұқсат береді."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"қоңыраулар тіркеуін оқу"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Бұл қолданба қоңыраулар тарихын оқи алады."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"қоңырау тіркеуді жазу"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"қосымша аймақ жабдықтаушы пәрмендеріне қол жетімділік"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Қолданбаға орын жеткізушісінің қосымша пәрмендеріне қатынасуға рұқсат береді. Бұл қолданбаға GPS немесе басқа орын көздерінің жұмысына кедергі келтіруге рұқсат беруі мүмкін."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"нақты орналасқан жер туралы ақпаратқа тек ашық экранда кіру"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Бұл қолданба нақты орналасқан жеріңіз туралы ақпаратты экранда ашық тұрғанда ғана анықтай алады. Қолданба бұл орынды анықтау қызметтерін пайдалана алуы үшін, олар қосулы әрі телефонда қолжетімді болуы керек. Батарея көбірек тұтынылуы мүмкін."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"болжалды геодерекке (желі негізінде) тек экрандық режимде кіру"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Бұл қолданба орналасқан жеріңізді ұялы байланыс мұнаралары мен Wi-Fi желілері сияқты желі көздерінің негізінде анықтайды. Бірақ бұл үшін қолданба экрандық режимде жұмыс істеп тұруы керек. Қолданба бұл орынды анықтау қызметтерін пайдалана алуы үшін, олар қосулы әрі планшетте қолжетімді болуы керек."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Бұл қолданба орналасқан жеріңізді ұялы байланыс мұнаралары мен Wi-Fi желілері сияқты желі көздерінің негізінде анықтайды. Бірақ бұл үшін қолданба ашық тұруы керек. Қолданба орынды анықтау қызметтерін пайдалана алуы үшін, олар қосулы әрі Android TV құрылғысында қолжетімді болуы керек."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Бұл қолданба орналасқан жеріңізді ұялы байланыс мұнаралары мен Wi-Fi желілері сияқты желі көздерінің негізінде анықтайды. Бірақ бұл үшін қолданба экранда ашық тұруы керек. Қолданба бұл орынды анықтау қызметтерін пайдалана алуы үшін, олар қосулы әрі телефонда қолжетімді болуы керек."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Бұл қолданба нақты орналасқан жеріңіз туралы ақпаратты экранда ашық тұрғанда ғана анықтай алады. Қолданба орынды анықтау қызметтерін пайдалана алуы үшін, олар қосулы әрі құрылғыда қолжетімді болуы керек. Батарея көбірек тұтынылуы мүмкін."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"болжалды орналасқан жер туралы ақпаратқа тек ашық экранда кіру"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Бұл қолданба орналасқан жеріңіз туралы болжалды ақпаратты экранда ашық тұрғанда ғана анықтай алады. Қолданба орынды анықтау қызметтерін пайдалана алуы үшін, олар қосулы әрі құрылғыда қолжетімді болуы керек."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"геодеректерді фондық режимде пайдалану"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Егер ол шамамен есептегендегі немесе нақты орынды пайдалануға рұқсат алса, қолданба фондық режимде жұмыс істеп тұрып-ақ геодеректерді пайдалана алады."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Қолданба фондық және белсенді режимде де орналасқан жеріңіз мәліметін ала алады."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"аудио параметрлерін өзгерту"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Қолданбаға дыбыс қаттылығы және аудио шығыс үндеткішін таңдау сияқты жаһандық аудио параметрлерін өзгерту мүмкіндігін береді."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"аудио жазу"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Қолданбаға планшеттегі Bluetooth конфигурациясын көру және жұпталған құрылғымен байланыс орнату немесе қабылдау мүмкіндігін береді."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Қолданба Android TV құрылғыңыздағы Bluetooth конфигурациясын көре алады және жұпталған құрылғылармен байланыс орнатып, оларды қабылдай алатын болады."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Қолданбаға телефондағы Bluetooth конфигурациясын көру және жұпталған құрылғымен байланыс орнату немесе қабылдау мүмкіндігін береді"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"NFC функциясын басқару"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Қолданбаға NFC белгілерімен, карталармен және оқу құралдарымен байланысуға рұқсат береді."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"экран бекітпесін істен шығару"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> қосылу орындалды"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Файлдарды көру үшін түртіңіз"</string>
<string name="pin_target" msgid="8036028973110156895">"PIN коды"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Босату"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Қолданба ақпараты"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Демо нұсқасы іске қосылуда..."</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" қызметіндегі <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> және <xliff:g id="TYPE_2">%3$s</xliff:g> деректері жаңартылсын ба?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Сақтау"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Жоқ, рақмет"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Қазір емес"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Ешқашан"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Жаңарту"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Жалғастыру"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"құпия сөз"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Экранды бөлу мүмкіндігін қосу/өшіру"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Құлып экраны"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Скриншот"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Қалқымалы терезедегі <xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасының жазу жолағы."</string>
</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 43289eb..331c9f3 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"កម្មវិធីអ្នកគ្រប់គ្រងកម្រងព័ត៌មានការងារនេះអាចបាត់ ឬមានបញ្ហា។ ដូច្នេះហើយទើបកម្រងព័ត៌មានការងាររបស់អ្នក និងទិន្នន័យដែលពាក់ព័ន្ធត្រូវបានលុប។ សូមទាក់ទងទៅអ្នកគ្រប់គ្រងរបស់អ្នក ដើម្បីទទួលបានជំនួយ។"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"កម្រងព័ត៌មានការងាររបស់អ្នកលែងមាននៅលើឧបករណ៍នេះទៀតហើយ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ការព្យាយាមបញ្ចូលពាក្យសម្ងាត់ច្រើនដងពេកហើយ"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"អ្នកគ្រប់គ្រងបានបោះបង់ឧបករណ៍ចោលដោយសារការប្រើប្រាស់ផ្ទាល់ខ្លួន"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"ឧបករណ៍ស្ថិតក្រោមការគ្រប់គ្រង"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ស្ថាប័នរបស់អ្នកគ្រប់គ្រងឧបករណ៍នេះ ហើយអាចនឹងតាមដានចរាចរណ៍បណ្តាញ។ ចុចដើម្បីទទួលបានព័ត៌មានលម្អិត។"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"ឧបករណ៍របស់អ្នកនឹងត្រូវបានលុប"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"អនុញ្ញាតឱ្យកម្មវិធីផ្ញើការផ្សាយស្អិត ដែលមានបន្ទាប់ពីការផ្សាយចប់។ ការប្រើប្រាស់ច្រើនពេកអាចធ្វើឱ្យឧបករណ៍ Android TV របស់អ្នកប្រើអង្គចងចាំច្រើនជ្រុល ដែលធ្វើឱ្យវាដើរយឺត ឬគ្មានស្ថិរភាព។"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ឲ្យកម្មវិធីផ្ញើការប្រកាសដែលទាក់ទាញ ដែលមានបន្ទាប់ពីការប្រកាសចប់។ ការប្រើលើសអាចធ្វើឲ្យទូរស័ព្ទយឺត ឬមិនស្ថិតស្ថេរដោយធ្វើឲ្យវាប្រើអង្គចងចាំធំពេក។"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"អានទំនាក់ទំនងរបស់អ្នក"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"ឲ្យកម្មវិធីអានទិន្នន័យអំពីទំនាក់ទំនងរបស់អ្នកដែលមានក្នុងកុំព្យូទ័របន្ទះរបស់អ្នក រួមមានប្រេកង់ដែលអ្នកបានហៅ អ៊ីមែល ឬទាក់ទងតាមវិធីផ្សេងៗជាមួយមនុស្សណាម្នាក់។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីរក្សាទុកទិន្នន័យទំនាក់ទំនងរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យទំនាក់ទំនងដោយមិនឲ្យអ្នកដឹង។"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"អនុញ្ញាតឱ្យកម្មវិធីអានទិន្នន័យអំពីទំនាក់ទំនង ដែលអ្នកបានរក្សាទុកនៅក្នុងឧបករណ៍ Android TV របស់អ្នក រួមទាំងភាពញឹកញាប់ដែលអ្នកបានហៅទូរសព្ទ ផ្ញើអ៊ីមែល ឬទាក់ទងតាមវិធីផ្សេងទៀតជាមួយបុគ្គលជាក់លាក់។ ការអនុញ្ញាតនេះអនុញ្ញាតឱ្យកម្មវិធីរក្សាទុកទិន្នន័យទំនាក់ទំនងរបស់អ្នក ហើយកម្មវិធីគ្រោះថ្នាក់អាចនឹងចែករំលែកទិន្នន័យទំនាក់ទំនងដោយមិនឱ្យអ្នកដឹង។"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"ឲ្យកម្មវិធីអានទិន្នន័យអំពីទំនាក់ទំនងរបស់អ្នកដែលបានរក្សាទុកក្នុងទូរស័ព្ទ រួមមានប្រេកង់ដែលអ្នកបានហៅ អ៊ីមែល ឬទាក់ទងតាមវិធីផ្សេងៗជាមួយអ្នកណាម្នាក់។ សិទ្ធិនេះឲ្យកម្មវិធីរក្សាទុកទិន្នន័យទំនាក់ទំនងរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យទំនាក់ទំនងដោយមិនឲ្យអ្នកដឹង។"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"អនុញ្ញាតឱ្យកម្មវិធីអានទិន្នន័យអំពីទំនាក់ទំនង ដែលអ្នកបានរក្សាទុកនៅក្នុងថេប្លេតរបស់អ្នក។ កម្មវិធីក៏នឹងមានសិទ្ធិចូលប្រើគណនីនៅលើថេប្លេត ដែលអ្នកបានបង្កើតទំនាក់ទំនងផងដែរ។ គណនីទាំងនោះអាចរួមបញ្ចូលទាំងគណនី ដែលបង្កើតដោយកម្មវិធីដែលអ្នកបានដំឡើង។ ការអនុញ្ញាតនេះអនុញ្ញាតឱ្យកម្មវិធីរក្សាទុកទិន្នន័យទំនាក់ទំនងរបស់អ្នក ហើយកម្មវិធីគ្រោះថ្នាក់អាចនឹងចែករំលែកទិន្នន័យទំនាក់ទំនងដោយមិនឱ្យអ្នកដឹង។"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"អនុញ្ញាតឱ្យកម្មវិធីអានទិន្នន័យអំពីទំនាក់ទំនង ដែលអ្នកបានរក្សាទុកនៅក្នុងឧបករណ៍ Android TV របស់អ្នក។ កម្មវិធីក៏នឹងមានសិទ្ធិចូលប្រើគណនីនៅលើឧបករណ៍ Android TV ដែលអ្នកបានបង្កើតទំនាក់ទំនងផងដែរ។ គណនីទាំងនោះអាចរួមបញ្ចូលទាំងគណនី ដែលបង្កើតដោយកម្មវិធីដែលអ្នកបានដំឡើង។ ការអនុញ្ញាតនេះអនុញ្ញាតឱ្យកម្មវិធីរក្សាទុកទិន្នន័យទំនាក់ទំនងរបស់អ្នក ហើយកម្មវិធីគ្រោះថ្នាក់អាចនឹងចែករំលែកទិន្នន័យទំនាក់ទំនងដោយមិនឱ្យអ្នកដឹង។"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"អនុញ្ញាតឱ្យកម្មវិធីអានទិន្នន័យអំពីទំនាក់ទំនង ដែលអ្នកបានរក្សាទុកនៅក្នុងទូរសព្ទរបស់អ្នក។ កម្មវិធីក៏នឹងមានសិទ្ធិចូលប្រើគណនីនៅលើទូរសព្ទ ដែលអ្នកបានបង្កើតទំនាក់ទំនងផងដែរ។ គណនីទាំងនោះអាចរួមបញ្ចូលទាំងគណនី ដែលបង្កើតដោយកម្មវិធីដែលអ្នកបានដំឡើង។ ការអនុញ្ញាតនេះអនុញ្ញាតឱ្យកម្មវិធីរក្សាទុកទិន្នន័យទំនាក់ទំនងរបស់អ្នក ហើយកម្មវិធីគ្រោះថ្នាក់អាចនឹងចែករំលែកទិន្នន័យទំនាក់ទំនងដោយមិនឱ្យអ្នកដឹង។"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"កែទំនាក់ទំនងរបស់អ្នក"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"ឲ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនងរបស់អ្នកដែលបានរក្សាទុកក្នុងកុំព្យូទ័របន្ទះ រួមមានប្រេកង់ដែលអ្នកបានហៅ អ៊ីមែល ឬទាក់ទងតាមវិធីផ្សេងៗជាមួយទំនាក់ទំនងជាក់លាក់។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនងរបស់អ្នក។"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"អនុញ្ញាតឱ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនងដែលអ្នកបានរក្សាទុកនៅក្នុងឧបករណ៍ Android TV របស់អ្នក រួមទាំងភាពញឹកញាប់ដែលអ្នកបានហៅទូរសព្ទ ផ្ញើអ៊ីមែល ឬទាក់ទងតាមវិធីផ្សេងទៀតជាមួយទំនាក់ទំនាក់ជាក់លាក់ផងដែរ។ ការអនុញ្ញាតនេះអនុញ្ញាតឱ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនង។"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"ឲ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនងរបស់អ្នកដែលបានរក្សាទុកក្នុងទូរស័ព្ទរបស់អ្នក រួមមានប្រេកង់ដែលអ្នកបានហៅ អ៊ីមែល ឬបានទាក់ទងតាមវិធីផ្សេងៗជាមួយទំនាក់ទំនាក់ជាក់លាក់។ សិទ្ធិនេះឲ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនង។"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"អនុញ្ញាតឱ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនង ដែលអ្នកបានរក្សាទុកនៅក្នុងថេប្លេតរបស់អ្នក។ ការអនុញ្ញាតនេះអនុញ្ញាតឱ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនង។"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"អនុញ្ញាតឱ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនង ដែលអ្នកបានរក្សាទុកនៅក្នុងឧបករណ៍ Android TV របស់អ្នក។ ការអនុញ្ញាតនេះអនុញ្ញាតឱ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនង។"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"អនុញ្ញាតឱ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនង ដែលអ្នកបានរក្សាទុកនៅក្នុងទូរសព្ទរបស់អ្នក។ ការអនុញ្ញាតនេះអនុញ្ញាតឱ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនង។"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"អានកំណត់ហេតុហៅ"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"កម្មវិធីនេះអាចអានប្រវត្តិហៅទូរសព្ទរបស់អ្នកបាន។"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"សរសេរបញ្ជីហៅ"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"ចូលដំណើរការពាក្យបញ្ជាក្រុមហ៊ុនផ្ដល់ទីតាំង"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"ឲ្យកម្មវិធីចូលដំណើរការពាក្យបញ្ជាកម្មវិធីផ្ដល់ទីតាំងបន្ថែម។ វាអាចអនុញ្ញាតឲ្យកម្មវិធីទាក់ទងជាមួយប្រតិបត្តិការជីភីអេស ឬប្រភពទីតាំងផ្សេង។"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"ចូលប្រើទីតាំងជាក់លាក់តែនៅផ្ទៃខាងមុខប៉ុណ្ណោះ"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"កម្មវិធីនេះអាចទទួលបានទីតាំងពិតប្រាកដរបស់អ្នកតែនៅពេលវាស្ថិតនៅផ្ទៃខាងមុខប៉ុណ្ណោះ។ សេវាកម្មទីតាំងទាំងនេះត្រូវតែបើក និងមាននៅលើទូរសព្ទរបស់អ្នក ដើម្បីឱ្យកម្មវិធីនេះអាចប្រើពួកវាបាន។ វាអាចប្រើថាមពលច្រើនជាងមុន។"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"ចូលប្រើទីតាំងប្រហាក់ប្រហែល (ផ្អែកលើបណ្តាញ) នៅផ្ទៃខាងមុខតែប៉ុណ្ណោះ"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"កម្មវិធីនេះអាចទទួលបានទីតាំងរបស់អ្នក ដោយផ្អែកលើប្រភពបណ្តាញដូចជា អង់តែនបណ្តាញទូរសព្ទ និងបណ្តាញ Wi-Fi ជាដើម ប៉ុន្តែនៅពេលកម្មវិធីស្ថិតនៅផ្ទៃខាងមុខតែប៉ុណ្ណោះ។ សេវាកម្មទីតាំងទាំងនេះត្រូវតែបើក និងមាននៅលើថេប្លេតរបស់អ្នក ដើម្បីឱ្យកម្មវិធីនេះអាចប្រើវាបាន។"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"កម្មវិធីនេះអាចទទួលបានទីតាំងរបស់អ្នក ដោយផ្អែកលើប្រភពបណ្តាញដូចជា អង់តែនបណ្តាញទូរសព្ទ និងបណ្តាញ Wi-Fi ជាដើម ប៉ុន្តែនៅពេលកម្មវិធីស្ថិតនៅផ្ទៃខាងមុខតែប៉ុណ្ណោះ។ សេវាកម្មទីតាំងទាំងនេះត្រូវតែបើក និងមាននៅលើឧបករណ៍ Android TV របស់អ្នក ដើម្បីអាចឱ្យកម្មវិធីប្រើវាបាន។"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"កម្មវិធីនេះអាចទទួលបានទីតាំងរបស់អ្នក ដោយផ្អែកលើប្រភពបណ្តាញដូចជា អង់តែនបណ្តាញទូរសព្ទ និងបណ្តាញ Wi-Fi ជាដើម ប៉ុន្តែនៅពេលកម្មវិធីស្ថិតនៅផ្ទៃខាងមុខតែប៉ុណ្ណោះ។ សេវាកម្មទីតាំងទាំងនេះត្រូវតែបើក និងមាននៅលើទូរសព្ទរបស់អ្នក ដើម្បីឱ្យកម្មវិធីនេះអាចប្រើវាបាន។"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"កម្មវិធីនេះអាចទទួលបានទីតាំងជាក់លាក់របស់អ្នក តែនៅពេលវាស្ថិតនៅផ្ទៃខាងមុខប៉ុណ្ណោះ។ សេវាកម្មទីតាំងត្រូវតែបើក និងមាននៅលើឧបករណ៍របស់អ្នក ដើម្បីអាចឱ្យកម្មវិធីប្រើវាបាន។ សកម្មភាពនេះអាចបង្កើនការប្រើប្រាស់ថ្ម។"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"ចូលប្រើទីតាំងប្រហាក់ប្រហែលតែនៅផ្ទៃខាងមុខប៉ុណ្ណោះ"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"កម្មវិធីនេះអាចទទួលបានទីតាំងប្រហាក់ប្រហែលរបស់អ្នក តែនៅពេលវាស្ថិតនៅផ្ទៃខាងមុខប៉ុណ្ណោះ។ សេវាកម្មទីតាំងត្រូវតែបើក និងមាននៅលើឧបករណ៍របស់អ្នក ដើម្បីអាចឱ្យកម្មវិធីប្រើវាបាន។"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"ចូលប្រើទីតាំងនៅផ្ទៃខាងក្រោយ"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"ប្រសិនបើផ្ដល់ការអនុញ្ញាតនេះបន្ថែមពីលើការចូលប្រើទីតាំងជាក់លាក់ ឬប្រហាក់ប្រហែល កម្មវិធីនឹងអាចចូលប្រើទីតាំងនោះ ខណៈពេលដំណើរការនៅផ្ទៃខាងក្រោយ។"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"កម្មវិធីនេះអាចចូលប្រើទីតាំង ពេលកំពុងដំណើរការនៅផ្ទៃខាងក្រោយ បន្ថែមពីលើការចូលប្រើទីតាំងនៅផ្ទៃខាងមុខ។"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"ប្ដូរការកំណត់អូឌីយូរបស់អ្នក"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"ឲ្យកម្មវិធីកែការកំណត់សំឡេងសកល ដូចជាកម្រិតសំឡេង និងអូប៉ាល័រដែលបានប្រើសម្រាប់លទ្ធផល។"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ថតសំឡេង"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ឲ្យកម្មវិធីមើលការកំណត់រចនាសម្ព័ន្ធប៊្លូធូសលើកុំព្យូទ័របន្ទះ ព្រមទាំងធ្វើការតភ្ជាប់ និងទទួលជាមួយឧបករណ៍បានផ្គូផ្គង។"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"អនុញ្ញាតឱ្យកម្មវិធីមើលការកំណត់រចនាសម្ព័ន្ធប៊្លូធូសនៅលើឧបករណ៍ Android TV របស់អ្នក ព្រមទាំងធ្វើការតភ្ជាប់ និងទទួលយកការតភ្ជាប់ជាមួយឧបករណ៍ដែលបានផ្គូផ្គង។"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ឲ្យកម្មវិធីមើលការកំណត់រចនាសម្ព័ន្ធប៊្លូធូសក្នុងទូរស័ព្ទ ដើម្បីទទួល និងតភ្ជាប់ជាមួយឧបករណ៍បានផ្គូផ្គង។"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ពិនិត្យការទាក់ទងនៅក្បែរ (NFC)"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"ឲ្យកម្មវិធីទាក់ទងជាមួយស្លាក (NFC) កាត និងកម្មវិធីអាន។"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"បិទការចាក់សោអេក្រង់របស់អ្នក"</string>
@@ -1864,7 +1865,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"បានភ្ជាប់ទៅ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ប៉ះដើម្បីមើលឯកសារ"</string>
<string name="pin_target" msgid="8036028973110156895">"ខ្ទាស់"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"មិនខ្ទាស់"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"ព័ត៌មានកម្មវិធី"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"កំពុងចាប់ផ្តើមការបង្ហាញសាកល្បង…"</string>
@@ -1907,6 +1912,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"ធ្វើបច្ចុប្បន្នភាពធាតុទាំងនេះនៅក្នុង "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> និង <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"រក្សាទុក"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"ទេ អរគុណ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"កុំទាន់"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"កុំឱ្យសោះ"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"ធ្វើបច្ចុប្បន្នភាព"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"បន្ត"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"ពាក្យសម្ងាត់"</string>
@@ -2002,5 +2009,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"បិទ/បើកមុខងារបំបែកអេក្រង់"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"អេក្រង់ចាក់សោ"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"រូបថតអេក្រង់"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"កម្មវិធី <xliff:g id="APP_NAME">%1$s</xliff:g> នៅក្នុងវិនដូលោតឡើង។"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"របារពណ៌នាអំពី <xliff:g id="APP_NAME">%1$s</xliff:g>។"</string>
</resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 6ebe7b4..cb7fd71 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ನಿರ್ವಾಹಕ ಅಪ್ಲಿಕೇಶನ್ ಕಳೆದು ಹೋಗಿದೆ ಅಥವಾ ಹಾಳಾಗಿದೆ. ಇದರ ಪರಿಣಾಮವಾಗಿ ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಮತ್ತು ಅದಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗಿದೆ. ಸಹಾಯಕ್ಕಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಈ ಸಾಧನದಲ್ಲಿ ಈಗ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ಹಲವಾರು ಪಾಸ್ವರ್ಡ್ ಪ್ರಯತ್ನಗಳು"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"ವೈಯಕ್ತಿಕ ಬಳಕೆಗಾಗಿ ನಿರ್ವಾಹಕರು ತೊರೆದ ಸಾಧನ"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಅದು ನೆಟ್ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಮೇಲೆ ಗಮನವಿರಿಸಬಹುದು. ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"ಪ್ರಸಾರವು ಮುಕ್ತಾಯಗೊಂಡ ನಂತರ ಉಳಿದಿರುವ ಜಿಗುಟಾದ ಪ್ರಸಾರಗಳನ್ನು ಕಳುಹಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದರ ಹೆಚ್ಚಿನ ಬಳಕೆಯು Android TV ಸಾಧನವನ್ನು ನಿಧಾನಗೊಳಿಸುತ್ತದೆ ಅಥವಾ ಅತಿಯಾಗಿ ಮೆಮೊರಿಯನ್ನು ಬಳಸುವಂತೆ ಮಾಡುವ ಮೂಲಕ ಅಸ್ಥಿರಗೊಳಿಸುತ್ತದೆ."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ಪ್ರಸಾರ ಕೊನೆಗೊಂಡ ನಂತರ ಹಾಗೆಯೇ ಉಳಿಯುವ ಸ್ಟಿಕಿ ಪ್ರಸಾರಗಳನ್ನು ಕಳುಹಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಮಿತಿಮೀರಿದ ಬಳಕೆಯು ಫೋನ್ ಅನ್ನು ನಿಧಾನಗೊಳಿಸಬಹುದು ಅಥವಾ ಅತಿಯಾದ ಮೆಮೊರಿ ಬಳಕೆಯು ಅಸ್ಥಿರತೆಯನ್ನು ಉಂಟುಮಾಡಬಹುದು."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ಓದಿರಿ"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ನಿರ್ದಿಷ್ಟ ವ್ಯಕ್ತಿಗಳೊಂದಿಗೆ ನೀವು ಇತರ ಮಾರ್ಗಗಳಲ್ಲಿ ಮಾಡಿರುವ ಕರೆ, ಇಮೇಲ್ ಅಥವಾ ಸಂವಹನ ನಡೆಸಿರುವ ಆವರ್ತನವೂ ಸೇರಿದಂತೆ, ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತ ಡೇಟಾವನ್ನು ರೀಡ್ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಸಂಪರ್ಕದ ಡೇಟಾವನ್ನು ಉಳಿಸಿಕೊಳ್ಳಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ ಮತ್ತು ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಗಮನಕ್ಕೆ ತರದೆಯೇ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"ನಿರ್ದಿಷ್ಟ ವ್ಯಕ್ತಿಗಳೊಂದಿಗೆ ಇತರ ವಿಧಾನಗಳಲ್ಲಿ ನೀವು ಕರೆ ಮಾಡಿದ, ಇಮೇಲ್ ಮಾಡಿದ ಅಥವಾ ಸಂವಹನ ಮಾಡಿದ ಆವರ್ತನ ಪ್ರಮಾಣ ಸೇರಿದಂತೆ ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಸಂಪರ್ಕದ ಡೇಟಾವನ್ನು ಉಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ಅನುಮತಿಸುತ್ತದೆ, ಮತ್ತು ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ನಿಮಗೆ ತಿಳಿಯದಂತೆ ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ನಿರ್ದಿಷ್ಟ ವ್ಯಕ್ತಿಗಳ ಜೊತೆಗೆ ನೀವು ವಿವಿಧ ಮಾರ್ಗಗಳಲ್ಲಿ ಮಾಡಿರುವ ಕರೆ, ಇಮೇಲ್ ಮತ್ತು ಸಂವಹನವನ್ನು ನಡೆಸಿರುವ ಆವರ್ತನವೂ ಸೇರಿದಂತೆ, ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತ ಡೇಟಾವನ್ನು ರೀಡ್ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಸಂಪರ್ಕದ ಡೇಟಾವನ್ನು ಉಳಿಸಿಕೊಳ್ಳಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ ಮತ್ತು ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಗಮನಕ್ಕೆ ತರದೆಯೇ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ರೀಡ್ ಮಾಡಲು ಆ್ಯಪ್ಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಂಪರ್ಕಗಳನ್ನು ರಚಿಸಿದ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿನ ಖಾತೆಗಳಿಗೂ ಸಹ ಆ್ಯಪ್ಗಳು ಪ್ರವೇಶ ಹೊಂದಿರುತ್ತವೆ. ಇದರಲ್ಲಿ ನೀವು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್ಗಳು ರಚಿಸಿದ ಖಾತೆಗಳನ್ನು ಒಳಗೊಂಡಿರಬಹುದು. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಉಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಆದರೆ ದುರುದ್ದೇಶಪೂರಿತ ಆ್ಯಪ್ಗಳಿಗೆ ನಿಮ್ಮ ಗಮನಕ್ಕೆ ಬಾರದೇ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹಿಸಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ರೀಡ್ ಮಾಡಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ರಚಿಸಲಾದ ಸಂಪರ್ಕಗಳಿಗೆ ಖಾತೆಗಳಿಗೆ ಆ್ಯಪ್ಗಳು ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತವೆ. ಇದರಲ್ಲಿ ನೀವು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್ಗಳು ರಚಿಸಿದ ಖಾತೆಗಳನ್ನು ಒಳಗೊಂಡಿರಬಹುದು. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಉಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಆದರೆ ದುರುದ್ದೇಶಪೂರಿತ ಆ್ಯಪ್ಗಳಿಗೆ ನಿಮ್ಮ ಗಮನಕ್ಕೆ ಬಾರದೇ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ರೀಡ್ ಮಾಡಲು ಆ್ಯಪ್ಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಂಪರ್ಕಗಳನ್ನು ರಚಿಸಿದ ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿನ ಖಾತೆಗಳಿಗೂ ಸಹ ಆ್ಯಪ್ಗಳು ಪ್ರವೇಶ ಹೊಂದಿರುತ್ತವೆ. ಇದರಲ್ಲಿ ನೀವು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್ಗಳು ರಚಿಸಿದ ಖಾತೆಗಳನ್ನು ಒಳಗೊಂಡಿರಬಹುದು. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಉಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಆದರೆ ದುರುದ್ದೇಶಪೂರಿತ ಆ್ಯಪ್ಗಳಿಗೆ ನಿಮ್ಮ ಗಮನಕ್ಕೆ ಬಾರದೇ ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ಮಾರ್ಪಡಿಸಿ"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"ನಿರ್ದಿಷ್ಟ ಸಂಪರ್ಕಗಳೊಂದಿಗೆ ಇತರ ಮಾರ್ಗಗಳಲ್ಲಿ ನೀವು ಕರೆ, ಇಮೇಲ್, ಅಥವಾ ಸಂವಹನ ನಡೆಸಿರುವ ಆವರ್ತನವೂ ಒಳಗೊಂಡಂತೆ, ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ಸಂಪರ್ಕದ ಡೇಟಾವನ್ನು ಅಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"ನಿರ್ದಿಷ್ಟ ವ್ಯಕ್ತಿಗಳೊಂದಿಗೆ ಇತರ ವಿಧಾನಗಳಲ್ಲಿ ನೀವು ಕರೆ ಮಾಡಿದ, ಇಮೇಲ್ ಮಾಡಿದ ಅಥವಾ ಸಂವಹನ ಮಾಡಿದ ಆವರ್ತನ ಪ್ರಮಾಣ ಸೇರಿದಂತೆ ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಈ ಅನುಮತಿಯು ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಅಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"ನಿರ್ದಿಷ್ಟ ಸಂಪರ್ಕಗಳೊಂದಿಗೆ ಇತರ ಮಾರ್ಗಗಳಲ್ಲಿ ನೀವು ಕರೆ, ಇಮೇಲ್, ಅಥವಾ ಸಂವಹನ ನಡೆಸಿರುವ ಆವರ್ತನವೂ ಒಳಗೊಂಡಂತೆ, ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ಸಂಪರ್ಕದ ಡೇಟಾವನ್ನು ಅಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ಮಾರ್ಪಡಿಸಲು ಆ್ಯಪ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಅಳಿಸಲು ಆ್ಯಪ್ಗಳಿಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ಮಾರ್ಪಡಿಸಲು ಆ್ಯಪ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಅಳಿಸಲು ಆ್ಯಪ್ಗಳಿಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳ ಕುರಿತಾದ ಡೇಟಾವನ್ನು ಮಾರ್ಪಡಿಸಲು ಆ್ಯಪ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ಸಂಪರ್ಕ ಡೇಟಾವನ್ನು ಅಳಿಸಲು ಆ್ಯಪ್ಗಳಿಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"ಕರೆಯ ಲಾಗ್ ಓದಿ"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಕರೆಯ ಇತಿಹಾಸ ಓದಬಹುದು."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"ಕರೆ ಲಾಗ್ ಬರೆಯಿರಿ"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"ಹೆಚ್ಚುವರಿ ಸ್ಥಳ ಪೂರೈಕೆದಾರರ ಆದೇಶಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"ಹೆಚ್ಚಿನ ಸ್ಥಳ ಪೂರೈಕೆದಾರ ಆದೇಶಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು GPS ಅಥವಾ ಇತರ ಸ್ಥಳ ಮೂಲಗಳ ಕಾರ್ಯಾಚರಣೆಯಲ್ಲಿ ಮಧ್ಯ ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸಬಹುದು."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"ಮುನ್ನೆಲೆಯಲ್ಲಿ ಮಾತ್ರ ನಿಖರವಾದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಮುಂಭಾಗದಲ್ಲಿರುವಾಗ ಮಾತ್ರ ನಿಮ್ಮ ನಿಖರ ಸ್ಥಳವನ್ನು ಪಡೆಯಬಹುದು. ಈ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"ಮುನ್ನೆಲೆಯಲ್ಲಿ ಮಾತ್ರ ಅಂದಾಜು ಸ್ಥಳವನ್ನು (ನೆಟ್ವರ್ಕ್-ಆಧಾರಿತ) ಪ್ರವೇಶಿಸಿ"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"ಈ ಆ್ಯಪ್ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳಂತಹ ನೆಟ್ವರ್ಕ್ ಮೂಲಗಳ ಆಧಾರದ ಮೇಲೆ ಪಡೆಯಬಹುದು, ಆದರೆ ಆ್ಯಪ್ ಮುನ್ನೆಲೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ. ಈ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳಂತಹ ನೆಟ್ವರ್ಕ್ ಮೂಲಗಳ ಆಧಾರದ ಮೇಲೆ ಪಡೆಯಬಹುದು, ಆದರೆ ಅದು ಅಪ್ಲಿಕೇಶನ್ ಮುನ್ನೆಲೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ. ಅವುಗಳನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಸಾಧ್ಯವಾಗಲು ಈ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಅವು ಲಭ್ಯವಿರಬೇಕು."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"ಈ ಆ್ಯಪ್ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳಂತಹ ನೆಟ್ವರ್ಕ್ ಮೂಲಗಳ ಆಧಾರದ ಮೇಲೆ ಪಡೆಯಬಹುದು, ಆದರೆ ಆ್ಯಪ್ ಮುನ್ನೆಲೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ. ಈ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"ಈ ಆ್ಯಪ್ ಮುಂಭಾಗದಲ್ಲಿರುವಾಗ ಮಾತ್ರ ನಿಮ್ಮ ನಿಖರ ಸ್ಥಳವನ್ನು ಪಡೆಯಬಲ್ಲದು. ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಬಳಸಲು ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು. ಇದು ಬ್ಯಾಟರಿ ಬಳಕೆಯನ್ನು ಹೆಚ್ಚಿಸಬಹುದು."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"ಮುನ್ನೆಲೆಯಲ್ಲಿ ಮಾತ್ರ ಅಂದಾಜು ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"ಈ ಆ್ಯಪ್ ಮುನ್ನೆಲೆಯಲ್ಲಿರುವಾಗ ಮಾತ್ರ ನಿಮ್ಮ ಅಂದಾಜು ಸ್ಥಳವನ್ನು ಪಡೆಯಬಲ್ಲದು. ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"ಇದನ್ನು ಅಂದಾಜು ಅಥವಾ ನಿಖರವಾದ ಸ್ಥಳ ಪ್ರವೇಶಕ್ಕೆ ಹೆಚ್ಚುವರಿಯಾಗಿ ಅನುಮತಿಸಿದರೆ, ಆ್ಯಪ್ ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿರುವಾಗ ಅದು ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"ಈ ಆ್ಯಪ್ ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುವಾಗ ಸ್ಥಳದ ಜೊತೆಗೆ ಮುನ್ನೆಲೆಯಲ್ಲಿನ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"ನಿಮ್ಮ ಆಡಿಯೊ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"ವಾಲ್ಯೂಮ್ ರೀತಿಯ ಮತ್ತು ಔಟ್ಪುಟ್ಗಾಗಿ ಯಾವ ಸ್ಪೀಕರ್ ಬಳಸಬೇಕು ಎಂಬ ರೀತಿಯ ಜಾಗತಿಕ ಆಡಿಯೊ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ಆಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಬ್ಲೂಟೂತ್ನ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ವೀಕ್ಷಿಸಲು ಮತ್ತು ಜೋಡಿ ಮಾಡಿರುವ ಸಾಧನಗಳೊಂದಿಗೆ ಸಂಪರ್ಕಗಳನ್ನು ಕಲ್ಪಿಸಲು ಹಾಗೂ ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಬ್ಲೂಟೂತ್ನ ಕಾನ್ಫಿಗರೇಶನ್ ವೀಕ್ಷಿಸಲು ಮತ್ತು ಜೋಡಿಸಿರುವ ಸಾಧನಗಳೊಂದಿಗೆ ಸಂಪರ್ಕಗಳನ್ನು ಮಾಡಲು ಮತ್ತು ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ಫೋನ್ನಲ್ಲಿ ಬ್ಲೂಟೂತ್ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ವೀಕ್ಷಿಸಲು ಮತ್ತು ಜೋಡಿ ಮಾಡಿರುವ ಸಾಧನಗಳೊಂದಿಗೆ ಸಂಪರ್ಕಗಳನ್ನು ಕಲ್ಪಿಸಲು ಹಾಗೂ ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ಸಮೀಪ ಕ್ಷೇತ್ರ ಸಂವಹನವನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"ಸಮೀಪದ ಕ್ಷೇತ್ರ ಸಂವಹನ (NFC) ಟ್ಯಾಗ್ಗಳು, ಕಾರ್ಡ್ಗಳು, ಮತ್ತು ಓದುಗರನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
@@ -1257,7 +1258,7 @@
<item msgid="9177085807664964627">"VPN"</item>
</string-array>
<string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ಅಪರಿಚಿತ ನೆಟ್ವರ್ಕ್ ಪ್ರಕಾರ"</string>
- <string name="accept" msgid="5447154347815825107">"ಸ್ವೀಕರಿಸು"</string>
+ <string name="accept" msgid="5447154347815825107">"ಸ್ವೀಕರಿಸಿ"</string>
<string name="decline" msgid="6490507610282145874">"ನಿರಾಕರಿಸಿ"</string>
<string name="select_character" msgid="3352797107930786979">"ಅಕ್ಷರವನ್ನು ಸೇರಿಸಿ"</string>
<string name="sms_control_title" msgid="4748684259903148341">"SMS ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ಫೈಲ್ಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="pin_target" msgid="8036028973110156895">"ಪಿನ್ ಮಾಡು"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"ಅನ್ಪಿನ್"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ಡೆಮೋ ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ..."</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"ಈ ಮುಂದಿನ ಐಟಂಗಳನ್ನು "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ನಲ್ಲಿ ಅಪ್ಡೇಟ್ ಮಾಡುವುದೇ: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ಮತ್ತು <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"ಉಳಿಸಿ"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"ಬೇಡ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"ಸದ್ಯಕ್ಕೆ ಬೇಡ"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"ಎಂದೂ ಇಲ್ಲ"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"ಅಪ್ಡೇಟ್"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"ಮುಂದುವರಿಯಿರಿ"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"ಪಾಸ್ವರ್ಡ್"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ಸ್ಪ್ಲಿಟ್-ಸ್ಕ್ರೀನ್ ಟಾಗಲ್ ಮಾಡಿ"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ಲಾಕ್ ಸ್ಕ್ರೀನ್"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ಸ್ಕ್ರೀನ್ಶಾಟ್"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"ಪಾಪ್-ಅಪ್ ಸ್ಪೇಸ್ ವಿಂಡೋದಲ್ಲಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಆ್ಯಪ್."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಆ್ಯಪ್ನ ಶೀರ್ಷಿಕೆಯ ಪಟ್ಟಿ."</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index c6caedf..95cd444 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"직장 프로필 관리 앱이 없거나 손상되어 직장 프로필 및 관련 데이터가 삭제되었습니다. 도움이 필요한 경우 관리자에게 문의하세요."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"직장 프로필을 이 기기에서 더 이상 사용할 수 없습니다."</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"비밀번호 입력을 너무 많이 시도함"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"관리자가 기기를 개인용으로 전환했습니다."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"관리되는 기기"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"조직에서 이 기기를 관리하며 네트워크 트래픽을 모니터링할 수도 있습니다. 자세한 내용을 보려면 탭하세요."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"기기가 삭제됩니다."</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"앱에서 브로드캐스트가 끝난 후에도 남아 있는 스티키 브로드캐스트를 허용합니다. 지나치게 사용하면 Android TV 기기에서 메모리를 너무 많이 사용하여 기기가 불안정해지거나 속도가 저하될 수 있습니다."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"앱이 브로드캐스트가 끝난 후에 남은 브로드캐스트를 보낼 수 있도록 허용합니다. 앱을 지나치게 사용하면 휴대전화에서 메모리를 너무 많이 사용하도록 하여 속도를 저하시키거나 불안정하게 만들 수 있습니다."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"연락처 읽기"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"특정인과 전화, 이메일 또는 기타 수단으로 연락한 빈도를 포함하여 사용자 태블릿에 저장된 연락처에 대한 데이터를 앱이 읽도록 허용합니다. 이 권한을 사용하면 앱이 연락처 데이터를 저장할 수 있으며, 악성 앱이 사용자 모르게 연락처 데이터를 공유할 수도 있습니다."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"특정인과 전화, 이메일 또는 기타 방법으로 연락한 빈도를 비롯하여 Android TV 기기에 저장된 연락처에 관한 데이터를 앱이 읽도록 허용합니다. 이 권한을 사용하면 앱이 연락처 데이터를 저장할 수 있으며, 악성 앱이 사용자가 모르게 연락처 데이터를 공유할 수도 있습니다."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"특정인과 전화, 이메일 또는 기타 수단으로 연락한 빈도를 포함하여 사용자 휴대전화에 저장된 연락처에 대한 데이터를 앱이 읽도록 허용합니다. 이 권한을 사용하면 앱이 연락처 데이터를 저장할 수 있으며, 악성 앱이 사용자 모르게 연락처 데이터를 공유할 수도 있습니다."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"태블릿에 저장된 연락처에 관한 데이터를 앱이 읽도록 허용합니다. 또한 앱은 태블릿에서 연락처가 생성된 계정에도 액세스할 수 있습니다. 여기에는 설치한 앱에서 생성한 계정이 포함될 수 있습니다. 이 권한을 사용하면 앱이 연락처 데이터를 저장할 수 있으며, 악성 앱이 사용자가 모르게 연락처 데이터를 공유할 수도 있습니다."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Android TV 기기에 저장된 연락처에 관한 데이터를 앱이 읽도록 허용합니다. 또한 앱은 Android TV 기기에서 연락처가 생성된 계정에도 액세스할 수 있습니다. 여기에는 설치한 앱에서 생성한 계정이 포함될 수 있습니다. 이 권한을 사용하면 앱이 연락처 데이터를 저장할 수 있으며, 악성 앱이 사용자가 모르게 연락처 데이터를 공유할 수도 있습니다."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"휴대전화에 저장된 연락처에 관한 데이터를 앱이 읽도록 허용합니다. 또한 앱은 휴대전화에서 연락처가 생성된 계정에도 액세스할 수 있습니다. 여기에는 설치한 앱에서 생성한 계정이 포함될 수 있습니다. 이 권한을 사용하면 앱이 연락처 데이터를 저장할 수 있으며, 악성 앱이 사용자가 모르게 연락처 데이터를 공유할 수도 있습니다."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"연락처 수정"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"특정인과 전화, 이메일 또는 기타 수단으로 연락한 빈도를 포함하여 사용자 태블릿에 저장된 연락처에 대한 데이터를 앱이 수정할 수 있도록 허용합니다. 이 권한을 사용하면 앱이 연락처 데이터를 삭제할 수 있습니다."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"특정인과 전화, 이메일 또는 기타 방법으로 연락한 빈도를 비롯하여 Android TV 기기에 저장된 연락처에 관한 데이터를 앱이 수정하도록 허용합니다. 이 권한을 사용하면 앱에서 연락처 데이터를 삭제할 수 있습니다."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"특정인과 전화, 이메일 또는 기타 수단으로 연락한 빈도를 포함하여 사용자 휴대전화에 저장된 연락처에 대한 데이터를 앱이 수정할 수 있도록 허용합니다. 이 권한을 사용하면 앱이 연락처 데이터를 삭제할 수 있습니다."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"태블릿에 저장된 연락처에 관한 데이터를 앱이 수정하도록 허용합니다. 이 권한을 사용하면 앱에서 연락처 데이터를 삭제할 수 있습니다."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Android TV 기기에 저장된 연락처에 관한 데이터를 앱이 수정하도록 허용합니다. 이 권한을 사용하면 앱에서 연락처 데이터를 삭제할 수 있습니다."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"휴대전화에 저장된 연락처에 관한 데이터를 앱이 수정하도록 허용합니다. 이 권한을 사용하면 앱에서 연락처 데이터를 삭제할 수 있습니다."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"통화 기록 읽기"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"이 앱은 통화 기록을 읽을 수 있습니다."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"통화 기록 쓰기"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"추가 위치 제공업체 명령에 접근"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"앱이 추가 위치 정보 제공 기능의 명령에 접근하도록 허용합니다. 이 경우 앱이 GPS 또는 기타 위치 소스의 작동을 방해할 수 있습니다."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"포그라운드에서만 정확한 위치에 액세스"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"이 앱은 포그라운드에 있을 때만 나의 정확한 위치를 알 수 있습니다. 앱에서 위치 서비스를 사용하려면 휴대전화에서 위치 서비스가 사용 설정되어 있으며 사용할 수 있어야 합니다. 배터리 사용량이 늘어날 수 있습니다."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"포그라운드에서만 대략적인 위치(네트워크 기반)에 액세스"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"앱이 포그라운드에 있을 때만 휴대전화 기지국과 Wi-Fi 네트워크 등의 네트워크 소스를 바탕으로 사용자의 위치를 파악할 수 있습니다. 앱에서 위치 서비스를 사용하려면 태블릿에서 위치 서비스가 켜져 있으며 사용 가능해야 합니다."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"앱이 포그라운드에 있을 때만 휴대전화 기지국과 Wi-Fi 네트워크 등의 네트워크 소스를 바탕으로 사용자의 위치를 파악할 수 있습니다. 앱에서 위치 서비스를 사용하려면 Android TV 기기에서 위치 서비스를 지원하며 사용 설정되어 있어야 합니다."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"앱이 포그라운드에 있을 때만 휴대전화 기지국과 Wi-Fi 네트워크 등의 네트워크 소스를 바탕으로 사용자의 위치를 파악할 수 있습니다. 앱에서 위치 서비스를 사용하려면 휴대전화에서 위치 서비스가 켜져 있으며 사용 가능해야 합니다."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"이 앱은 포그라운드에 있을 때만 나의 정확한 위치를 확인할 수 있습니다. 앱에서 위치 서비스를 사용하려면 기기에서 위치 서비스가 지원되며 사용 설정되어 있어야 합니다. 배터리 사용량이 늘어날 수 있습니다."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"포그라운드에서만 대략적인 위치에 액세스"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"이 앱은 포그라운드에 있을 때만 나의 대략적인 위치를 확인할 수 있습니다. 앱에서 위치 서비스를 사용하려면 기기에서 위치 서비스가 지원되며 사용 설정되어 있어야 합니다."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"백그라운드에서 위치 정보 액세스"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"이 권한이 대략적인 위치 정보 또는 정확한 위치 정보 액세스 권한에 추가적으로 부여되면 앱이 백그라운드에서 실행되는 동안 위치에 액세스할 수 있습니다."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"이 앱이 포그라운드뿐만 아니라 백그라운드에서 실행되는 동안에도 위치에 액세스할 수 있습니다."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"오디오 설정 변경"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"앱이 음량이나 출력을 위해 사용하는 스피커 등 전체 오디오 설정을 변경할 수 있도록 허용합니다."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"오디오 녹음"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"앱이 태블릿의 블루투스 설정을 확인하고 페어링된 기기에 연결하며 연결을 수락할 수 있도록 허용합니다."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"앱이 Android TV 기기에서 블루투스 설정을 보고 페어링된 기기에 연결하며 페어링된 기기와의 연결을 수락하도록 허용합니다."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"앱에서 휴대전화의 블루투스 설정을 확인하고 등록된 디바이스에 연결하며 연결을 수락할 수 있습니다."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"NFC(Near Field Communication) 제어"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"앱이 NFC(근거리 무선 통신) 태그, 카드 및 리더와 통신할 수 있도록 허용합니다."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"화면 잠금 사용 중지"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>에 연결됨"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"파일을 확인하려면 탭하세요."</string>
<string name="pin_target" msgid="8036028973110156895">"고정"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"고정 해제"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"앱 정보"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"데모 시작 중..."</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"에서 <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> 및 <xliff:g id="TYPE_2">%3$s</xliff:g> 업데이트"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"저장"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"사용 안함"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"나중에"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"사용 안함"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"업데이트"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"계속"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"비밀번호"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"화면 분할 모드 전환"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"잠금 화면"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"스크린샷"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"팝업 창의 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>의 자막 표시줄입니다."</string>
</resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 341c996..c247e9f 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Жумуш профилинин башкаруучу колдонмосу жок же бузулгандыктан, жумуш профилиңиз жана ага байланыштуу дайындар жок кылынды. Жардам алуу үчүн администраторуңузга кайрылыңыз."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Жумуш профилиңиз бул түзмөктөн жок кылынды"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Өтө көп жолу сырсөздү киргизүү аракети жасалды"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Админ түзмөктөн жеке колдонуу үчүн баш тартты"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Түзмөктү ишкана башкарат"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ишканаңыз бул түзмөктү башкарат жана тармак трафигин көзөмөлдөшү мүмкүн. Чоо-жайын көрүү үчүн таптап коюңуз."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Түзмөгүңүз тазаланат"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Колдонмого таркатма аяктагандан кийин калган кадалган таркатмаларды жөнөтүүгө уруксат берет. Ашыкча колдонуу Android TV түзмөгүңүздүн өтө көп эстутумду пайдалануу менен жай же туруксуз иштешине алып келиши мүмкүн."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Колдонмого берүү токтогондон кийин улантыла берүүчү жабышкак берүүлөрдү жөнөтүү уруксатын берет. Муну ашыкча колдонуу, эстутумду өтө көп пайдаланууга алып келип, телефондун жай же туруксуз иштөөсүнүнө себепкер болушу мүмкүн."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"байланыштарыңызды окуу"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Колдонмо планшетиңиздеги байланыштар, ошондой эле белгилүү бир адамдар менен канчалык көп чалышып, кат жазышып жана башка жолдор менен байланышып жаткандыгыңыз тууралуу маалыматты көрүп, сактай алат. Мындай уруксатты алган колдонмолор байланыштар тууралуу маалыматты сактай алышат, ал эми зыянкеч программалар байланыштар тууралуу маалыматты алдын ала эскертүүсүз бөлүшүүсү мүмкүн."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Колдонмого Android TV түзмөгүңүздө сакталган байланыштар тууралуу дайындарды, анын ичинде белгилүү бир байланыштарга канча убакытта бир чалып, электрондук кат жөнөтүп же башка ыкмалар менен баарлашканыңызды өзгөртүүгө колдонмого уруксат берет. Бул уруксат колдонмолорго байланыштарыңыздын дайындарын сактоого уруксат берет жана зыянкеч колдонмолор ал дайындарды сизге кабарлабастан башкалар менен бөлүшүүсү мүмкүн."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Колдонмо түзмөктөгү байланыштар, ошондой эле белгилүү бир адамдар менен канчалык көп чалышып, кат жазышып жана башка жолдор менен байланышып жаткандыгыңыз тууралуу маалыматты көрүп, сактай алат. Зыянкеч программалар байланыштар тууралуу маалыматты алдын ала эскертүүсүз бөлүшүүсү мүмкүн."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Колдонмо планшетиңизде сакталган байланыштардын дайын-даректерин көрө алат. Мындан тышкары, колдонмолорго планшетиңиздеги байланыштар камтылган аккаунттар да жеткиликтүү болот. Алардын катарына сиз орноткон колдонмолордо түзүлгөн аккаунттар кириши мүмкүн. Байланыштардын чоо-жайын сактоо мүмкүнчүлүгүнө ээ болгон зыянкеч программалар ал маалыматты сиздин уруксатыңызсыз башкаларга бериши мүмкүн."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Колдонмо Android TV түзмөгүңүздө сакталган байланыштардын дайын-даректерин көрө алат. Мындан тышкары, колдонмолорго Android TV түзмөгүңүздөгү байланыштар камтылган аккаунттар да жеткиликтүү болот. Алардын катарына сиз орноткон колдонмолордо түзүлгөн аккаунттар кириши мүмкүн. Байланыштардын чоо-жайын сактоо мүмкүнчүлүгүнө ээ болгон зыянкеч программалар ал маалыматты сиздин уруксатыңызсыз башкаларга бериши мүмкүн."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Колдонмо телефонуңузда сакталган байланыштардын дайын-даректерин көрө алат. Мындан тышкары, колдонмолорго телефонуңуздагы байланыштар камтылган аккаунттар да жеткиликтүү болот. Алардын катарына сиз орноткон колдонмолордо түзүлгөн аккаунттар кириши мүмкүн. Байланыштардын чоо-жайын сактоо мүмкүнчүлүгүнө ээ болгон зыянкеч программалар ал маалыматты сиздин уруксатыңызсыз башкаларга бериши мүмкүн."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"байланыштарыңызды өзгөртүү"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Колдонмо планшетиңиздеги байланыштар, ошондой эле белгилүү бир адамдар менен канчалык көп чалышып, кат жазышып жана башка жолдор менен байланышып жаткандыгыңыз тууралуу маалыматты өзгөртө алат. Мындай уруксатты алган колдонмолор байланыштар тууралуу маалыматты жок кыла алышат."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Android TV түзмөгүңүздө сакталган байланыштар тууралуу дайындарды, анын ичинде белгилүү бир байланыштарга канча убакытта бир чалып, электрондук кат жөнөтүп же башка ыкмалар менен баарлашканыңызды өзгөртүүгө колдонмого уруксат берет. Бул уруксат колдонмолорго байланыштардын дайындарын өчүрүүгө уруксат берет."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Колдонмо телефонуңуздагы байланыштар, ошондой эле белгилүү бир адамдар менен канчалык көп чалышып, кат жазышып жана башка жолдор менен байланышып жаткандыгыңыз тууралуу маалыматты өзгөртө алат. Мындай уруксатты алган колдонмолор байланыштар тууралуу маалыматты жок кыла алышат."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Колдонмо планшетиңизде сакталган байланыштарыңыздын дайын-даректерин өзгөртө алат. Мындан тышкары, бул уруксат колдонмолорго байланыштардын дайын-даректерин өчүрүүгө уруксат берет."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Колдонмо Android TV түзмөгүңүздө сакталган байланыштарыңыздын дайын-даректерин өзгөртө алат. Мындан тышкары, бул уруксат колдонмолорго байланыштардын дайын-даректерин өчүрүүгө уруксат берет."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Колдонмо телефонуңузда сакталган байланыштарыңыздын дайын-даректерин өзгөртө алат. Мындан тышкары, бул уруксат колдонмолорго байланыштардын дайын-даректерин өчүрүүгө уруксат берет."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"чалуулар тизмегин окуу"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Бул колдонмо чалууларыңыздын таржымалын окуй алат."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"чалуулар тизмегин жаздыруу"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"жайгашкан жерди аныктагычтын кошумча буйруктарын пайдалануу"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Колдонмого жайгашкан жерди табуучу кошумча жабдуучулардын буйруктарын колдонуу мүмкүнчүлүгүн берет. Ушуну менен колдонмо GPS\'тин ишине жана башка жайгашкан жерлерди аныктоо кызматтарына кийлигише алат."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"так аныкталган жайгашкан жерге активдүү режимде гана кирүүгө уруксат берүү"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Бул колдонмонун активдүү режимде гана жайгашкан жериңиздин дайындарын алууга мүмкүнчүлүгү бар. Колдонмо бул кызматтарды пайдаланышы үчүн аларды күйгүзүп, телефонуңузга туташтырып коюшуңуз керек. Ушуну менен батареянын кубаты көбүрөөк сарпталышы мүмкүн."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"болжолдуу аныкталган жайгашкан жерге (тармактын негизинде) автивдүү режимде гана кирүүгө уруксат берүү"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Бул колдонмо байланыш мунаралары жана Wi-Fi сыяктуу тармактык булактар аркылуу жайгашкан жериңизди аныктай алат, бирок ал үчүн колдонмо ачылып турушу керек. Колдонмо бул кызматтарды пайдаланышы үчүн, аларды күйгүзүп, планшетиңизге туташтырып коюшуңуз керек."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Бул колдонмо байланыш мунаралары жана Wi-Fi сыяктуу тармактык булактар аркылуу жайгашкан жериңизди аныктай алат, бирок ал үчүн колдонмо ачылып турушу керек. Колдонмо бул кызматтарды пайдаланышы үчүн жайгашкан жерди аныктоо кызматтарын күйгүзүп, Android TV түзмөгүңүзгө туташтырып коюшуңуз керек."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Бул колдонмо байланыш мунаралары жана Wi-Fi сыяктуу тармактык булактар аркылуу жайгашкан жериңизди аныктай алат, бирок ал үчүн колдонмо ачылып турушу керек. Колдонмо бул кызматтарды пайдаланышы үчүн, аларды күйгүзүп, телефонуңузга туташтырып коюшуңуз керек."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Колдонмо кайда жүргөнүңүздү активдүү режимде гана аныктай алат. Ал үчүн түзмөгүңүздө жайгашкан жерди аныктоо кызматын иштетип, колдонмого кайда жүргөнүңүздү аныктоого уруксат беришиңиз керек. Батареяңыз тез отуруп калышы мүмкүн."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"кайда жүргөнүмдү активдүү режимде божомолдоого уруксат берүү"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Колдонмо кайда жүргөнүңүздү активдүү режимде гана аныктай алат. Ал үчүн түзмөгүңүздө жайгашкан жерди аныктоо кызматын иштетип, колдонмого кайда жүргөнүңүздү аныктоого уруксат беришиңиз керек."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"жайгашкан жерди фондо аныктоо"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Эгер колдонмого жайгашкан жерди болжолдуу же так аныктоого уруксат берилсе, ал фондо иштеп жатып эле жайгашкан жерди аныктап турат."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Колдонмо кайда жүргөнүңүздү активдүү режимде гана эмес, фондук режимде да аныктай алат."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"аудио жөндөөлөрүңүздү өзгөртүңүз"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Колдонмого үн деңгээли жана кайсы динамик аркылуу үн чыгарылышы керек сыяктуу түзмөктүн аудио тууралоолорун өзгөртүүгө уруксат берет."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"аудио жаздыруу"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Колдонмого планшеттин Bluetooth конфигурацияларын көрүү, жупталган түзмөктөр менен байланыш түзүү жана кабыл алуу уруксатын берет."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Android TV түзмөгүңүздөгү Bluetooth конфигурациясын көрүп, жупташтырылган түзмөктөргө туташууга жана туташуу сурамын кабыл алууга колдонмого уруксат берет."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Колдонмого телефондун Bluetooth конфигурацияларын көрүү, жупташкан түзмөктөр менен туташуу түзүү жана кабыл алуу уруксатын берет."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication көзөмөлү"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Колдонмого Жакынкы аралыкта байланышуу (NFC) белгилери, карталары жана окугучтары менен байланышуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"экранды бөгөттөөнү өчүрүү"</string>
@@ -605,8 +606,8 @@
<string name="permdesc_register_call_provider" msgid="4201429251459068613">"Колдонмого жаңы телеком туташууларын каттоо мүмкүнчүлүгүн берет."</string>
<string name="permlab_connection_manager" msgid="3179365584691166915">"телеком туташууларын башкаруу"</string>
<string name="permdesc_connection_manager" msgid="1426093604238937733">"Колдонмого телеком туташууларын башкаруу мүмкүнчүлүгүн берет."</string>
- <string name="permlab_bind_incall_service" msgid="5990625112603493016">"чалуу экраны менен байланыштыруу"</string>
- <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Колдонмого чалуу экраны качан жана кандай көрүнө тургандыгын башкаруу мүмкүнчүлүгүн берет."</string>
+ <string name="permlab_bind_incall_service" msgid="5990625112603493016">"сүйлөшүп жатканда экранды башкара аласыз"</string>
+ <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Сүйлөшүп жатканда экранды башкара аласыз."</string>
<string name="permlab_bind_connection_service" msgid="5409268245525024736">"телефония кызматтары"</string>
<string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Колдонмого чалууларды жасоо/кабыл алуу үчүн телефония кызматтары менен байланышууга уруксат берет."</string>
<string name="permlab_control_incall_experience" msgid="6436863486094352987">"чалуу ичиндеги колдонуучу тажрыйбасын камсыз кылуу"</string>
@@ -827,7 +828,7 @@
<string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Токтотуу"</string>
<string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Артка түрүү"</string>
<string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"Алдыга түрүү"</string>
- <string name="emergency_calls_only" msgid="3057351206678279851">"Өзгөчө кырдаалда гана чалууга болот"</string>
+ <string name="emergency_calls_only" msgid="3057351206678279851">"Кырсыктаганда гана чалуу"</string>
<string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Тармак кулпуланган"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"SIM-карта PUK-бөгөттө."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Колдонуучунун нускамасын караңыз же Кардарларды тейлөө борборуна кайрылыңыз."</string>
@@ -1757,8 +1758,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Администраторуңуз жаңыртып койгон"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Администраторуңуз жок кылып салган"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ЖАРАЙТ"</string>
- <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Батареянын кубатынын мөөнөтүн узартуу үчүн Батареяны үнөмдөгүч режими төмөнкүлөрдү аткарат:\n·Түнкү режимди күйгүзөт\n·Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт\n\n"<annotation id="url">"Кеңири маалымат"</annotation></string>
- <string name="battery_saver_description" msgid="7618492104632328184">"Батареянын кубатынын мөөнөтүн узартуу үчүн Батареяны үнөмдөгүч режими төмөнкүлөрдү аткарат:\n·Түнкү режимди күйгүзөт\n·Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Батареяны үнөмдөө үчүн Батареяны үнөмдөгүч:\n·Караңгы теманы күйгүзөт\n·Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт\n\n"<annotation id="url">"Кеңири маалымат"</annotation></string>
+ <string name="battery_saver_description" msgid="7618492104632328184">"Батареяны үнөмдөө үчүн Батареяны үнөмдөгүч режими:\n·Караңгы теманы күйгүзөт\n·Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт"</string>
<string name="data_saver_description" msgid="4995164271550590517">"Трафикти үнөмдөө режиминде айрым колдонмолор дайындарды фондо өткөрө алышпайт. Учурда сиз пайдаланып жаткан колдонмо дайындарды жөнөтүп/ала алат, бирок адаттагыдан азыраак өткөргөндүктөн, анын айрым функциялары талаптагыдай иштебей коюшу мүмкүн. Мисалы, сүрөттөр басылмайынча жүктөлбөйт."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Трафикти үнөмдөө режимин иштетесизби?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Күйгүзүү"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> менен туташты"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Файлдарды көрүү үчүн таптап коюңуз"</string>
<string name="pin_target" msgid="8036028973110156895">"Кадоо"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Кадоодон алып коюу"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Колдонмо тууралуу"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Демо режим башталууда…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" кызматындагы төмөнкүлөр жаңыртылсынбы: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> жана <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Сактоо"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Жок, рахмат"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Азыр эмес"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Эч качан"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Жаңыртуу"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Улантуу"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"сырсөз"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Экранды бөлүүнү күйгүзүү же өчүрүү"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Кулпуланган экран"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Скриншот"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу Калкыма терезеде көрүндү."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунун маалымат тилкеси."</string>
</resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index e0da206..45e7c44d 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"ບໍ່ມີແອັບຜູ້ເບິ່ງແຍງລະບົບໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ ຫຼື ເສຍຫາຍ. ຜົນກໍຄື, ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ ແລະ ຂໍ້ມູນທີ່ກ່ຽວຂ້ອງຂອງທ່ານຖືກລຶບອອກແລ້ວ. ໃຫ້ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບການຊ່ວຍເຫຼືອ."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານບໍ່ສາມາດໃຊ້ໄດ້ໃນອຸປະກອນນີ້ອີກຕໍ່ໄປ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ລອງໃສ່ລະຫັດຜ່ານຫຼາຍເທື່ອເກີນໄປ"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"ອຸປະກອນທີ່ຍົກເລີກແລ້ວສຳລັບການໃຊ້ສ່ວນບຸກຄົນ"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"ອຸປະກອນມີການຈັດການ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ອົງກອນຂອງທ່ານຈັດການອຸປະກອນນີ້ ແລະ ອາດກວດສອບທຣາບຟິກເຄືອຂ່າຍນຳ. ແຕະເພື່ອເບິ່ງລາຍລະອຽດ."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"ອຸປະກອນຂອງທ່ານຈະຖືກລຶບ"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"ອະນຸຍາດໃຫ້ແອັບສົ່ງການອອກອາກາດແບບຍຶດຕິດ, ເຊິ່ງຍັງຄົງຢູ່ຫຼັງຈາກການອອກອາກາດສິ້ນສຸດ. ການໃຊ້ເກີນອາດຈະເຮັດໃຫ້ອຸປະກອນ Android TV ຂອງທ່ານຊ້າລົງ ຫຼື ບໍ່ໝັ້ນຄົງເນື່ອງຈາກມັນໃຊ້ໜ່ວຍຄວາມຈຳຫຼາຍເກີນໄປ."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນສົ່ງການກະຈາຍສັນຍານແບບຍຶດຕິດ, ທີ່ຍັງຄົງເຫຼືອຫຼັງຈາກການກະຈາຍສັນຍານສິ້ນສຸດລົງ. ການນຳໃຊ້ແບບມະຫາສານອາດເຮັດໃຫ້ໂທລະສັບຊ້າ ຫຼືບໍ່ສະຖຽນ ໂດຍການໃຊ້ໜ່ວຍຄວາມຈຳຫຼາຍເກີນໄປ."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"ອ່ານລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານ"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ່ຕິດຕໍ່ໃນແທັບເລັດຂອງທ່ານ, ຮວມເຖິງຂໍ້ມູນການຈຳນວນການຕິດຕໍ່ຕ່າງໆເຊັ່ນ: ການໂທ, ອີເມວ, ຫຼືຕິດຕໍ່ຫາໃນທາງອື່ນໆກັບບຸກຄົນໃດນຶ່ງໄດ້. ການອະນຸຍາດນີ້ເຮັດໃຫ້ແອັບຯ ສາມາດບັນທຶກຂໍ້ມູນຜູ່ຕິດຕໍ່ຂອງທ່ານ ແລະແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດສົ່ງຕໍ່ຂໍ້ມູນເຫຼົ່ານັ້ນໂດຍທີ່ທ່ານບໍ່ຮູ້ໂຕ."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"ອະນຸຍາດໃຫ້ແອັບອ່ານຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ້ຕິດຕໍ່ຂອງທ່ານທີ່ບັນທຶກໄວ້ຢູ່ໃນອຸປະກອນ Android TV ຂອງທ່ານ, ຮວມທັງຄວາມຖີ່ທີ່ທ່ານໄດ້ໂທ, ອີເມວ ຫຼື ສື່ສານກັບບຸກຄົນສະເພາະດ້ວຍວິທີອື່ນ. ສິດອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຕ່າງໆສາມາດບັນທຶກຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່ຂອງທ່ານ ແລະ ແອັບທີ່ເປັນອັນຕະລາຍອາດສາມາດແບ່ງປັນຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່ໂດຍທີ່ທ່ານບໍ່ຮູ້ໄດ້."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ່ຕິດຕໍ່ທີ່ເກັບໄວ້ໃນໂທລະສັບຂອງທ່ານ ຮວມເຖິງຄວາມຖີ່ການໂທ, ການສົ່ງສົ່ງອີເມວ ຫຼືການສື່ສານໃນຮູບແບບອື່ນກັບບຸກຄົນໃດນຶ່ງ. ການອະນຸຍາດເຮັດໃຫ້ແອັບຯ ສາມາດບັນທຶກຂໍ້ມູນລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານ ແລະແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດເຜີຍແຜ່ຂໍ້ມູນຂອງທ່ານໂດຍທີ່ທ່ານບໍ່ໄດ້ຮັບຮູ້."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"ອະນຸຍາດໃຫ້ແອັບອ່ານຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ້ຕິດຕໍ່ທີ່ບັນທຶກໄວ້ຢູ່ແທັບເລັດຂອງທ່ານ. ນອກຈາກນັ້ນ, ແອັບຕ່າງໆຍັງມີສິດເຂົ້າເຖິງບັນຊີຢູ່ແທັບເລັດຂອງທ່ານທີ່ສ້າງລາຍຊື່ຜູ້ຕິດຕໍ່ໄດ້ນຳ. ນີ້ອາດຮວມເຖິງບັນຊີທີ່ສ້າງຂຶ້ນມາໂດຍແອັບທີ່ທ່ານຕິດຕັ້ງໄວ້ນຳ. ສິດອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຕ່າງໆສາມາດບັນທຶກຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່ຂອງທ່ານ ແລະ ແອັບທີ່ເປັນອັນຕະລາຍອາດແບ່ງປັນຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່ໄດ້ໂດຍທີ່ທ່ານບໍ່ຮູ້ໄດ້."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"ອະນຸຍາດໃຫ້ແອັບອ່ານຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ້ຕິດຕໍ່ທີ່ຈັດເກັບໄວ້ຢູ່ອຸປະກອນ Android TV ຂອງທ່ານ. ນອກຈາກນັ້ນ, ແອັບຕ່າງໆຍັງມີສິດເຂົ້າເຖິງບັນຊີຢູ່ອຸປະກອນ Android TV ຂອງທ່ານທີ່ສ້າງລາຍຊື່ຜູ້ຕິດຕໍ່ໄດ້ນຳ. ນີ້ອາດຮວມເຖິງບັນຊີທີ່ສ້າງຂຶ້ນມາໂດຍແອັບທີ່ທ່ານຕິດຕັ້ງໄວ້ນຳ. ສິດອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຕ່າງໆສາມາດບັນທຶກຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່ຂອງທ່ານ ແລະ ແອັບທີ່ເປັນອັນຕະລາຍອາດແບ່ງປັນຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່ໄດ້ໂດຍທີ່ທ່ານບໍ່ຮູ້ໄດ້."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ອະນຸຍາດໃຫ້ແອັບອ່ານຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ້ຕິດຕໍ່ທີ່ບັນທຶກໄວ້ຢູ່ໂທລະສັບຂອງທ່ານ. ນອກຈາກນັ້ນ, ແອັບຕ່າງໆຍັງມີສິດເຂົ້າເຖິງບັນຊີຢູ່ໂທລະສັບຂອງທ່ານທີ່ສ້າງລາຍຊື່ຜູ້ຕິດຕໍ່ໄດ້ນຳ. ນີ້ອາດຮວມເຖິງບັນຊີທີ່ສ້າງຂຶ້ນມາໂດຍແອັບທີ່ທ່ານຕິດຕັ້ງໄວ້ນຳ. ສິດອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຕ່າງໆສາມາດບັນທຶກຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່ຂອງທ່ານ ແລະ ແອັບທີ່ເປັນອັນຕະລາຍອາດແບ່ງປັນຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່ໄດ້ໂດຍທີ່ທ່ານບໍ່ຮູ້ໄດ້."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"ແກ້ໄຂລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານ"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານທີ່ເກັບໄວ້ໃນແທັບເລັດ ຮວມທັງຄວາມຖີ່ໃນການໂທ, ການສົ່ງອີເມວ ຫຼືການສື່ສານໃນຮູບແບບອື່ນຂອງທ່ານກັບລາຍຊື່ຜູ່ຕິດຕໍ່ໃດນຶ່ງ. ການກຳນົດສິດນີ້ເຮັດໃຫ້ແອັບຯສາມາດລຶບຂໍ້ມູນລາຍຊື່ຜູ່ຕິດຕໍ່ໄດ້."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"ອະນຸຍາດໃຫ້ແອັບແກ້ໄຂຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຕິດຕໍ່ຂອງທ່ານທີ່ບັນທຶກຢູ່ໃນອຸປະກອນ Android TV ທ່ານ, ຮວມທັງຄວາມຖີ່ ທີທ່ານໂທ, ອີເມວ ຫຼື ການສື່ ສານກັບລາຍຊື່ຕິດຕໍ່ສະເພາະໃນຮູບແບບອື່ນນຳ. ສິດອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບສາມາດລຶບຂໍ້ມູນລາຍຊື່ຕິດຕໍ່ໄດ້."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ່ຕິດຕໍ່ ທີ່ບັນທຶກໃນໂທລະສັບຂອງທ່ານ ຮວມທັງຄວາມຖີ່ຂອງການໂທ, ການອີເມວ ຫຼືການຕິດຕໍ່ໃນຮູບແບບອື່ນກັບລາຍຊື່ຜູ່ຕິດຕໍ່ໃດນຶ່ງນຳ. ການອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຯ ສາມາດລຶບຂໍ້ມູນລາຍຊື່ຜູ່ຕິດຕໍ່ໄດ້."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"ອະນຸຍາດໃຫ້ແອັບແກ້ໄຂຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ້ຕິດຕໍ່ທີ່ບັນທຶກໄວ້ຢູ່ແທັບເລັດຂອງທ່ານ. ສິດອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບສາມາດລຶບຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່ອອກໄດ້."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"ອະນຸຍາດໃຫ້ແອັບແກ້ໄຂຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຕິດຕໍ່ຂອງທ່ານທີ່ບັນທຶກຢູ່ໃນອຸປະກອນ Android TV ທ່ານ. ສິດອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບສາມາດລຶບຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່ອອກໄດ້."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"ອະນຸຍາດໃຫ້ແອັບແກ້ໄຂຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ້ຕິດຕໍ່ທີ່ບັນທຶກໄວ້ຢູ່ໂທລະສັບຂອງທ່ານ. ສິດອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບສາມາດລຶບຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່ອອກໄດ້."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"ອ່ານບັນທຶກການໂທ"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"This app can read your call history."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"ຂຽນຂໍ້ມູນການໂທ"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"ເຂົ້າເຖິງຄຳສັ່ງຜູ່ໃຫ້ບໍລິການພິກັດສະຖານທີ່"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"ອະນຸຍາດໃຫ້ແອັບຯເຂົ້າເຖິງຄຳສັ່ງເພີ່ມເຕີມຂອງຜູ່ໃຫ້ບໍລິການສະຖານທີ່. ນີ້ອາດຈະເປັນການເຮັດໃຫ້ແອັບຯ ລົບກວນການເຮັດວຽກຂອງ GPS ຫຼືແຫລ່ງຂໍ້ມູນສະຖານທີ່ອື່ນໆໄດ້."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"ເຂົ້າເຖິງສະຖານທີ່ແນ່ນອນໃນພື້ນໜ້າເທົ່ານັ້ນ"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"ແອັບນີ້ສາມາດຮັບເອົາສະຖານທີ່ແນ່ນອນຂອງທ່ານໄດ້ທຸກເວລາທີ່ມັນຢູ່ໃນພື້ນໜ້າ. ການບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຕ້ອງເປີດຢູ່ ແລະ ສາມາດໃຊ້ໄດ້ໃນໂທລະສັບຂອງທ່ານເພື່ອໃຫ້ແອັບສາມາດໃຊ້ພວກມັນໄດ້. ນີ້ອາດຈະເຮັດໃຫ້ການໃຊ້ແບັດເຕີຣີເພີ່ມຂຶ້ນ."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"ເຂົ້າເຖິງສະຖານທີ່ໂດຍປະມານ (ອ້າງອີງຈາກເຄືອຂ່າຍ) ສະເພາະໃນພື້ນໜ້າ"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"ແອັບນີ້ສາມາດເບິ່ງສະຖານທີ່ຂອງທ່ານໂດຍອ້າງອີງຈາກແຫລ່ງທີ່ມເຄືອຂ່າຍ ເຊັ່ນ: ເສົາສັນຍານໂທລະສັບ ແລະ ເຄືອຂ່າຍ Wi-Fi ໄດ້, ແຕ່ສະເພາະເມື່ອແອັບເຮັດວຽກໂດຍປາກົດຢູ່ໜ້າເທົ່ານັ້ນ. ບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຈະຕ້ອງຖືກເປີດໃຊ້ ແລະ ສາມາດໃຊ້ໄດ້ຢູ່ແທັບເລັດຂອງທ່ານ, ແອັບຈຶ່ງຈະສາມາດໃຊ້ພວກມັນໄດ້."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"ແອັບນີ້ສາມາດດຶງຂໍ້ມູນສະຖານທີ່ຂອງທ່ານໂດຍອ້າງອີງແຫລ່ງຂໍ້ມູນເຄືອຂ່າຍ ເຊັ່ນ: ເສົາສັນຍານໂທລະສັບມືຖື ແລະ ເຄືອຂ່າຍ Wi-Fi, ແຕ່ສະເພາະເມື່ອແອັບຢູ່ໃນພື້ນໜ້າເທົ່ານັ້ນ. ບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຈະຕ້ອງຖືກເປີດໃຊ້ກ່ອນ ແລະ ສາມາດໃຊ້ໄດ້ຢູ່ອຸປະກອນ Android TV ຂອງທ່ານເພື່ອໃຫ້ແອັບສາມາດໃຊ້ພວກມັນໄດ້."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"ແອັບນີ້ສາມາດເບິ່ງສະຖານທີ່ຂອງທ່ານໂດຍອ້າງອີງຈາກແຫລ່ງທີ່ມເຄືອຂ່າຍ ເຊັ່ນ: ເສົາສັນຍານໂທລະສັບ ແລະ ເຄືອຂ່າຍ Wi-Fi ໄດ້, ແຕ່ສະເພາະເມື່ອແອັບເຮັດວຽກໂດຍປາກົດຢູ່ໜ້າເທົ່ານັ້ນ. ບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຈະຕ້ອງຖືກເປີດໃຊ້ ແລະ ສາມາດໃຊ້ໄດ້ຢູ່ໂທລະສັບຂອງທ່ານ, ແອັບຈຶ່ງຈະສາມາດໃຊ້ພວກມັນໄດ້."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"ແອັບນີ້ສາມາດຮັບເອົາສະຖານທີ່ແນ່ນອນຂອງທ່ານໄດ້ທຸກເວລາທີ່ມັນຢູ່ໃນພື້ນໜ້າ. ການບໍລິການສະຖານທີ່ຕ້ອງເປີດຢູ່ ແລະ ສາມາດໃຊ້ໄດ້ໃນອຸປະກອນຂອງທ່ານເພື່ອໃຫ້ແອັບສາມາດໃຊ້ພວກມັນໄດ້. ນີ້ອາດຈະເຮັດໃຫ້ການໃຊ້ແບັດເຕີຣີເພີ່ມຂຶ້ນ."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"ເຂົ້າເຖິງສະຖານທີ່ໂດຍປະມານເມື່ອຢູ່ໃນພື້ນໜ້າເທົ່ານັ້ນ"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"ແອັບນີ້ສາມາດລະບຸສະຖານທີ່ໂດຍປະມານການຂອງທ່ານໄດ້ສະເພາະເມື່ອມັນຢູ່ໃນພື້ນຫຼັງເທົ່ານັ້ນ. ຈະຕ້ອງເປີດໃຊ້ບໍລິການສະຖານທີ່ ແລະ ໃຊ້ໄດ້ຢູ່ລົດຂອງທ່ານເພື່ອໃຫ້ແອັບສາມາດໃຊ້ພວກມັນໄດ້."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"ເຂົ້າເຖິງສະຖານທີ່ໃນພື້ນຫຼັງ"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"ຖ້າອະນຸຍາດສິ່ງນີ້ນອກຈາກການເຂົ້າເຖິງສະຖານທີ່ໂດຍປະມານ ຫຼື ທີ່ແນ່ນອນ ແອັບສາມາດເຂົ້າເຖິງສະຖານທີ່ໄດ້ໃນຂະນະທີ່ເປີດໃຊ້ໃນພື້ນຫຼັງ."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"ແອັບນີ້ສາມາດເຂົ້າເຖິງສະຖານທີ່ໃນເວລາເຮັດວຽກໃນພື້ນຫຼັງ, ນອກເໜືອໄປຈາກການເຂົ້າເຖິງສະຖານທີ່ໃນພື້ນໜ້າ."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"ປ່ຽນການຕັ້ງຄ່າສຽງຂອງທ່ານ"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂການຕັ້ງຄ່າສຽງສ່ວນກາງ ເຊັ່ນ: ລະດັບສຽງ ແລະລຳໂພງໃດທີ່ຖືກໃຊ້ສົ່ງສຽງອອກ."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ບັນທຶກສຽງ"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ອະນຸຍາດໃຫ້ແອັບຯເບິ່ງການຕັ້ງຄ່າຂອງ Bluetooth ໃນແທັບເລັດ ຕະຫຼອດຈົນເຊື່ອມຕໍ່ ແລະຍອມຮັບການເຊື່ອມຕໍ່ກັບອຸປະກອນທີ່ຈັບຄູ່ກັນແລ້ວ."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"ອະນຸຍາດໃຫ້ແອັບເບິ່ງການຕັ້ງຄ່າ Bluetooth ຢູ່ອຸປະກອນ Android TV ຂອງທ່ານ ແລະ ຕອບຮັບການເຊື່ອມຕໍ່ກັບອຸປະກອນທີ່ຈັບຄູ່ໄວ້."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ອະນຸຍາດໃຫ້ແອັບຯເບິ່ງການຕັ້ງຄ່າຂອງ Bluetooth ໃນໂທລະສັບ, ຮວມທັງໃຫ້ສ້າງ ແລະຮັບການເຊື່ອມຕໍ່ຈາກອຸປະກອນທີ່ຈັບຄູ່ກັນ."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ຄວບຄຸມ Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"ອະນຸຍາດໃຫ້ແອັບຯຕິດຕໍ່ສື່ສານກັບປ້າຍກຳກັບ, ບັດ ແລະໂຕອ່ານຂອງການສື່ສານໄລຍະສັ້ນ (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"ປິດການລັອກໜ້າຈໍ"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"ເຊື່ອມຕໍ່ກັບ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ແລ້ວ"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ແຕະເພື່ອເບິ່ງໄຟລ໌"</string>
<string name="pin_target" msgid="8036028973110156895">"ປັກໝຸດ"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"ຖອນປັກໝຸດ"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"ຂໍ້ມູນແອັບ"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ກຳລັງເລີ່ມເດໂມ…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"ອັບເດດລາຍການເຫຼົ່ານີ້ໃນ "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ແລະ <xliff:g id="TYPE_2">%3$s</xliff:g> ບໍ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"ບັນທຶກ"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"ບໍ່, ຂອບໃຈ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"ບໍ່ຟ້າວເທື່ອ"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"ຢ່າບັນທຶກ"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"ອັບເດດ"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"ສືບຕໍ່"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"ລະຫັດຜ່ານ"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ເປີດ/ປິດການແບ່ງໜ້າຈໍ"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ໜ້າຈໍລັອກ"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ຮູບໜ້າຈໍ"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"ແອັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ໃນໜ້າຈໍປັອບອັບ."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"ແຖບຄຳບັນຍາຍຂອງ <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 1212aa4..75df18c 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -192,8 +192,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Trūksta darbo profilio administratoriaus programos arba ji sugadinta. Todėl darbo profilis ir susiję duomenys buvo ištrinti. Jei reikia pagalbos, susisiekite su administratoriumi."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Darbo profilis nebepasiekiamas šiame įrenginyje"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Per daug slaptažodžio bandymų"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratorius atmetė prašymą įrenginį naudoti asmeniniais tikslais"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Įrenginys yra tvarkomas"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Šį įrenginį tvarko organizacija ir gali stebėti tinklo srautą. Palieskite, kad gautumėte daugiau informacijos."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Įrenginys bus ištrintas"</string>
@@ -387,13 +386,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Programai leidžiama siųsti užsifiksuojančias transliacijas, kurios išlieka pasibaigus transliacijai. Per dažnas jų naudojimas gali sulėtinti „Android TV“ įrenginio veikimą ar padaryti jį nestabilų verčiant naudoti per daug atminties."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Leidžiama programai siųsti užsifiksuojančias transliacijas, kurios išlieka pasibaigus transliacijai. Per dažnas jų naudojimas gali sulėtinti telefono veikimą ar padaryti jį nestabilų verčiant naudoti per daug atminties."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"skaityti kontaktus"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Leidžiama programai skaityti duomenis apie planšetiniame kompiuteryje saugomus kontaktus, įskaitant dažnį, kuriuo konkretiems asmenims skambinote, siuntėte el. laiškus ar bendravote kitais būdais. Šis leidimas suteikia teisę programoms saugoti kontaktinius duomenis, o kenkėjiškos programos gali bendrinti kontaktinius duomenis be jūsų žinios."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Programai leidžiama skaityti duomenis apie „Android TV“ įrenginyje saugomus kontaktus, įskaitant dažnį, kuriuo konkretiems asmenims skambinote, siuntėte el. laiškus ar bendravote kitais būdais. Šis leidimas suteikia teisę programoms saugoti kontaktinius duomenis, o kenkėjiškos programos gali bendrinti kontaktinius duomenis be jūsų žinios."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Leidžiama programai skaityti duomenis apie telefone saugomus kontaktus, įskaitant dažnį, kuriuo konkretiems asmenims skambinote, siuntėte el. laiškus ar bendravote kitais būdais. Šis leidimas suteikia teisę programoms saugoti kontaktinius duomenis, o kenkėjiškos programos gali bendrinti kontaktinius duomenis be jūsų žinios."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Programai leidžiama skaityti duomenis apie planšetiniame kompiuteryje saugomus kontaktus. Programos taip pat galės pasiekti planšetiniame kompiuteryje esančias paskyras, kuriose buvo sukurta kontaktų. Gali būti įtrauktos paskyros, kurias sukūrė jūsų įdiegtos programos. Šis leidimas suteikia teisę programoms saugoti kontaktinius duomenis, o kenkėjiškos programos gali bendrinti kontaktinius duomenis be jūsų žinios."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Programai leidžiama skaityti duomenis apie „Android TV“ įrenginyje saugomus kontaktus. Programos taip pat galės pasiekti „Android TV“ įrenginyje esančias paskyras, kuriose buvo sukurta kontaktų. Gali būti įtrauktos paskyros, kurias sukūrė jūsų įdiegtos programos. Šis leidimas suteikia teisę programoms saugoti kontaktinius duomenis, o kenkėjiškos programos gali bendrinti kontaktinius duomenis be jūsų žinios."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Programai leidžiama skaityti duomenis apie telefone saugomus kontaktus. Programos taip pat galės pasiekti telefone esančias paskyras, kuriose buvo sukurta kontaktų. Gali būti įtrauktos paskyros, kurias sukūrė jūsų įdiegtos programos. Šis leidimas suteikia teisę programoms saugoti kontaktinius duomenis, o kenkėjiškos programos gali bendrinti kontaktinius duomenis be jūsų žinios."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"keisti kontaktus"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Leidžiama programai keisti duomenis apie planšetiniame kompiuteryje saugomus kontaktus, įskaitant dažnį, kuriuo konkretiems asmenims skambinote, siuntėte el. laiškus ar bendravote kitais būdais. Šis leidimas suteikia teisę programoms ištrinti kontaktinius duomenis."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Leidžiama programai keisti duomenis apie „Android TV“ įrenginyje saugomus kontaktus, įskaitant dažnį, kuriuo konkretiems asmenims skambinote, siuntėte el. laiškus ar bendravote kitais būdais. Šis leidimas suteikia teisę programoms ištrinti kontaktinius duomenis."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Leidžiama programai keisti duomenis apie telefone saugomus kontaktus, įskaitant dažnį, kuriuo konkretiems asmenims skambinote, siuntėte el. laiškus ar bendravote kitais būdais. Šis leidimas suteikia teisę programoms ištrinti kontaktinius duomenis."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Programai leidžiama keisti duomenis apie planšetiniame kompiuteryje saugomus kontaktus. Su šiuo leidimu programos gali ištrinti kontaktinius duomenis."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Programai leidžiama keisti duomenis apie „Android TV“ įrenginyje saugomus kontaktus. Su šiuo leidimu programos gali ištrinti kontaktinius duomenis."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Programai leidžiama keisti duomenis apie telefone saugomus kontaktus. Su šiuo leidimu programos gali ištrinti kontaktinius duomenis."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"skaityti skambučių žurnalą"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Ši programa gali nuskaityti skambučių istoriją."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"rašyti skambučių žurnalą"</string>
@@ -413,13 +412,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"pasiekti papildomas vietos teikimo įrankio komandas"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Programai leidžiama pasiekti papildomas vietovės nustatymo paslaugų teikėjų komandas. Dėl to programa gali trukdyti veikti GPS ar kitiems vietovės nustatymo šaltiniams."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"pasiekti tikslią vietovę, tik kai programa veikia priekiniame plane"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Ši programa gali gauti tikslius jūsų vietovės duomenis bet kuriuo metu, kai veikia priekiniame plane. Šios vietovės paslaugos turi būti įjungtos ir pasiekiamos telefone, kad programa galėtų jas naudoti. Tai gali padidinti akumuliatoriaus energijos suvartojimą."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"pasiekti apytikslę vietovę (pagal tinklo duomenis), tik kai programa veikia priekiniame plane"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Ši programa gali gauti jūsų vietos informaciją naudodamasi tinklo šaltinių, pvz., mobiliojo ryšio bokštų ir „Wi-Fi“ tinklų, duomenimis, bet tik kai ji yra naudojama priekiniame plane. Šios vietovės paslaugos turi būti įjungtos ir pasiekiamos planšetiniame kompiuteryje, kad programa galėtų jas naudoti."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Ši programa gali gauti jūsų vietos informaciją naudodamasi tinklo šaltinių, pvz., mobiliojo ryšio bokštų ir „Wi-Fi“ tinklų, duomenimis, bet tik kai ji yra naudojama priekiniame plane. Šios vietovės paslaugos turi būti įjungtos ir pasiekiamos „Android TV“ įrenginyje, kad programa galėtų jas naudoti."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Ši programa gali gauti jūsų vietos informaciją naudodamasi tinklo šaltinių, pvz., mobiliojo ryšio bokštų ir „Wi-Fi“ tinklų, duomenimis, bet tik kai ji yra naudojama priekiniame plane. Šios vietovės paslaugos turi būti įjungtos ir pasiekiamos telefone, kad programa galėtų jas naudoti."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Ši programa gali gauti tikslius jūsų vietovės duomenis, tik kai veikia priekiniame plane. Vietovės paslaugos turi būti įjungtos ir pasiekiamos įrenginyje, kad programa galėtų jas naudoti. Dėl to akumuliatoriui gali reikėti daugiau energijos."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"pasiekti apytikslę vietovę, tik kai programa veikia priekiniame plane"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Ši programa gali gauti apytikslius jūsų vietovės duomenis, tik kai veikia priekiniame plane. Vietovės paslaugos turi būti įjungtos ir pasiekiamos įrenginyje, kad programa galėtų jas naudoti."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"prieiga prie vietovės fone"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Jei papildomai suteikiama prieiga prie apytikslės arba tikslios vietovės, programa gali pasiekti vietovės duomenis veikdama fone."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Ši programa gali pasiekti vietovę, kai veikia fone ar priekiniame plane."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"keisti garso nustatymus"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Leidžiama programai keisti visuotinius garso nustatymus, pvz., garsumą ir tai, kuris garsiakalbis naudojamas išvesčiai."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"įrašyti garsą"</string>
@@ -500,6 +497,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Leidžiama programai peržiūrėti „Bluetooth“ konfigūraciją planšetiniame kompiuteryje ir užmegzti bei priimti ryšius iš susietų įrenginių."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Programai leidžiama peržiūrėti „Bluetooth“ konfigūraciją „Android TV“ įrenginyje ir užmegzti bei priimti ryšius iš susietų įrenginių."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Leidžiama programai peržiūrėti „Bluetooth“ konfigūraciją telefone ir užmegzti bei priimti ryšius iš susietų įrenginių."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"valdyti artimo lauko perdavimą (angl. „Near Field Communication“)"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Leidžiama programai perduoti artimojo lauko ryšių technologijos (ALR) žymas, korteles ir skaitymo programas."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"išjungti ekrano užraktą"</string>
@@ -1926,7 +1927,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Prisijungta prie „<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>“"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Palieskite, kad peržiūrėtumėte failus"</string>
<string name="pin_target" msgid="8036028973110156895">"Prisegti"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Atsegti"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Programos informacija"</string>
<string name="negative_duration" msgid="1938335096972945232">"–<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Paleidžiama demonstracinė versija…"</string>
@@ -1971,6 +1976,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Atnaujinti šiuos elementus paslaugoje "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ir <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Išsaugoti"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Ne, ačiū"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne dabar"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Niekada"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Atnaujinti"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Tęsti"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"slaptažodį"</string>
@@ -2068,5 +2075,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Perjungti išskaidyto ekrano režimą"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Užrakinimo ekranas"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekrano kopija"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ iššokančiajame lange."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“ antraštės juosta."</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 547b6c9..89fd885 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -190,8 +190,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Trūkst darba profila administratora lietotnes, vai šī lietotne ir bojāta. Šī iemesla dēļ jūsu darba profils un saistītie dati tika dzēsti. Lai saņemtu palīdzību, sazinieties ar administratoru."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jūsu darba profils šai ierīcē vairs nav pieejams."</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Veikts pārāk daudz paroles ievadīšanas mēģinājumu."</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrators atteicās no tādas ierīces pārvaldības, ko var izmantot personiskām vajadzībām"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Ierīce tiek pārvaldīta"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Jūsu organizācija pārvalda šo ierīci un var uzraudzīt tīkla datplūsmu. Pieskarieties, lai saņemtu detalizētu informāciju."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Jūsu ierīces dati tiks dzēsti"</string>
@@ -384,13 +383,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Ļauj lietotnei sūtīt piesaistošas apraides, kas tiek saglabātas pēc apraides pabeigšanas. Pārmērīga izmantošana var palēnināt Android TV ierīces darbību vai padarīt tās darbību nestabilu, liekot izmantot pārāk daudz atmiņas."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Ļauj lietotnei sūtīt piesaistošas apraides, kas tiek saglabātas pēc apraides pabeigšanas. Pārmērīga izmantošana var palēnināt tālruņa darbību vai padarīt tā darbību nestabilu, liekot izmantot pārāk daudz atmiņas."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"lasīt kontaktpersonu informāciju"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Ļauj lietotnei lasīt datus par jūsu planšetdatorā saglabātajām kontaktpersonām, tostarp to, cik bieži esat zvanījis, sazinājies pa e-pastu vai citādi sazinājies ar konkrētām personām. Ar šo atļauju lietotnes var saglabāt jūsu kontaktpersonu datus, un ļaunprātīgas lietotnes var kopīgot kontaktpersonu datus bez jūsu atļaujas."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Ļauj lietotnei lasīt datus par Android TV ierīcē glabātajām kontaktpersonām, tostarp par zvanu un e-pasta ziņojumu apjomu vai saziņu citos veidos, kas veikta ar konkrētām kontaktpersonām. Ar šo atļauju lietotnes var saglabāt jūsu kontaktpersonu datus, un ļaunprātīgas lietotnes var kopīgot kontaktpersonu datus, jums nezinot."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Ļauj lietotnei lasīt datus par jūsu tālrunī saglabātajām kontaktpersonām, tostarp to, cik bieži esat zvanījis, sazinājies pa e-pastu vai citādi sazinājies ar konkrētām personām. Ar šo atļauju lietotnes var saglabāt jūsu kontaktpersonu datus, un ļaunprātīgas lietotnes var kopīgot kontaktpersonu datus bez jūsu atļaujas."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Ļauj lietotnei lasīt datus par planšetdatorā glabātajām kontaktpersonām. Lietotnēm būs arī piekļuve kontiem jūsu planšetdatorā, kuros ir izveidotas kontaktpersonas. Tas var ietvert kontus, ko izveidojušas jūsu instalētās lietotnes. Ar šo atļauju lietotnes var saglabāt jūsu kontaktpersonu datus, savukārt ļaunprātīgas lietotnes var kopīgot kontaktpersonu datus, jums nezinot."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Ļauj lietotnei lasīt datus par Android TV ierīcē glabātajām kontaktpersonām. Lietotnēm būs arī piekļuve kontiem jūsu Android TV ierīcē, kuros ir izveidotas kontaktpersonas. Tas var ietvert kontus, ko izveidojušas jūsu instalētās lietotnes. Ar šo atļauju lietotnes var saglabāt jūsu kontaktpersonu datus, savukārt ļaunprātīgas lietotnes var kopīgot kontaktpersonu datus, jums nezinot."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Ļauj lietotnei lasīt datus par tālrunī glabātajām kontaktpersonām. Lietotnēm būs arī piekļuve kontiem jūsu tālrunī, kuros ir izveidotas kontaktpersonas. Tas var ietvert kontus, ko izveidojušas jūsu instalētās lietotnes. Ar šo atļauju lietotnes var saglabāt jūsu kontaktpersonu datus, savukārt ļaunprātīgas lietotnes var kopīgot kontaktpersonu datus, jums nezinot."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"mainīt kontaktpersonu informāciju"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Ļauj lietotnei mainīt datus par planšetdatorā saglabātajām kontaktpersonām, tostarp par zvanu un e-pasta ziņojumu apjomu vai saziņu citos veidos, kas veikta ar konkrētām kontaktpersonām. Ar šo atļauju lietotne var dzēst kontaktpersonu datus."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Ļauj lietotnei mainīt datus par Android TV ierīcē saglabātajām kontaktpersonām, tostarp par zvanu un e-pasta ziņojumu apjomu vai saziņu citos veidos, kas veikta ar konkrētām kontaktpersonām. Ar šo atļauju lietotnes var dzēst kontaktpersonu datus."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Ļauj lietotnei mainīt datus par tālrunī saglabātajām kontaktpersonām, tostarp par zvanu un e-pasta ziņojumu apjomu vai saziņu citos veidos, kas veikta ar konkrētām kontaktpersonām. Ar šo atļauju lietotne var dzēst kontaktpersonu datus."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Ļauj lietotnei mainīt datus par planšetdatorā glabātajām kontaktpersonām. Ar šo atļauju lietotnes var dzēst kontaktpersonu datus."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Ļauj lietotnei mainīt datus par Android TV ierīcē glabātajām kontaktpersonām. Ar šo atļauju lietotnes var dzēst kontaktpersonu datus."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Ļauj lietotnei mainīt datus par tālrunī glabātajām kontaktpersonām. Ar šo atļauju lietotnes var dzēst kontaktpersonu datus."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"nolasīt zvanu žurnālu"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Šī lietotne var lasīt jūsu zvanu vēsturi."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"rakstīt zvanu žurnālā"</string>
@@ -410,13 +409,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"piekļūt atrašanās vietas nodrošinātāja papildu komandām"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Ļauj lietotnei piekļūt papildu atrašanās vietas noteikšanas nodrošinātāju komandām. Tas var ļaut lietotnei traucēt GPS vai citu atrašanās vietas noteikšanas avotu darbību."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"piekļuve precīzai atrašanās vietai, tikai darbojoties priekšplānā"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Šī lietotne var iegūt precīzu jūsu atrašanās vietu, tikai darbojoties priekšplānā. Šiem atrašanās vietu pakalpojumiem ir jābūt ieslēgtiem un pieejamiem jūsu tālrunī, lai lietotne varētu tos izmantot. Tādējādi var palielināties akumulatora jaudas patēriņš."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"piekļuve aptuvenai atrašanās vietai (pēc tīkla datiem), tikai darbojoties priekšplānā"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Kad šī lietotne darbojas priekšplānā, tā var noteikt jūsu atrašanās vietu, izmantojot tīkla resursus, piemēram, mobilo sakaru torņus un Wi-Fi tīklus. Šiem atrašanās vietu pakalpojumiem ir jābūt ieslēgtiem un pieejamiem jūsu planšetdatorā, lai lietotne varētu tos izmantot."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Kad šī lietotne darbojas priekšplānā, tā var noteikt jūsu atrašanās vietu, izmantojot tīkla resursus, piemēram, mobilo sakaru torņus un Wi-Fi tīklus. Šiem atrašanās vietu pakalpojumiem ir jābūt ieslēgtiem un pieejamiem jūsu Android TV ierīcē, lai lietotne varētu tos izmantot."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Kad šī lietotne darbojas priekšplānā, tā var noteikt jūsu atrašanās vietu, izmantojot tīkla resursus, piemēram, mobilo sakaru torņus un Wi-Fi tīklus. Šiem atrašanās vietu pakalpojumiem ir jābūt ieslēgtiem un pieejamiem jūsu tālrunī, lai lietotne varētu tos izmantot."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Šī lietotne var iegūt precīzu jūsu atrašanās vietu, tikai darbojoties priekšplānā. Jūsu ierīcē ir jābūt ieslēgtiem un pieejamiem atrašanās vietu pakalpojumiem, lai lietotne varētu tos izmantot. Tādējādi var palielināties akumulatora jaudas patēriņš."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"piekļuve aptuvenai atrašanās vietai, tikai darbojoties priekšplānā"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Šī lietotne var iegūt aptuvenu jūsu atrašanās vietu, tikai darbojoties priekšplānā. Jūsu ierīcē ir jābūt ieslēgtiem un pieejamiem atrašanās vietu pakalpojumiem, lai lietotne varētu tos izmantot."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"piekļūt atrašanās vietai fonā"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Ja šī atļauja tiek piešķirta līdz ar piekļuvi aptuvenai vai precīzai atrašanās vietai, lietotne var piekļūt atrašanās vietai, darbojoties fonā."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Šī lietotne var piekļūt atrašanās vietas datiem, darbojoties ne tikai priekšplānā, bet arī fonā."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"mainīt audio iestatījumus"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Ļauj lietotnei mainīt globālos audio iestatījumus, piemēram, skaļumu un izejai izmantoto skaļruni."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ierakstīt audio"</string>
@@ -497,6 +494,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Ļauj lietotnei skatīt Bluetooth konfigurāciju planšetdatorā, kā arī veidot un pieņemt savienojumus ar pārī savienotām ierīcēm."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Ļauj lietotnei skatīt Bluetooth konfigurāciju Android TV ierīcē, kā arī veidot un pieņemt savienojumus ar pārī savienotām ierīcēm."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Ļauj lietotnei skatīt Bluetooth konfigurāciju tālrunī, kā arī veidot un pieņemt savienojumus ar pārī savienotām ierīcēm."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolē tuvlauka saziņu"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Ļauj lietotnei sazināties ar tuva darbības lauka sakaru (Near Field Communication — NFC) atzīmēm, kartēm un lasītājiem."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"atspējot ekrāna bloķēšanu"</string>
@@ -1894,7 +1895,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Izveidots savienojums ar: <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Pieskarieties, lai skatītu failus."</string>
<string name="pin_target" msgid="8036028973110156895">"Piespraust"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Atspraust"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Lietotnes informācija"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Notiek demonstrācijas palaišana..."</string>
@@ -1938,6 +1943,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Vai atjaunināt šos vienumus pakalpojumā "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> un <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Saglabāt"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nē, paldies"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Vēlāk"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nekad"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Atjaunināt"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Turpināt"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"paroli"</string>
@@ -2034,5 +2041,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Pārslēgt ekrāna sadalīšanu"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Bloķēt ekrānu"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekrānuzņēmums"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> uznirstošajā logā."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> subtitru josla."</string>
</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 93f2da1..0c73516 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Апликацијата на администраторот за работниот профил или исчезна или е оштетена. Како резултат на тоа, вашиот работен профил и поврзаните податоци ќе се избришат. За помош, контактирајте со администраторот."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Вашиот работен профил веќе не е достапен на уредов"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Премногу обиди за внесување лозинка"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Уред откажан од администраторот за лична употреба"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Некој управува со уредот"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Вашата организација управува со уредов и можно е да го следи сообраќајот на мрежата. Допрете за детали."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Уредот ќе се избрише"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Дозволува апликацијата да испраќа лепливи емитувања, што остануваат по завршување на емитувањето. Прекумерното користење може да го направи вашиот уред Android TV бавен или нестабилен, така што ќе предизвика користење премногу меморија."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Овозможува апликацијата да испраќа лепливи емитувања, кои остануваат по завршувањето на емитувањето. Прекумерна употреба може да предизвика телефонот да биде бавен или нестабилен со тоа што предизвикува да користи премногу меморија."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"прочитај контакти"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Овозможува апликацијата да чита податоци за контактите зачувани на вашиот таблет, вклучувајќи ја и фреквенцијата со која сте повикувале, сте праќале е-пошта или сте комуницирале на други начини со конкретни поединци. Оваа дозвола овозможува апликациите да ги зачуваат вашите податоци за контакт и злонамерните апликации може да споделат податоци за контакт без ваше знаење."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Дозволува апликацијата да чита податоци за вашите контакти кои се складирани во вашиот уред Android TV, вклучувајќи ја зачестеноста со која сте повикувале, сте испраќале е-пораки или сте комуницирале на друг начин со конкретни поединци. Оваа дозвола овозможува апликациите да ги зачувуваат вашите податоци на контактите, а злонамерните апликации можат да ги споделуваат податоците на контактите без ваше знаење."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Овозможува апликацијата да чита податоци за контактите зачувани во вашиот телефон, вклучувајќи ја и фреквенцијата со која сте повикувале, сте праќале е-пошта или сте комуницирале на други начини со конкретни поединци. Оваа дозвола овозможува апликациите да ги зачуваат вашите податоци за контакт и злонамерните апликации може да споделат податоци за контакт без ваше знаење."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Овозможува апликацијата да чита податоци за контактите складирани во вашиот таблет. Апликациите ќе имаат пристап и до сметките на вашиот таблет што создале контакти. Тука може да спаѓаат сметките создадени од апликациите што сте ги инсталирале. Оваа дозвола им овозможува на апликациите да ги зачувуваат податоците за вашите контакти, а злонамерните апликации може да споделуваат податоци за контактите без ваше знаење."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Овозможува апликацијата да чита податоци за контактите складирани во вашиот уред со Android TV. Апликациите ќе имаат пристап и до сметките на вашиот уред со Android TV што создале контакти. Тука може да спаѓаат сметките создадени од апликациите што сте ги инсталирале. Оваа дозвола им овозможува на апликациите да ги зачувуваат податоците за вашите контакти, а злонамерните апликации може да споделуваат податоци за контактите без ваше знаење."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Овозможува апликацијата да чита податоци за контактите складирани во вашиот телефон. Апликациите ќе имаат пристап и до сметките на вашиот телефон што создале контакти. Тука може да спаѓаат сметките создадени од апликациите што сте ги инсталирале. Оваа дозвола им овозможува на апликациите да ги зачувуваат податоците за вашите контакти, а злонамерните апликации може да споделуваат податоци за контактите без ваше знаење."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"измени ги своите контакти"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Овозможува апликацијата да менува податоци за контактите зачувани во вашиот таблет, вклучувајќи ја и колку често сте повикувале, сте праќале е-пошта или сте комуницирале на други начини со конкретни контакти. Оваа дозвола овозможува апликациите да бришат податоци за контакти."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Дозволува апликацијата да чита податоци за вашите контакти кои се складирани во вашиот уред Android TV, вклучувајќи ја зачестеноста со која сте повикувале, испраќале е-пораки или комуницирале на друг начин со конкретни контакти. Оваа дозвола овозможува апликациите да бришат податоци на контактите."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Овозможува апликацијата да менува податоци за контактите зачувани во вашиот телефон, вклучувајќи и колку често сте повикувале, сте праќале е-пошта или сте комуницирале на други начини со конкретни контакти. Оваа дозвола овозможува апликациите да бришат податоци за контакти."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Овозможува апликацијата да менува податоци за контактите складирани во вашиот таблет. Оваа дозвола им овозможува на апликациите да бришат податоци за контактите."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Овозможува апликацијата да менува податоци за контактите складирани во вашиот уред со Android TV. Оваа дозвола им овозможува на апликациите да бришат податоци за контактите."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Овозможува апликацијата да менува податоци за контактите складирани во вашиот телефон. Оваа дозвола им овозможува на апликациите да бришат податоци за контактите."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"прочитај дневник на повици"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Апликацијава може да ја чита историјата на повиците."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"напиши дневник на повици"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"пристапи кон наредби на давателот на дополнителна локација"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Овозможува апликацијата да пристапи кон дополнителни наредби на давател на локација. Ова може да овозможи апликацијата да го попечи функционирањето на GPS или други извори на локација."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"пристап до прецизната локација само во преден план"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Апликацијава може да ја добие вашата точна локација само кога е во преден план. Услугиве според локација мора да се вклучени и достапни на телефонот за да може да ги користи апликацијата. Ова може да го зголеми трошењето на батеријата."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"пристап до приближна локација (според мрежа) само во преден план"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Апликацијава може да ја добие вашата локација од мрежните извори како што се репетиторите за мобилни мрежи и Wi-Fi мрежите, но само кога апликацијата е во преде план. Овие услуги за локација мора да се вклучени и достапни на таблетот за да може да ги користи апликацијата."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Апликацијава може да ја добие вашата локација од мрежните извори како што се репетиторите за мобилни мрежи и Wi-Fi мрежите, но само кога апликацијата е во преден план. Овие услуги според локација мора да се вклучени и достапни на уредот Android TV за да може да ги користи апликацијата."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Апликацијава може да ја добие вашата локација од мрежните извори како што се репетиторите за мобилни мрежи и Wi-Fi мрежите, но само кога апликацијата е во преде план. Овие услуги за локација мора да се вклучени и достапни на телефонот за да може да ги користи апликацијата."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Апликацијава може да ја добие вашата точна локација само кога е во преден план. Услугите според локација мора да се вклучени и достапни на уредот за да може да ги користи апликацијата. Ова може да го зголеми трошењето на батеријата."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"пристап до приближната локација само во преден план"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Апликацијава може да ја добие вашата приближна локација само кога е во преден план. Услугите според локација мора да се вклучени и достапни на уредот за да може да ги користи апликацијата."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"пристап до локацијата во заднина"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Ако покрај дозволата за пристап до приближната или прецизната локација е доделена и оваа дозвола, тогаш апликацијата ќе може да пристапува до локацијата додека се извршува во заднина."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Оваа апликација, покрај тоа што може да пристапува до локацијата кога е во преден план, има пристап и кога се извршува во заднина."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"менува аудио поставки"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Овозможува апликацијата да ги менува глобалните аудио поставки, како што се јачината на звукот и кој звучник се користи за излез."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"снимај аудио"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Овозможува апликацијата да ја види конфигурацијата на Bluetooth на таблетот и да прави и да прифаќа врски со спарени уреди."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Дозволува апликацијата да ја прикажува конфигурацијата на Bluetooth на вашиот уред Android TV и да прави и прифаќа врски со спарените уреди."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Овозможува апликацијата да ја види конфигурацијата на Bluetooth на телефонот и да прави и да прифаќа врски со спарени уреди."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"контролирај комуникација на блиско поле"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Дозволува апликацијата да комуницира со ознаки, картички и читачи за Комуникација при непосредна близина (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"оневозможи заклучување на екран"</string>
@@ -1864,7 +1865,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Поврзан на <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Допрете за да ги погледнете датотеките"</string>
<string name="pin_target" msgid="8036028973110156895">"Прикачете"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Откачете"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Информации за апликација"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Се вклучува демонстрацијата…"</string>
@@ -1907,6 +1912,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Да се ажурираат овие ставки во "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> и <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Зачувај"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Не, фала"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Не сега"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Никогаш"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Ажурирај"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Продолжи"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"лозинка"</string>
@@ -2002,5 +2009,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Вклучи/исклучи поделен екран"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Заклучен екран"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Слика од екранот"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Апликацијата <xliff:g id="APP_NAME">%1$s</xliff:g> во скокачки прозорец."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Насловна лента на <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index c220cdd..a7d48cf 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"ഔദ്യോഗിക പ്രൊഫൈൽ അഡ്മിൻ ആപ്പ് വിട്ടുപോയിരിക്കുന്നു അല്ലെങ്കിൽ കേടായിരിക്കുന്നു. ഫലമായി, നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലും ബന്ധപ്പെട്ട വിവരങ്ങളും ഇല്ലാതാക്കിയിരിക്കുന്നു. സഹായത്തിന് അഡ്മിനെ ബന്ധപ്പെടുക."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ഈ ഉപകരണത്തിൽ തുടർന്നങ്ങോട്ട് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ ലഭ്യമല്ല"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"വളരെയധികം പാസ്വേഡ് ശ്രമങ്ങൾ"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"വ്യക്തിപരമായ ഉപയോഗത്തിനായി, ഉപകരണത്തിന്റെ ഔദ്യോഗിക ഉപയോഗം അഡ്മിൻ അവസാനിപ്പിച്ചു"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"ഉപകരണം മാനേജുചെയ്യുന്നുണ്ട്"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"നിങ്ങളുടെ സ്ഥാപനമാണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്, നെറ്റ്വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കുകയും ചെയ്തേക്കാം, വിശദാംശങ്ങൾ അറിയാൻ ടാപ്പുചെയ്യുക."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"നിങ്ങളുടെ ഉപകരണം മായ്ക്കും"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"പ്രക്ഷേപണം അവസാനിച്ച ശേഷവും അവശേഷിക്കുന്ന സ്റ്റിക്കി പ്രക്ഷേപണങ്ങൾ അയയ്ക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. Android ടിവിയുടെ അമിതമായ ഉപയോഗം ഒരുപാട് മെമ്മറി ഉപയോഗിക്കാൻ കാരണമാകുകയും ടിവിയുടെ വേഗത കുറയ്ക്കുകയോ അതിനെ അസ്ഥിരമാക്കുകയോ ചെയ്തേക്കാം."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"സ്റ്റിക്കി പ്രക്ഷേപണങ്ങൾ അയയ്ക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു, പ്രക്ഷേപണം അവസാനിച്ചതിനുശേഷവും അത് നിലനിൽക്കുന്നു. അമിതോപയോഗം വളരെയധികം മെമ്മറി ഉപയോഗിക്കുന്നതിനാൽ, അത് ഫോണിന്റെ പ്രവർത്തനത്തെ മന്ദഗതിയിലാക്കുകയോ അസ്ഥിരമാക്കുകയോ ചെയ്യാം."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"നിങ്ങളുടെ കോൺടാക്റ്റുകൾ റീഡുചെയ്യുക"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"നിശ്ചിത ആളുകളെ മറ്റ് മാർഗങ്ങളിൽ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നതോ അവർക്ക് ഇമെയിൽ ചെയ്തിട്ടുണ്ടെന്നതോ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നതോ ഉൾപ്പെടെ, നിങ്ങളുടെ ടാബ്ലെറ്റിൽ സംഭരിച്ചിരിക്കുന്ന നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ കോൺടാക്റ്റ് ഡാറ്റ സംരക്ഷിക്കാൻ ഈ അനുമതി അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു, ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ അറിവില്ലാതെ കോൺടാക്റ്റ് ഡാറ്റ പങ്കിടാനിടയുണ്ട്."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"നിർദ്ദിഷ്ട വ്യക്തികളെ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നും അവർക്ക് ഇമെയിൽ അയച്ചിട്ടുണ്ടെന്നും മറ്റ് മാർഗങ്ങളിലൂടെ അവരുമായി എത്ര തവണ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നും ഉൾപ്പെടെ നിങ്ങളുടെ Android ടിവിയിൽ സംഭരിച്ചിരിക്കുന്ന കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ പരിഷ്ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. ഈ അനുമതി നിങ്ങളുടെ കോൺടാക്റ്റ് ഡാറ്റ സംരക്ഷിക്കാൻ ആപ്പുകളെ അനുവദിക്കുന്നു, നിങ്ങളുടെ അറിവില്ലാതെ ദോഷകരമായ ആപ്പുകൾ കോൺടാക്റ്റ് ഡാറ്റ പങ്കിടുകയും ചെയ്തേക്കാം."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"നിശ്ചിത ആളുകളെ മറ്റ് മാർഗങ്ങളിൽ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നതോ അവർക്ക് ഇമെയിൽ ചെയ്തിട്ടുണ്ടെന്നതോ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നതോ ഉൾപ്പെടെ, നിങ്ങളുടെ ഫോണിൽ സംഭരിച്ചിരിക്കുന്ന നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ കോൺടാക്റ്റ് ഡാറ്റ സംരക്ഷിക്കാൻ ഈ അനുമതി അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു, ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ അറിവില്ലാതെ കോൺടാക്റ്റ് ഡാറ്റ പങ്കിടാനിടയുണ്ട്."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"ടാബ്ലെറ്റിൽ സംഭരിച്ച നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ വായിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ ടാബ്ലെറ്റിൽ കോണ്ടാക്റ്റുകൾ സൃഷ്ടിച്ച അക്കൗണ്ടുകളിലേക്കുള്ള ആക്സസും ആപ്പുകൾക്ക് ഉണ്ടായിരിക്കും. നിങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്ത ആപ്പുകൾ സൃഷ്ടിച്ച അക്കൗണ്ടുകളും ഇതിൽ ഉൾപ്പെട്ടേക്കാം. നിങ്ങളുടെ കോണ്ടാക്റ്റ് ഡാറ്റ സംരക്ഷിക്കാൻ ആപ്പുകളെ ഈ അനുമതി അനുവദിക്കുന്നു, നിങ്ങളുടെ അറിവില്ലാതെ, ദോഷകരമായ ആപ്പുകൾ കോണ്ടാക്റ്റ് ഡാറ്റ പങ്കിടുകയും ചെയ്തേക്കാം."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"നിങ്ങളുടെ Android ടിവിയിൽ സംഭരിച്ച കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ വായിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ Android ടിവിയിൽ കോണ്ടാക്റ്റുകൾ സൃഷ്ടിച്ച അക്കൗണ്ടുകളിലേക്കുള്ള ആക്സസും ആപ്പുകൾക്ക് ഉണ്ടായിരിക്കും. നിങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്ത ആപ്പുകൾ സൃഷ്ടിച്ച അക്കൗണ്ടുകളും ഇതിൽ ഉൾപ്പെട്ടേക്കാം. നിങ്ങളുടെ കോണ്ടാക്റ്റ് ഡാറ്റ സംരക്ഷിക്കാൻ ആപ്പുകളെ ഈ അനുമതി അനുവദിക്കുന്നു, നിങ്ങളുടെ അറിവില്ലാതെ, ദോഷകരമായ ആപ്പുകൾ കോണ്ടാക്റ്റ് ഡാറ്റ പങ്കിടുകയും ചെയ്തേക്കാം."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ഉപകരണത്തിൽ സംഭരിച്ച നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ വായിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ ഫോണിൽ കോണ്ടാക്റ്റുകൾ സൃഷ്ടിച്ച അക്കൗണ്ടുകളിലേക്കുള്ള ആക്സസും ആപ്പുകൾക്ക് ഉണ്ടായിരിക്കും. നിങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്ത ആപ്പുകൾ സൃഷ്ടിച്ച അക്കൗണ്ടുകളും ഇതിൽ ഉൾപ്പെട്ടേക്കാം. നിങ്ങളുടെ കോണ്ടാക്റ്റ് ഡാറ്റ സംരക്ഷിക്കാൻ ആപ്പുകളെ ഈ അനുമതി അനുവദിക്കുന്നു, നിങ്ങളുടെ അറിവില്ലാതെ, ദോഷകരമായ ആപ്പുകൾ കോണ്ടാക്റ്റ് ഡാറ്റ പങ്കിടുകയും ചെയ്തേക്കാം."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"നിങ്ങളുടെ കോൺടാക്റ്റുകൾ പരിഷ്ക്കരിക്കുക"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"നിശ്ചിത കോൺടാക്റ്റുകളെ മറ്റ് മാർഗങ്ങളിൽ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നതോ അവർക്ക് ഇമെയിൽ ചെയ്തിട്ടുണ്ടെന്നതോ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നതോ ഉൾപ്പെടെ, നിങ്ങളുടെ ടാബ്ലെറ്റിൽ സംഭരിച്ചിരിക്കുന്ന നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ പരിഷ്ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഈ അനുമതി കോൺടാക്റ്റ് ഡാറ്റ ഇല്ലാതാക്കാൻ അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"നിർദ്ദിഷ്ട കോൺടാക്റ്റുകളെ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നും അവർക്ക് ഇമെയിൽ അയച്ചിട്ടുണ്ടെന്നും മറ്റ് മാർഗങ്ങളിലൂടെ അവരുമായി എത്ര തവണ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നും ഉൾപ്പെടെ നിങ്ങളുടെ Android ടിവിയിൽ സംഭരിച്ചിരിക്കുന്ന കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ പരിഷ്ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. കോൺടാക്റ്റ് ഡാറ്റ ഇല്ലാതാക്കാൻ ഈ അനുമതി ആപ്പുകളെ അനുവദിക്കുന്നു."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"നിശ്ചിത കോൺടാക്റ്റുകളെ മറ്റ് മാർഗങ്ങളിൽ നിങ്ങൾ എത്ര തവണ വിളിച്ചിട്ടുണ്ടെന്നതോ അവർക്ക് ഇമെയിൽ ചെയ്തിട്ടുണ്ടെന്നതോ ആശയവിനിമയം നടത്തിയിട്ടുണ്ടെന്നതോ ഉൾപ്പെടെ, നിങ്ങളുടെ ഫോണിൽ സംഭരിച്ചിരിക്കുന്ന നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ പരിഷ്ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഈ അനുമതി കോൺടാക്റ്റ് ഡാറ്റ ഇല്ലാതാക്കാൻ അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"ടാബ്ലെറ്റിൽ സംഭരിച്ച നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ പരിഷ്ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. കോൺടാക്റ്റ് ഡാറ്റ ഇല്ലാതാക്കാൻ അപ്പുകളെ ഈ അനുമതി അനുവദിക്കുന്നു."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"നിങ്ങളുടെ Android ടിവിയിൽ സംഭരിച്ച കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ പരിഷ്ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. കോൺടാക്റ്റ് ഡാറ്റ ഇല്ലാതാക്കാൻ അപ്പുകളെ ഈ അനുമതി അനുവദിക്കുന്നു."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"ഫോണിൽ സംഭരിച്ച നിങ്ങളുടെ കോൺടാക്റ്റുകളെക്കുറിച്ചുള്ള ഡാറ്റ പരിഷ്ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. കോൺടാക്റ്റ് ഡാറ്റ ഇല്ലാതാക്കാൻ അപ്പുകളെ ഈ അനുമതി അനുവദിക്കുന്നു."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"കോൾ ചരിത്രം റീഡ് ചെയ്യുക"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"ഈ ആപ്പിന് നിങ്ങളുടെ കോൾ ചരിത്രം വായിക്കാൻ കഴിയും."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"കോൾ ചരിത്രം റൈറ്റ് ചെയ്യുക"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"ലൊക്കേഷൻ ദാതാവിന്റെ അധിക കമാൻഡുകൾ ആക്സസ്സുചെയ്യുക"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"ലൊക്കേഷൻ ദാതാവിന്റെ അധിക കമാൻഡുകൾ ആക്സസ്സുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് GPS-ന്റെയോ മറ്റ് ലൊക്കേഷൻ ഉറവിടങ്ങളുടെയോ പ്രവർത്തനത്തിൽ ഇടപെടാൻ അപ്ലിക്കേഷനെ അനുവദിക്കാനിടയുണ്ട്."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"ഫോർഗ്രൗണ്ടിൽ മാത്രം കൃത്യമായ ലൊക്കേഷൻ ആക്സസ് ചെയ്യുക"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"ഫോർഗ്രൗണ്ടിൽ ഉള്ളപ്പോൾ മാത്രമേ ഈ ആപ്പിന് നിങ്ങളുടെ കൃത്യമായ ലൊക്കേഷൻ നേടാനാവൂ. ആപ്പിന് ഉപയോഗിക്കാനായി, ഈ ലൊക്കേഷൻ സേവനങ്ങൾ ഓണായിരിക്കുകയും നിങ്ങളുടെ ഫോണിൽ ലഭ്യമാവുകയും വേണം. ഇതിലൂടെ ബാറ്ററി ഉപഭോഗം വർദ്ധിച്ചേക്കാം."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"ഫോർഗ്രൗണ്ടിൽ മാത്രം, ഏകദേശ ലൊക്കേഷൻ (നെറ്റ്വർക്ക്-അടിസ്ഥാനമാക്കി) ആക്സസ് ചെയ്യുക"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"സെൽ ടവറുകളും വൈഫൈ നെറ്റ്വർക്കുകളും പോലുള്ള നെറ്റ്വർക്ക് ഉറവിടങ്ങൾ അടിസ്ഥാനമാക്കി, ഈ ആപ്പിന് നിങ്ങളുടെ ലൊക്കേഷൻ നേടാൻ കഴിയും. എന്നാൽ, ഫോർഗ്രൗണ്ടിൽ ഉള്ളപ്പോൾ മാത്രമേ ആപ്പിന് ഇതിന് കഴിയൂ. ആപ്പിന് ഉപയോഗിക്കാനായി, ഈ ലൊക്കേഷൻ സേവനങ്ങൾ ഓണായിരിക്കുകയും നിങ്ങളുടെ ടാബ്ലെറ്റിൽ ലഭ്യമാവുകയും വേണം."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"സെൽ ടവറുകളും വൈഫൈ നെറ്റ്വർക്കുകളും പോലെയുള്ള നെറ്റ്വർക്ക് ഉറവിടങ്ങളുടെ അടിസ്ഥാനത്തിൽ ഈ ആപ്പിന് നിങ്ങളുടെ ലൊക്കേഷൻ നേടാനാവും, എന്നാൽ ആപ്പ് ഫോർഗ്രൗണ്ടിൽ ആയിരിക്കുമ്പോൾ മാത്രമേ ഇത് സാധ്യമാവൂ. ആപ്പിന് ഉപയോഗിക്കാനായി ഈ ലൊക്കേഷൻ സേവനങ്ങൾ ഓണായിരിക്കുകയും നിങ്ങളുടെ Android ടിവിയിൽ ലഭ്യമാവുകയും വേണം."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"സെൽ ടവറുകളും വൈഫൈ നെറ്റ്വർക്കുകളും പോലുള്ള നെറ്റ്വർക്ക് ഉറവിടങ്ങൾ അടിസ്ഥാനമാക്കി, ഈ ആപ്പിന് നിങ്ങളുടെ ലൊക്കേഷൻ നേടാൻ കഴിയും. എന്നാൽ, ഫോർഗ്രൗണ്ടിൽ ഉള്ളപ്പോൾ മാത്രമേ ആപ്പിന് ഇതിന് കഴിയൂ. ആപ്പിന് ഉപയോഗിക്കാനായി, ഈ ലൊക്കേഷൻ സേവനങ്ങൾ ഓണായിരിക്കുകയും നിങ്ങളുടെ ഫോണിൽ ലഭ്യമാവുകയും വേണം."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"ഫോർഗ്രൗണ്ടിൽ ഉള്ളപ്പോൾ മാത്രമേ ഈ ആപ്പിന് നിങ്ങളുടെ കൃത്യമായ ലൊക്കേഷൻ ലഭിക്കൂ. ഈ ആപ്പിന് ലൊക്കേഷൻ സേവനങ്ങൾ ഉപയോഗിക്കാൻ കഴിയണമെങ്കിൽ, അവ നിങ്ങളുടെ ഉപകരണത്തിൽ ലഭ്യമായിരിക്കുകയും ഓണായിരിക്കുകയും വേണം. ഇത് ബാറ്ററി ഉപഭോഗം വർദ്ധിപ്പിച്ചേക്കാം."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"ഫോർഗ്രൗണ്ടിൽ മാത്രം ഏകദേശ ലൊക്കേഷൻ ആക്സസ് ചെയ്യുക"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"ഫോർഗ്രൗണ്ടിൽ ഉള്ളപ്പോൾ മാത്രമേ ഈ ആപ്പിന് നിങ്ങളുടെ ഏകദേശ ലൊക്കേഷൻ ലഭിക്കൂ. ഈ ആപ്പിന് ലൊക്കേഷൻ സേവനങ്ങൾ ഉപയോഗിക്കാൻ കഴിയണമെങ്കിൽ, അവ നിങ്ങളുടെ ഉപകരണത്തിൽ ലഭ്യമായിരിക്കുകയും ഓണായിരിക്കുകയും വേണം."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"പശ്ചാത്തലത്തിൽ ലൊക്കേഷൻ ആക്സസ് ചെയ്യുക"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"ഏകദേശം അല്ലെങ്കിൽ കൃത്യമായ ലൊക്കേഷൻ ആക്സസിന് ഇത് അധികമായി അനുവദിച്ചതാണെങ്കിൽ, പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുമ്പോഴും ആപ്പിന് ലൊക്കേഷൻ ആക്സസ് ചെയ്യാനാവും."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"പശ്ചാത്തലത്തിൽ പ്രവർത്തിക്കുമ്പോൾ, ഫോർഗ്രൗണ്ട് ലൊക്കേഷന് പുറമെ, ലൊക്കേഷൻ ആക്സസ് ചെയ്യാനും ഈ ആപ്പിന് കഴിയും."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"നിങ്ങളുടെ ഓഡിയോ ക്രമീകരണങ്ങൾ മാറ്റുക"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"വോളിയവും ഔട്ട്പുട്ടിനായി ഉപയോഗിച്ച സ്പീക്കറും പോലുള്ള ആഗോള ഓഡിയോ ക്രമീകരണങ്ങൾ പരിഷ്ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ഓഡിയോ റെക്കോർഡ് ചെയ്യുക"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ടാബ്ലെറ്റിലെ ബ്ലൂടൂത്ത് കോൺഫിഗറേഷൻ കാണാനും ജോടിയാക്കിയ ഉപകരണങ്ങളുമായി കണക്ഷനുകൾ നടത്തി അംഗീകരിക്കാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"നിങ്ങളുടെ Android ടിവിയിലെ Bluetooth കോൺഫിഗറേഷൻ കാണാനും ജോടിയാക്കിയ ഉപകരണങ്ങളുമായി കണക്ഷനുകൾ സൃഷ്ടിക്കാനും അംഗീകരിക്കാനും ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ഫോണിലെ ബ്ലൂടൂത്ത് കോൺഫിഗറേഷൻ കാണാനും ജോടിയാക്കിയ ഉപകരണങ്ങളുമായി കണക്ഷനുകൾ നടത്തി അംഗീകരിക്കാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"സമീപ ഫീൽഡുമായുള്ള ആശയവിനിമയം നിയന്ത്രിക്കുക"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"നിയർ ഫീൽഡ് കമ്മ്യൂണിക്കേഷൻ (NFC) ടാഗുകളുമായും കാർഡുകളുമായും റീഡറുകളുമായുള്ള ആശയവിനിമയത്തിന് അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"നിങ്ങളുടെ സ്ക്രീൻ ലോക്ക് പ്രവർത്തനരഹിതമാക്കുക"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> എന്നതിലേക്ക് കണക്റ്റുചെയ്തു"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ഫയലുകൾ കാണുന്നതിന് ടാപ്പുചെയ്യുക"</string>
<string name="pin_target" msgid="8036028973110156895">"പിൻ ചെയ്യുക"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"അൺപിൻ ചെയ്യുക"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"ആപ്പ് വിവരം"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ഡെമോ ആരംഭിക്കുന്നു…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"ഇനിപ്പറയുന്ന ഇനങ്ങൾ "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" എന്നതിൽ അപ്ഡേറ്റ് ചെയ്യണോ: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"സംരക്ഷിക്കുക"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"വേണ്ട, നന്ദി"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"ഇപ്പോൾ വേണ്ട"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"ഒരിക്കലും വേണ്ട"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"അപ്ഡേറ്റ് ചെയ്യുക"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"തുടരുക"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"പാസ്വേഡ്"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"സ്ക്രീൻ വിഭജന മോഡ് മാറ്റുക"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ലോക്ക് സ്ക്രീൻ"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"സ്ക്രീൻഷോട്ട്"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"പോപ്പ്-അപ്പ് വിൻഡോയിലെ <xliff:g id="APP_NAME">%1$s</xliff:g> ആപ്പ്."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിന്റെ അടിക്കുറിപ്പ് ബാർ."</string>
</resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 8c26113..9766475 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Ажлын профайлын админ апп байхгүй эсвэл эвдэрсэн байна. Үүний улмаас таны ажлын профайл болон холбогдох мэдээллийг устгасан болно. Тусламж хэрэгтэй бол админтай холбогдоно уу."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Таны ажлын профайл энэ төхөөрөмжид боломжгүй байна"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Нууц үгийг хэт олон удаа буруу оруулсан байна"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Админ хувийн хэрэглээнд зориулж төхөөрөмжийн эрхийг хассан"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Төхөөрөмжийг удирдсан"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Таны байгууллага энэ төхөөрөмжийг удирдаж, сүлжээний ачааллыг хянадаг. Дэлгэрэнгүй мэдээлэл авах бол товшино уу."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Таны төхөөрөмж устах болно."</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Аппад нэвтрүүлэг дууссаны дараа үлдэх бэхлэгдсэн нэвтрүүлэг илгээхийг зөвшөөрнө. Хэт их ашиглах нь санах ойн ачааллыг нэмэгдүүлж, улмаар таны Android ТВ төхөөрөмжийг удаан эсвэл тогтворгүй болгож болзошгүй."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Апп нь өргөн дамжуулал дууссаны дараа үлдсэн өргөн дамжуулалыг илгээх боломжтой. Ихээр ашиглах нь хэт их санах ой ашиглан утсыг удаашруулах болон тогтворгүй болгох боломжтой."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"өөрийн харилцагчдыг унших"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Апп нь таны утсаар ярьсан, имэйл илгээсэн давтамж эсвэл тусгай харилцагдчидтайгаа өөр аргаар холбоо барьсан байдал зэргийг агуулсан таблет дээр хадгалагдсан харилцагчдын талаарх датаг унших боломжтой. Энэ зөвшөөрөл нь апп-д таны харилцагчийн датаг хадгалах боломжийг олгох ба хортой апп нь танд мэдэгдэлгүйгээр харилцагчийн датаг хуваалцах боломжтой."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Аппaд таны тодорхой хувь хүн рүү хийсэн дуудлага, бичсэн имэйл эсвэл бусад аргаар харилцсан байдлын давтамж зэрэг таны Android ТВ төхөөрөмжид хадгалсан харилцагчдын талаарх өгөгдлийг өөрчлөхийг зөвшөөрнө. Энэ зөвшөөрөл нь аппуудад таны харилцагчийн өгөгдлийг хадгалахыг зөвшөөрөх бөгөөд хортой аппууд танд мэдэгдэлгүйгээр харилцагчийн өгөгдлийг бусадтай хуваалцаж болзошгүй."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Апп нь таны утсаар ярьсан, имэйл илгээсэн давтамж эсвэл тусгай харилцагчидтайгаа өөр аргаар холбоо барьсан байдал зэргийг агуулсан таны утсан дээр хадгалагдсан харилцагчдын талаарх датаг унших боломжтой. Энэ зөвшөөрөл нь апп-д таны харилцагчийн датаг хадгалах боломжийг олгох ба хортой апп нь танд мэдэгдэлгүйгээр харилцагчийн датаг хуваалцах боломжтой."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Аппaд таны таблет дээр хадгалагдсан харилцагчдын өгөгдлийг уншихыг зөвшөөрнө. Мөн аппууд нь таны таблет дээрх харилцагч үүсгэсэн бүртгэлд хандах боломжтой байна. Үүнд таны суулгасан аппуудын үүсгэсэн бүртгэлийг оролцуулж болзошгүй. Энэ зөвшөөрөл нь аппуудад таны харилцагчийн өгөгдлийг хадгалахыг зөвшөөрөх бөгөөд хортой аппууд нь танд мэдэгдэлгүйгээр харилцагчийн өгөгдлийг хуваалцаж болзошгүй."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Аппaд таны Android TВ төхөөрөмж дээр хадгалагдсан харилцагчдын өгөгдлийг уншихыг зөвшөөрнө. Мөн аппууд нь таны Android TВ төхөөрөмж дээрх харилцагч үүсгэсэн бүртгэлд хандах боломжтой байна. Үүнд таны суулгасан аппуудын үүсгэсэн бүртгэлийг оролцуулж болзошгүй. Энэ зөвшөөрөл нь аппуудад таны харилцагчийн өгөгдлийг хадгалахыг зөвшөөрөх бөгөөд хортой аппууд нь танд мэдэгдэлгүйгээр харилцагчийн өгөгдлийг хуваалцаж болзошгүй."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Аппaд таны утсан дээр хадгалагдсан харилцагчдын өгөгдлийг уншихыг зөвшөөрнө. Мөн аппууд нь таны утсан дээрх харилцагч үүсгэсэн бүртгэлд хандах боломжтой байна. Үүнд таны суулгасан аппуудын үүсгэсэн бүртгэлийг оролцуулж болзошгүй. Энэ зөвшөөрөл нь аппуудад таны харилцагчийн өгөгдлийг хадгалахыг зөвшөөрөх бөгөөд хортой аппууд нь танд мэдэгдэлгүйгээр харилцагчийн өгөгдлийг хуваалцаж болзошгүй."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"таны харилцагчдыг өөрчлөх"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Апп нь таны утсаар ярьсан, имэйл илгээсэн давтамж эсвэл тусгай харилцагчидтайгаа өөр аргаар холбоо барьсан байдал зэргийг агуулсан таны таблет дээр хадгалагдсан харилцагчдын талаарх датаг өөрчлөх боломжтой. Энэ зөвшөөрөл нь апп-д харилцагчийн датаг устгах боломжийг олгоно."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Аппaд таны тодорхой харилцагч руу хийсэн дуудлага, бичсэн имэйл эсвэл бусад аргаар харилцсан байдлын давтамж зэрэг таны Android ТВ төхөөрөмжид хадгалсан харилцагчдын талаарх өгөгдлийг өөрчлөхийг зөвшөөрнө. Энэ зөвшөөрөл нь аппуудад харилцагчийн өгөгдлийг устгахыг зөвшөөрнө."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Апп нь таны утсаар ярьсан, имэйл илгээсэн давтамж эсвэл харилцагдчидтайгаа өөр аргаар холбоо барьсан байдал зэргийг агуулсан утсан дээр хадгалагдсан харилцагчдын талаарх датаг өөрчлөх боломжтой. Энэ зөвшөөрөл нь апп-д харилцагчийн датаг устгах боломжийг олгоно."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Аппад таны таблет дээр хадгалагдсан харилцагчдын өгөгдлийг өөрчлөхийг зөвшөөрнө. Энэ зөвшөөрөл нь харилцагчийн өгөгдлийг устгахыг аппуудад зөвшөөрнө."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Аппaд таны Android TВ төхөөрөмж дээр хадгалагдсан харилцагчдын өгөгдлийг өөрчлөхийг зөвшөөрнө. Энэ зөвшөөрөл нь харилцагчийн өгөгдлийг устгахыг аппуудад зөвшөөрнө."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Аппад таны утсан дээр хадгалагдсан харилцагчдын өгөгдлийг өөрчлөхийг зөвшөөрнө. Энэ зөвшөөрөл нь харилцагчийн өгөгдлийг устгахыг аппуудад зөвшөөрнө."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"дуудлагын логийг унших"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Энэ апп таны дуудлагын түүхийг унших боломжтой."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"дуудлагын логруу бичих"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"байршил нийлүүлэгчийн нэмэлт тушаалд хандах"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Апп нь байршил нийлүүлэгчийн нэмэлт тушаалд хандах боломжтой. Энэ нь апп-д GPS эсвэл бусад байршлын үйлчилгээний ажиллагаанд нөлөөлөх боломжийг олгоно."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"нарийвчилсан байршилд зөвхөн нүүр хэсэгт хандах"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Энэ апп нь зөвхөн нүүр хэсэгт байх үедээ л таны байршлыг нарийн тогтоох боломжтой. Апп эдгээр байршлын үйлчилгээг ашиглахын тулд эдгээрийг таны утсан дээр асааж идэвхтэй байлгах шаардлагатай. Энэ нь батарейны хэрэглээг ихэсгэж болзошгүй."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"ойролцоох байршилд (сүлжээнд суурилсан) зөвхөн дэлгэц дээр хандах"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Энэ апп зөвхөн дэлгэц дээр байх үед үүрэн цамхаг, Wi-Fi сүлжээ зэрэг сүлжээний эх сурвалжид тулгуурлан таны байршлыг мэдэх боломжтой. Та энэ аппад эдгээр байршлын үйлчилгээг ашиглуулахын тулд эдгээрийг таблет дээрээ асааж, боломжтой байлгах шаардлагатай."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Энэ апп зөвхөн дэлгэц дээр байх үед үүрэн цамхаг, Wi-Fi сүлжээ зэрэг сүлжээний эх сурвалжид тулгуурлан таны байршлыг мэдэх боломжтой. Та энэ аппад эдгээр байршлын үйлчилгээг ашиглуулахын тулд эдгээрийг Android TB төхөөрөмж дээрээ асааж, боломжтой байлгах шаардлагатай."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Энэ апп зөвхөн дэлгэц дээр байх үед үүрэн цамхаг, Wi-Fi сүлжээ зэрэг сүлжээний эх сурвалжид тулгуурлан таны байршлыг мэдэх боломжтой. Та энэ аппад эдгээр байршлын үйлчилгээг ашиглуулахын тулд эдгээрийг утсан дээрээ асааж, боломжтой байлгах шаардлагатай."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Энэ апп нь зөвхөн дэлгэц дээр байх үедээ л таны байршлыг нарийн тогтоох боломжтой. Байршлын үйлчилгээ нь таны төхөөрөмж дээр асаалттай, апп ашиглах боломжтой байх ёстой. Энэ нь батарейны хэрэглээг нэмэгдүүлж болзошгүй."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"зөвхөн дэлгэц дээр байхад ойролцоо байршилд хандах"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Энэ апп нь зөвхөн дэлгэц дээр байх үедээ л таны байршлыг ойролцоогоор тогтоох боломжтой. Байршлын үйлчилгээ нь таны төхөөрөмж дээр асаалттай, апп ашиглах боломжтой байх ёстой."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"байршилд ард хандах"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Хэрэв үүнийг ойролцоо эсвэл нарийвчилсан байршлын хандалтад нэмэлтээр зөвшөөрсөн бол энэ апп ард ажиллах явцдаа байршилд хандаж болно."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Энэ апп нь дэлгэц дээр байхдаа байршилд хандахаас гадна арын хэсэгт ажиллах үедээ байршилд хандах боломжтой."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"Аудио тохиргоо солих"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Апп нь дууны хэмжээ, спикерын гаралтад ашиглагдах глобал аудио тохиргоог өөрчлөх боломжтой."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"аудио бичих"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Апп нь таблет дээрх блютүүт тохиргоог харах боломжтой ба хос болох төхөөрөмжтэй холболтыг зөвшөөрөх болон хийх боломжтой."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Аппад таны Android ТВ төхөөрөмж дээрх Bluetooth-н тохируулгыг харах болон хослуулсан төхөөрөмжүүдтэй холболт хийж, холболтыг баталгаажуулахыг зөвшөөрнө."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Апп нь утсан дээрх Bluetooth тохиргоог харах боломжтой ба хос болох төхөөрөмжтэй холболтыг зөвшөөрөх болон хийх боломжтой."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ойролцоо талбарын холбоог удирдах"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Апп нь Ойролцоо Талбарын Холболт(NFC) таг, карт, болон уншигчтай холбогдох боломжтой."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"дэлгэцний түгжээг идэвхгүй болгох"</string>
@@ -1757,8 +1758,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Таны админ шинэчилсэн"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Таны админ устгасан"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string>
- <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Батарейны ажиллах хугацааг уртасгахын тулд Батарей хэмнэгч нь:\n·Бараан загварыг асаадаг\n·Арын үйл ажиллагаа, зарим визуал эффект болон “Hey Google” зэрэг бусад онцлогийг унтрааж эсвэл хязгаарладаг\n\n"<annotation id="url">"Нэмэлт мэдээлэл авах"</annotation></string>
- <string name="battery_saver_description" msgid="7618492104632328184">"Батарейны ажиллах хугацааг уртасгахын тулд Батарей хэмнэгч нь:\n·Бараан загварыг асаадаг\n·Арын үйл ажиллагаа, зарим визуал эффект болон “Hey Google” зэрэг бусад онцлогийг унтрааж эсвэл хязгаарладаг"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="1817385558636532621">"Батарейн ажиллах хугацааг уртасгахын тулд Батарей хэмнэгч нь:\n·Бараан загварыг асаадаг\n·Арын үйл ажиллагаа, зарим визуал эффект болон “Hey Google” зэрэг бусад онцлогийг унтрааж эсвэл хязгаарладаг\n\n"<annotation id="url">"Нэмэлт мэдээлэл авах"</annotation></string>
+ <string name="battery_saver_description" msgid="7618492104632328184">"Батарейн ажиллах хугацааг уртасгахын тулд Батарей хэмнэгч нь:\n·Бараан загварыг асаадаг\n·Арын үйл ажиллагаа, зарим визуал эффект болон “Hey Google” зэрэг бусад онцлогийг унтрааж эсвэл хязгаарладаг"</string>
<string name="data_saver_description" msgid="4995164271550590517">"Дата ашиглалтыг багасгахын тулд дата хэмнэгч нь зарим апп-н өгөгдлийг дэвсгэрт илгээх болон авахаас сэргийлдэг. Таны одоогийн ашиглаж буй апп нь өгөгдөлд хандах боломжтой хэдий ч тогтмол хандахгүй. Жишээлбэл зургийг товших хүртэл харагдахгүй."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Дата хэмнэгчийг асаах уу?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Асаах"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>-д холбогдсон"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Файлыг үзэхийн тулд дарна уу"</string>
<string name="pin_target" msgid="8036028973110156895">"PIN"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Unpin"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Апп-н мэдээлэл"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Жишээг эхлүүлж байна…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Эдгээр зүйлийг буюу <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> болон <xliff:g id="TYPE_2">%3$s</xliff:g>-г "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"-д шинэчлэх үү?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Хадгалах"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Үгүй, баярлалаа"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Одоо биш"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Хэзээ ч үгүй"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Шинэчлэх"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Үргэлжлүүлэх"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"нууц үг"</string>
@@ -1956,7 +1963,7 @@
<string name="notification_appops_overlay_active" msgid="5571732753262836481">"таны дэлгэцэд бусад аппын дээр харуулж байна"</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_summary" msgid="4141614604437372157">"Батарейн ажиллах хугацааг уртасгахын тулд Батарей хэмнэгчийг идэвхжүүллээ"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Батарей хэмнэгч"</string>
<string name="battery_saver_sticky_disabled_notification_title" msgid="616803848887159814">"Батарей хэмнэгч батарейг дахин багасах хүртэл дахин идэвхжихгүй"</string>
<string name="battery_saver_sticky_disabled_notification_summary" msgid="9091127514013090563">"Батарейг хангалттай түвшинд цэнэглэлээ. Батарей хэмнэгч батарейг дахин багасах хүртэл дахин идэвхжихгүй."</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Дэлгэц хуваахыг унтраах/асаах"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Дэлгэцийг түгжих"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Дэлгэцийн зураг дарах"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Үзэгдэх цонхонд байгаа <xliff:g id="APP_NAME">%1$s</xliff:g> апп."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>-н гарчгийн талбар."</string>
</resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 2782caf..9e38391 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"कार्य प्रोफाइल प्रशासक अॅप गहाळ आहे किंवा करप्ट आहे. परिणामी, तुमचे कार्य प्रोफाइल आणि संबंधित डेटा हटवले गेले आहेत. सहाय्यासाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"तुमचे कार्य प्रोफाइल आता या डिव्हाइसवर उपलब्ध नाही"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"बर्याचदा पासवर्ड टाकण्याचा प्रयत्न केला"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"वैयक्तिक वापरासाठी ॲडमिनने नियंत्रण सोडलेले डिव्हाइस"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"डिव्हाइस व्यवस्थापित केले आहे"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"तुमची संस्था हे डिव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे निरीक्षण करू शकते. तपशीलांसाठी टॅप करा."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"तुमचे डिव्हाइस मिटविले जाईल"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"चिकट प्रसारणे पाठविण्यासाठी ॲपला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो तुमच्या Android TV डिव्हाइसला धीमा किंवा अस्थिर करू शकतो."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"रोचक प्रसारणे पाठविण्यासाठी अॅप ला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो फोनला धीमा किंवा अस्थिर करू शकतो."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"तुमचे संपर्क वाचा"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"तुम्ही कॉल केलेल्या, ईमेल केलेल्या किंवा विशिष्ट लोकांशी अन्य मार्गांनी संवाद प्रस्थापित केलेल्या लोकांच्या फ्रिक्वेन्सीसह, आपल्या टॅब्लेटवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा वाचण्यासाठी अॅप ला अनुमती देते. ही परवानगी तुमचा संपर्क डेटा सेव्ह करण्याची अॅप्स ला अनुमती देते आणि दुर्भावनापूर्ण अॅप्स आपल्या माहितीशिवाय संपर्क डेटा शेअर करू शकतात."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"तुम्ही केलेले कॉल, केलेले ईमेल किंवा विशिष्ट संपर्कांसह अन्य मार्गांनी केलेले कम्युनिकेशन यांची वारंवारता, यासह तुमच्या Android TV डिव्हाइसवर स्टोअर केलेल्या तुमच्या संपर्कांविषयीचा डेटा वाचण्याची ॲपला अनुमती देते. ही परवानगी अॅप्सना तुमचा संपर्क डेटा सेव्ह करण्याची अनुमती देते आणि ही दुर्भावनापूर्ण अॅप्स तुम्हाला न कळवता संपर्क डेटा शेअर करू शकतात."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"तुम्ही कॉल केलेल्या, ईमेल केलेल्या किंवा विशिष्ट लोकांशी अन्य मार्गांनी संवाद प्रस्थापित केलेल्या लोकांच्या फ्रिक्वेन्सीसह, आपल्या फोनवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा वाचण्यासाठी अॅप ला अनुमती देते. ही परवानगी तुमचा संपर्क डेटा सेव्ह करण्याची अॅप्स ला अनुमती देते आणि दुर्भावनापूर्ण अॅप्स आपल्या माहितीशिवाय संपर्क डेटा शेअर करू शकतात."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"तुमच्या टॅबलेटवर स्टोअर केलेल्या तुमच्या संपर्कांविषयीचा डेटा वाचण्याची ॲपला अनुमती देते. अॅप्सना संपर्क तयार केलेल्या तुमच्या टॅबलेटवरील खात्याचा अॅक्सेसदेखील असेल. यामध्ये तुम्ही इंस्टॉल केलेल्या ॲप्सने तयार केलेल्या खात्यांचा समावेश असू शकतात. ही परवानगी ॲप्सना तुमचा संपर्क डेटा सेव्ह करण्याची अनुमती देते आणि दुर्भावनापूर्ण ॲप्स तुम्हाला न कळवता संपर्क डेटा शेअर करू शकतात."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"तुमच्या Android TV डिव्हाइस स्टोअर केलेल्या तुमच्या संपर्कांविषयीचा डेटा वाचण्याची ॲपला अनुमती देते. अॅप्सना संपर्क तयार केलेल्या तुमच्या Android TV डिव्हाइसवरील खात्याचा अॅक्सेसदेखील असेल. यामध्ये तुम्ही इंस्टॉल केलेल्या ॲप्सने तयार केलेल्या खात्यांचा समावेश असू शकतात. ही परवानगी ॲप्सना तुमचा संपर्क डेटा सेव्ह करण्याची अनुमती देते आणि दुर्भावनापूर्ण ॲप्स तुम्हाला न कळवता संपर्क डेटा शेअर करू शकतात."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"तुमच्या फोनवर स्टोअर केलेल्या तुमच्या संपर्कांविषयीचा डेटा वाचण्याची ॲपला अनुमती देते. अॅप्सना संपर्क तयार केलेल्या तुमच्या फोनवरील खात्याचा अॅक्सेसदेखील असेल. यामध्ये तुम्ही इंस्टॉल केलेल्या ॲप्सने तयार केलेल्या खात्यांचा समावेश असू शकतात. ही परवानगी ॲप्सना तुमचा संपर्क डेटा सेव्ह करण्याची अनुमती देते आणि दुर्भावनापूर्ण ॲप्स तुम्हाला न कळवता संपर्क डेटा शेअर करू शकतात."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"तुमचे संपर्क सुधारित करा"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"तुम्ही विशिष्ट संपर्कांशी अन्य मार्गांनी कॉल केलेल्या, ईमेल केलेल्या किंवा संवाद प्रस्थापित केलेल्या फ्रिक्वेन्सीसह, आपल्या टॅब्लेटवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा सुधारित करण्यासाठी अॅप ला अनुमती देते. ही परवानगी संपर्क डेटा हटविण्यासाठी अॅप ला अनुमती देते."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"तुम्ही विशिष्ट संपर्कांशी कॉल, ईमेल किंवा इतर मार्गांनी संवाद प्रस्थापित केल्याची वारंवारता यांच्या समावेशासह, तुमच्या Android TV वर स्टोअर केलेल्या तुमच्या संपर्कांविषयीचा डेटा सुधारित करण्यासाठी ॲपला अनुमती देते. ही परवानगी ॲपला संपर्क डेटा हटविण्यासाठी अनुमती देते."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"तुम्ही विशिष्ट संपर्कांशी अन्य मार्गांनी कॉल केलेल्या, ईमेल केलेल्या किंवा संवाद प्रस्थापित केलेल्या फ्रिक्वेन्सीसह, आपल्या फोनवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा सुधारित करण्यासाठी अॅप ला अनुमती देते. ही परवानगी संपर्क डेटा हटविण्यासाठी अॅप ला अनुमती देते."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"तुमच्या टॅबलेटवर स्टोअर केलेल्या तुमच्या संपर्कांविषयीच्या डेटामध्ये बदल करण्यासाठी अॅपला अनुमती देते. ही परवानगी अॅप्सला संपर्क डेटा हटवण्याची परवानगी देते."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Android TV वर स्टोअर केलेल्या तुमच्या संपर्कांविषयीच्या डेटामध्ये बदल करण्यासाठी अॅपला अनुमती देते. ही परवानगी अॅप्सला संपर्क डेटा हटवण्याची परवानगी देते."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"तुमच्या फोनवर स्टोअर केलेल्या तुमच्या संपर्कांविषयीच्या डेटामध्ये बदल करण्यासाठी अॅपला अनुमती देते. ही परवानगी अॅप्सला संपर्क डेटा हटवण्याची परवानगी देते."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"कॉल लॉग वाचा"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"हा अॅप तुमचा कॉल इतिहास वाचू शकता."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"कॉल लॉग लिहा"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"अतिरिक्त स्थान प्रदाता आदेश अॅक्सेस करा"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"अॅपला अतिरिक्त स्थान प्रदाता आदेशावर प्रवेश करण्याची अनुमती देते. हे कदाचित अॅपला GPS किंवा इतर स्थान स्रोत च्या ऑपरेशनमध्ये हस्तक्षेप करण्याची अनुमती देऊ शकते."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"फक्त फोरग्राउंडमध्ये अचूकपणे अॅक्सेस करा"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"हे अॅप फक्त फोरग्राउंडमध्ये असतानाच तुमचे अचूक स्थान मिळवू शकते. या स्थान सेवा सुरू करणे आणि त्या वापरण्यासाठी अॅपसाठी तुमच्या फोनवर उपलब्ध करणे आवश्यक आहे, यामुळे बॅटरी वापर वाढू शकतो."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"फक्त फोरग्राउंडमध्ये अंदाजे स्थान (नेटवर्क आधारित) अॅक्सेस करा"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"हे अॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. त्या वापरण्याकरता अॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या टॅबलेटवर उपलब्ध करणे आवश्यक आहे."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"हे ॲप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. ॲपने वापरण्याकरिता, या स्थान सेवा सुरू करणे आणि त्या तुमच्या Android TV डिव्हाइसवर उपलब्ध करणे आवश्यक आहे."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"हे अॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. ते वापरण्याकरता अॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या फोनवर उपलब्ध करणे आवश्यक आहे."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"हे अॅप फक्त फोरग्राउंडमध्ये असतानाच तुमचे अचूक स्थान मिळवू शकते. स्थातुमच्या डिव्हाइसवर स्थान सेवा सुरू असणे आणि उपलब्ध असणे आवश्यक आहे जेणेकरून ॲप त्यांचा वापर करू शकतील. यामुळे बॅटरी वापर वाढू शकतो."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"फक्त फोअरग्राउंडमध्ये अचूक स्थान अॅक्सेस करा"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"हे अॅप फक्त फोरग्राउंडमध्ये असताना तुमचे अचूक स्थान मिळवू शकते. तुमच्या डिव्हाइसवर स्थान सेवा सुरू असणे आणि उपलब्ध असणे आवश्यक आहे जेणेकरून ॲप त्यांचा वापर करू शकतील."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"बॅकग्राउंडमध्ये स्थान अॅक्सेस करू शकतो"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"याला अंदाजे किंवा अचूक स्थान अॅक्सेस करण्यास अतिरिक्त मंजूरी दिल्यास, बॅकग्राउंडमध्ये चालतांना अॅप स्थान अॅक्सेस करू शकतो."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"हे अॅप फोरग्राउंड स्थान ॲक्सेस व्यतिरिक्त, बॅकग्राउंडमध्ये सुरू असताना स्थान ॲक्सेस करू शकते."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"आपल्या ऑडिओ सेटिंग्ज बदला"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"व्हॉल्यूम आणि आउटपुटसाठी कोणता स्पीकर वापरला आहे यासारख्या समग्र ऑडिओ सेटिंग्ज सुधारित करण्यासाठी अॅप ला अनुमती देते."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ऑडिओ रेकॉर्ड"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"टॅबलेटवर ब्लूटूथ चे कॉंफिगरेशन पाहण्यासाठी आणि पेअर केलेल्या डीव्हाइससह कनेक्शन इंस्टॉल करण्यासाठी आणि स्वीकारण्यासाठी, अॅप ला अनुमती देते."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Android TV डिव्हाइसवर ब्लूटूथ चे कॉंफिगरेशन पाहण्यासाठी आणि पेअर केलेल्या डीव्हाइससह कनेक्शन तयार करण्यासाठी आणि स्वीकारण्यासाठी, ॲपला अनुमती देते."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"फोनवर ब्लूटूथ चे कॉंफिगरेशन पाहण्यासाठी आणि पेअर केलेल्या डीव्हाइससह कनेक्शन इंस्टॉल करण्यासाठी आणि स्वीकारण्यासाठी, अॅप ला अनुमती देते."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"फील्ड जवळील कम्युनिकेशन नियंत्रित करा"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"फील्ड जवळील कम्युनिकेशन (NFC) टॅग, कार्डे आणि वाचक यांच्यासह संवाद करण्यासाठी ॲपला अनुमती देते."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"तुमचे स्क्रीन लॉक अक्षम करा"</string>
@@ -900,7 +901,7 @@
<string name="factorytest_no_action" msgid="339252838115675515">"FACTORY_TEST क्रिया प्रदान करणारे कोणतेही पॅकेज आढळले नाही."</string>
<string name="factorytest_reboot" msgid="2050147445567257365">"रीबूट करा"</string>
<string name="js_dialog_title" msgid="7464775045615023241">"\"<xliff:g id="TITLE">%s</xliff:g>\" वरील पृष्ठ हे म्हणते:"</string>
- <string name="js_dialog_title_default" msgid="3769524569903332476">"Javascript"</string>
+ <string name="js_dialog_title_default" msgid="3769524569903332476">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="7012587995876771246">"नेव्हिगेशनची पुष्टी करा"</string>
<string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"हे पृष्ठ सोडा"</string>
<string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"या पेजवर रहा"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> शी कनेक्ट केलेले"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"फायली पाहण्यासाठी टॅप करा"</string>
<string name="pin_target" msgid="8036028973110156895">"पिन"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"अनपिन करा"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"अॅप माहिती"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"डेमो प्रारंभ करत आहे..."</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"हे आयटम "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> आणि <xliff:g id="TYPE_2">%3$s</xliff:g> मध्ये अपडेट करायचे का?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"सेव्ह करा"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"नाही, नको"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"आता नाही"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"कधीही नाही"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"अपडेट करा"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"पुढे सुरू ठेवा"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"पासवर्ड"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"विभाजित स्क्रीन टॉगल करा"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"स्क्रीन लॉक करा"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"स्क्रीनशॉट"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"पॉप-अप विंडोमध्ये <xliff:g id="APP_NAME">%1$s</xliff:g> ॲप."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> चा शीर्षक बार."</string>
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index a40eca0..0670fad 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Apl pentadbir profil kerja tiada atau rosak. Akibatnya, profil kerja anda dan data yang berkaitan telah dipadamkan. Hubungi pentadbir anda untuk mendapatkan bantuan."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profil kerja anda tidak lagi tersedia pada peranti ini"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Terlalu banyak percubaan kata laluan"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Pentadbir melepaskan peranti untuk kegunaan peribadi"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Peranti ini diurus"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasi anda mengurus peranti ini dan mungkin memantau trafik rangkaian. Ketik untuk mendapatkan butiran."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Peranti anda akan dipadam"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Membenarkan apl menghantar siaran lekit, yang kekal selepas siaran tamat. Penggunaan secara berlebihan boleh menyebabkan peranti Android TV anda menjadi perlahan atau tidak stabil kerana menggunakan terlalu banyak memori."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Membenarkan apl untuk menghantar siaran melekit, yang kekal selepas siaran berakhir. Penggunaan berlebihan boleh membuat telefon perlahan atau tidak stabil dengan menyebabkannya menggunakan memori yang terlalu banyak."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"baca kenalan anda"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Membenarkan apl membaca data tentang kenalan anda yang tersimpan di tablet anda, termasuk kekerapan anda memanggil, menghantar e-mel atau berkomunikasi dalam cara lain dengan individu tertentu. Kebenaran ini membenarkan apl untuk menyimpan data kenalan anda dan apl hasad boleh berkongsi data kenalan anda tanpa pengetahuan anda."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Membenarkan apl membaca data tentang kenalan anda yang tersimpan pada peranti Android TV, termasuk kekerapan anda membuat panggilan, menghantar e-mel atau berkomunikasi melalui cara lain dengan individu tertentu. Kebenaran ini membenarkan apl menyimpan data kenalan anda dan apl hasad mungkin berkongsi data kenalan tanpa pengetahuan anda."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Membenarkan apl membaca data tentang kenalan anda yang tersimpan di telefon anda, termasuk kekerapan anda memanggil, menghantar e-mel atau berkomunikasi dalam cara lain dengan individu tertentu. Kebenaran ini membenarkan apl untuk menyimpan data kenalan anda dan apl hasad boleh berkongsi data kenalan anda tanpa pengetahuan anda."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Membenarkan apl membaca data tentang kenalan anda yang tersimpan pada tablet anda. Apl juga akan mempunyai akses kepada akaun pada tablet anda yang telah dibuat kenalan. Ini mungkin termasuk akaun yang dibuat oleh apl yang telah anda pasang. Kebenaran ini membolehkan apl menyimpan data kenalan anda dan apl hasad mungkin berkongsi data kenalan tanpa pengetahuan anda."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Membenarkan apl membaca data tentang kenalan anda yang tersimpan pada peranti Android TV anda. Apl juga akan mempunyai akses kepada akaun pada peranti Android TV anda yang telah dibuat kenalan. Ini mungkin termasuk akaun yang dibuat oleh apl yang telah anda pasang. Kebenaran ini membolehkan apl menyimpan data kenalan anda dan apl hasad mungkin berkongsi data kenalan tanpa pengetahuan anda."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Membenarkan apl membaca data tentang kenalan anda yang tersimpan pada telefon anda. Apl juga mempunyai akses kepada akaun pada telefon anda yang telah dibuat kenalan. Ini mungkin termasuk akaun yang dibuat oleh apl yang telah anda pasang. Kebenaran ini membolehkan apl menyimpan data kenalan anda dan apl hasad mungkin berkongsi data kenalan tanpa pengetahuan anda."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"ubah suai kenalan anda"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Membenarkan apl mengubah suai data tentang kenalan anda yang tersimpan pada tablet anda, termasuk kekerapan siapa anda panggil, hantar e-mel atau berkomunikasi dalam cara lain dengan kenalan tertentu. Kebenaran ini membenarkan apl untuk memadam data kenalan."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Membenarkan apl mengubah suai data tentang kenalan anda yang tersimpan pada peranti Android TV anda, termasuk kekerapan anda membuat panggilan, menghantar e-mel atau berkomunikasi melalui cara lain dengan kenalan tertentu. Kebenaran ini membenarkan apl memadam data kenalan."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Membenarkan apl mengubah suai data tentang kenalan anda yang tersimpan pada telefon anda, termasuk kekerapan siapa anda panggil, hantar e-mel atau berkomunikasi dalam cara lain dengan kenalan tertentu. Kebenaran ini membenarkan apl untuk memadam data kenalan."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Membenarkan apl mengubah suai data tentang kenalan anda yang tersimpan pada tablet anda. Kebenaran ini membenarkan apl memadamkan data kenalan."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Membenarkan apl mengubah suai data tentang kenalan anda yang tersimpan pada peranti Android TV anda. Kebenaran ini membenarkan apl memadamkan data kenalan."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Membenarkan apl mengubah suai data tentang kenalan anda yang tersimpan pada telefon anda. Kebenaran ini membenarkan apl memadamkan data kenalan."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"baca log panggilan"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Apl ini boleh membaca sejarah panggilan anda."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"tulis log panggilan"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"akses perintah tambahan pembekal lokasi"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Membenarkan apl mengakses arahan pembekal lokasi tambahan. Ini boleh membenarkan apl untuk campur tangan dengan operasi GPS atau sumber lokasi lain."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"akses lokasi tepat hanya di latar depan"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Apl ini boleh mendapatkan lokasi tepat anda hanya apabila apl tersebut berada di latar depan. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada telefon anda untuk membolehkan apl menggunakan perkhidmatan tersebut. Tindakan ini mungkin meningkatkan penggunaan bateri."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"akses lokasi anggaran (berdasarkan rangkaian) hanya di latar depan"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Apl ini boleh mendapatkan lokasi anda berdasarkan sumber rangkaian seperti menara selular dan rangkaian Wi-Fi, tetapi hanya apabila apl itu di latar depan. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada tablet anda untuk membolehkan apl menggunakan perkhidmatan tersebut."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Apl ini boleh mendapatkan lokasi anda berdasarkan sumber rangkaian seperti menara selular dan rangkaian Wi-Fi, tetapi hanya apabila apl itu di latar depan. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada peranti Android TV anda untuk membolehkan apl menggunakan perkhidmatan tersebut."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Apl ini boleh mendapatkan lokasi anda berdasarkan sumber rangkaian seperti menara selular dan rangkaian Wi-Fi, tetapi hanya apabila apl itu di latar depan. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada telefon anda untuk membolehkan apl menggunakan perkhidmatan tersebut."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Apl ini boleh mendapatkan lokasi tepat anda hanya apabila apl tersebut berada di latar depan. Perkhidmatan lokasi mesti dihidupkan dan tersedia pada peranti anda untuk membolehkan apl menggunakan perkhidmatan tersebut. Tindakan ini mungkin meningkatkan penggunaan bateri."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"akses lokasi anggaran hanya di latar depan"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Apl ini boleh mendapatkan lokasi anggaran anda hanya apabila apl tersebut berada di latar depan. Perkhidmatan lokasi mesti dihidupkan dan tersedia pada peranti anda untuk membolehkan apl menggunakan perkhidmatan tersebut."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"akses lokasi di latar belakang"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Jika tindakan ini dibenarkan bagi akses lokasi anggaran atau lokasi tepat, apl tersebut boleh mengakses lokasi itu semasa berjalan di latar belakang."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Apl ini boleh mengakses lokasi semasa berjalan di latar belakang, di samping akses lokasi di latar depan."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"tukar tetapan audio anda"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Membenarkan apl untuk mengubah suai tetapan audio global seperti kelantangan dan pembesar suara mana digunakan untuk output."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"rakam audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Membenarkan apl melihat konfigurasi Bluetooth pada tablet dan untuk membuat serta menerima sambungan dengan peranti yang dipasangkan."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Membenarkan apl melihat konfigurasi Bluetooth pada peranti Android TV anda dan membuat serta menerima sambungan dengan peranti yang digandingkan."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Membenarkan apl melihat konfigurasi Bluetooth pada telefon dan membuat serta menerima sambungan dengan peranti yang dipasangkan."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"mengawal Komunikasi Medan Dekat"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Membenarkan apl berkomunikasi dengan teg, kad dan pembaca Komunikasi Medan Dekat (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"lumpuhkan kunci skrin anda"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Disambungkan ke <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Ketik untuk melihat fail"</string>
<string name="pin_target" msgid="8036028973110156895">"Semat"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Nyahsemat"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Maklumat apl"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Memulakan tunjuk cara…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Kemas kini item ini dalam "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> dan <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Simpan"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Tidak, terima kasih"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Bukan sekarang"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Jangan"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Kemas kini"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Teruskan"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"kata laluan"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Togol Skrin Pisah"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Skrin Kunci"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Tangkapan skrin"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Apl <xliff:g id="APP_NAME">%1$s</xliff:g> dalam tetingkap Timbul."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Bar kapsyen <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 64e2376..67c5f89 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"အလုပ်ပရိုဖိုင် စီမံခန့်ခွဲရန်အက်ပ် မရှိပါ သို့မဟုတ် ပျက်စီးနေပါသည်။ ထို့ကြောင့် သင်၏ အလုပ်ပရိုဖိုင်နှင့် ဆက်စပ်နေသော ဒေတာများကို ဖျက်လိုက်ပါပြီ။ အကူအညီရယူရန် သင်၏စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ဤစက်ပစ္စည်းတွင် သင်၏ အလုပ်ပရိုဖိုင်မရှိတော့ပါ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"စကားဝှက်ထည့်သွင်းရန် ကြိုးစားသည့် အကြိမ်အရေအတွက် အလွန်များသွား၍ ဖြစ်ပါသည်"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"ပုဂ္ဂိုလ်ရေးအသုံးပြုရန်အတွက် စီမံခန့်ခွဲသူက စက်ပစ္စည်းထိန်းချုပ်မှုကို ရပ်တန့်လိုက်သည်"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"စက်ပစ္စည်းကို စီမံခန့်ခွဲထားပါသည်"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ဤစက်ပစ္စည်းကို သင်၏ အဖွဲ့အစည်းက စီမံပြီး ကွန်ရက်အသွားအလာကို စောင့်ကြည့်နိုင်ပါသည်။ ထပ်မံလေ့လာရန် တို့ပါ။"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"သင့်ကိရိယာအား ပယ်ဖျက်လိမ့်မည်"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"ထုတ်လွှင့်ခြင်းများ ပြီးဆုံးသွားသည့်နောက် ဆက်လက်တည်ရှိနေသည့် ထုတ်လွှင့်မှုများကို အက်ပ်အား ပို့ခွင့်ပြုသည်။ အလွန်အကျွံအသုံးပြုပါက မှတ်ဉာဏ်အသုံးပြုမှု လွန်ကဲပြီး သင့် Android TV စက်ကို နှေးကွေးစေခြင်း သို့မဟုတ် မတည်ငြိမ်ခြင်းတို့ ဖြစ်စေနိုင်သည်။"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"အက်ပ်အား ကြာရှည်ခံ ထုတ်လွှင့်မှု ပြုပါ။ ဤထုတ်လွှင့်မှုများဟာ ထုတ်လွှင့်မှု ပြီးဆုံးပြီးသွားတည့်တိုင် ကျန်နေမည် ဖြစ်ပါသည်။ အလွန်အကျွံသုံးခြင်းကြောင့် မှတ်ဉာဏ်အသုံးများပြီး ဖုန်းနှေးခြင်း၊ မတည်ငြိမ်ခြင်း ဖြစ်နိုင်ပါသည်"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"အဆက်အသွယ်များအား ဖတ်ခြင်း"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"အပလီကေးရှင်းအား ခေါ်ဆိုသော အကြိမ်ရေ၊ အီးမေးလ်အကြိမ်ရေ၊ တခြားဆက်သွယ်မှုများစသည်ကဲ့သို့ သင့်တက်ဘလက်မှာ သိမ်းဆည်းထားသော အဆက်အသွယ်များရဲ့ အချက်အလက်ကို ဖတ်ခွင့်ပြုပါ။ ဤသို့ခွင့်ပြုခြင်းအားဖြင့် အပလီကေးရှင်းများကို သင့် အဆက်အသွယ်၏ အချက်မလက်များကို သိမ်းရန် ခွင့်ပြုပြီး အန္တရာယ်ရှိသော အပလီကေးရှင်းများမှ ထိုအချက်အလက်များ ကို သင် မသိစေပဲ ဖြန့်ဝေနိုင််မည် ဖြစ်ပါသည်။"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"အချို့သော လူပုဂ္ဂိုလ်များသို့ ခေါ်ဆိုသော၊ အီးမေးလ်ပို့သော သို့မဟုတ် အခြားနည်းလမ်းဖြင့် ဆက်သွယ်သော အကြိမ်ရေများအပါအဝင် သင့် Android TV စက်ပေါ်တွင် သိမ်းဆည်းထားသည့် အဆက်အသွယ်များအကြောင်း ဒေတာများကို အက်ပ်အား မွမ်းမံခွင့်ပြုသည်။ ဤခွင့်ပြုချက်သည် သင်၏ အဆက်အသွယ်ဒေတာကို အက်ပ်အား သိမ်းခွင့်ပေးသောကြောင့် သံသယဖြစ်ဖွယ်အက်ပ်များသည် သင်မသိဘဲ အဆက်အသွယ်ဒေတာများကို မျှဝေနိုင်သည်။"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"အပလီကေးရှင်းအား ခေါ်ဆိုသော အကြိမ်ရေ၊ အီးမေးလ်အကြိမ်ရေ၊ တခြားဆက်သွယ်မှုများစသည်ကဲ့သို့ သင့်ဖုန်းမှာ သိမ်းဆည်းထားသော အဆက်အသွယ်များရဲ့ အချက်အလက်ကို ဖတ်ခွင့်ပြုပါ။ ဤသို့ခွင့်ပြုခြင်းအားဖြင့် အပလီကေးရှင်းများကို သင့် အဆက်အသွယ်၏ အချက်မလက်များကို သိမ်းရန် ခွင့်ပြုပြီး အန္တရာယ်ရှိသော အပလီကေးရှင်းများမှ ထိုအချက်အလက်များ ကို သင် မသိစေပဲ ဖြန့်ဝေနိုင််မည် ဖြစ်ပါသည်။"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"သင့်တက်ဘလက်ထဲတွင် သိမ်းဆည်းထားသော အဆက်အသွယ်များ၏ အချက်အလက်ကို အက်ပ်အား ဖတ်ခွင့်ပြုသည်။ အက်ပ်သည် သင့်တက်ဘလက် မှတစ်ဆင့် အဆက်အသွယ်များကို ပြုလုပ်ထားသော အကောင့်များကို အသုံးပြုခွင့် ရလိမ့်မည်။ သင်ထည့်သွင်းထားသော အက်ပ်များမှတစ်ဆင့် ပြုလုပ်ထားသော အကောင့်များ ပါဝင်နိုင်ပါသည်။ ဤခွင့်ပြုချက်က သင့်အဆက်အသွယ်၏ အချက်အလက်များကို အက်ပ်များအား သိမ်းခွင့်ပြုပြီး အန္တရာယ်ရှိသော အက်ပ်များက ထိုအချက်အလက်များကို သင်မသိဘဲ ဖြန့်ဝေနိုင်သည်။"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"သင်၏ Android TV ထဲတွင် သိမ်းဆည်းထားသော အဆက်အသွယ်များ၏ အချက်အလက်ကို အက်ပ်အား ဖတ်ခွင့်ပြုသည်။ အက်ပ်သည် သင့် Android TV မှတစ်ဆင့် အဆက်အသွယ်များကို ပြုလုပ်ထားသော အကောင့်များကို အသုံးပြုခွင့် ရလိမ့်မည်။ သင်ထည့်သွင်းထားသော အက်ပ်များမှတစ်ဆင့် ပြုလုပ်ထားသော အကောင့်များ ပါဝင်နိုင်ပါသည်။ ဤခွင့်ပြုချက်က သင့်အဆက်အသွယ်၏ အချက်အလက်များကို အက်ပ်များအား သိမ်းခွင့်ပြုပြီး အန္တရာယ်ရှိသော အက်ပ်များက ထိုအချက်အလက်များကို သင်မသိဘဲ ဖြန့်ဝေနိုင်သည်။"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"သင်၏ ဖုန်းထဲတွင် သိမ်းဆည်းထားသော အဆက်အသွယ်များ၏ အချက်အလက်ကို အက်ပ်အား ဖတ်ခွင့်ပြုသည်။ အက်ပ်သည် သင့်ဖုန်းမှတစ်ဆင့် အဆက်အသွယ်များကို ပြုလုပ်ထားသော အကောင့်များကို အသုံးပြုခွင့် ရလိမ့်မည်။ သင်ထည့်သွင်းထားသော အက်ပ်များမှတစ်ဆင့် ပြုလုပ်ထားသော အကောင့်များ ပါဝင်နိုင်ပါသည်။ ဤခွင့်ပြုချက်က သင့်အဆက်အသွယ်၏ အချက်အလက်များကို အက်ပ်များအား သိမ်းခွင့်ပြုပြီး အန္တရာယ်ရှိသော အက်ပ်များက ထိုအချက်အလက်များကို သင်မသိဘဲ ဖြန့်ဝေနိုင်သည်။"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"အဆက်အသွယ်များအား ပြင်ဆင်ခြင်း"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"အပလီကေးရှင်းအား သင့်တက်ဘလက်မှာ သိမ်းဆည်းထားသော အဆက်အသွယ်များရဲ့ အချက်အလက် (အထူးအဆက်အသွယ်များအား ခေါ်ဆိုသော အကြိမ်ရေ၊ အီးမေးလ်ပို့သောအကြိမ်ရေ သို့ အခြားနည်းလမ်းဖြင့်ဆက်သွယ်မှုများ) ကို ပြင်ဆင်ခွင့်ပြုခြင်း။ ဒီခွင့်ပြုချက်က အပလီကေးရှင်းများအား အဆက်အသွယ် အချက်အလက်များ ဖျက်စီးခြင်း လုပ်ဆောင်စေနိုင်မှာ ဖြစ်ပါသည်။"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"အချို့သော အဆက်အသွယ်များသို့ ခေါ်ဆိုသော၊ အီးမေးလ်ပို့သော သို့မဟုတ် အခြားနည်းလမ်းဖြင့် ဆက်သွယ်သော အကြိမ်ရေများအပါအဝင် သင့် Android TV စက်ပေါ်တွင် သိမ်းဆည်းထားသည့် အဆက်အသွယ်များအကြောင်း ဒေတာများကို အက်ပ်အား မွမ်းမံခွင့်ပြုသည်။ ဤခွင့်ပြုချက်သည် အဆက်အသွယ်ဒေတာကို အက်ပ်အား ဖျက်ခွင့်ပေးသည်။"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"အပလီကေးရှင်းအား သင့်ဖုန်းမှာ သိမ်းဆည်းထားသော အဆက်အသွယ်များရဲ့ အချက်အလက် (အထူးအဆက်အသွယ်များအား ခေါ်ဆိုသော အကြိမ်ရေ၊ အီးမေးလ်ပို့သောအကြိမ်ရေ သို့ အခြားနည်းလမ်းဖြင့်ဆက်သွယ်မှုများ) ကို ပြင်ဆင်ခွင့်ပြုခြင်း။ ဒီခွင့်ပြုချက်က အပလီကေးရှင်းများအား အဆက်အသွယ် အချက်အလက်များ ဖျက်စီးခြင်း လုပ်ဆောင်စေနိုင်မှာ ဖြစ်ပါသည်။"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"သင့်တက်ဘလက်တွင် သိမ်းဆည်းထားသော အဆက်အသွယ်များ၏ အချက်အလက်ကို ပြင်ဆင်ရန် အက်ပ်အား ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်က အက်ပ်အား သင့်အဆက်အသွယ်များ၏ အချက်အလက်ကို ဖျက်ခွင့်ပြုသည်။"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"သင့် Android TV တွင် သိမ်းဆည်းထားသော အဆက်အသွယ်များ၏ အချက်အလက်ကို ပြင်ဆင်ရန် အက်ပ်အား ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်က အက်ပ်အား သင့်အဆက်အသွယ်များ၏ အချက်အလက်ကို ဖျက်ခွင့်ပြုသည်။"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"သင့်ဖုန်းတွင် သိမ်းဆည်းထားသော အဆက်အသွယ်များ၏ အချက်အလက်ကို ပြင်ဆင်ရန် အက်ပ်အား ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်က အက်ပ်အား သင့်အဆက်အသွယ်များ၏ အချက်အလက်ကို ဖျက်ခွင့်ပြုသည်။"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"ခေါ်ဆိုမှု မှတ်တမ်းအား ဖတ်ခြင်း"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"ဤအက်ပ်သည် သင့်ခေါ်ဆိုမှုမှတ်တမ်းကို ကြည့်ရှုနိုင်ပါသည်။"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"ခေါ်ဆိုမှုမှတ်တမ်း ရေးသားခြင်း"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"တည်နေရာပံ့ပိုးမှုညွှန်ကြားချက်အပိုအား ဝင်ရောက်ကြည့်ခြင်း"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"အက်ပ်အား တည်နေရာ စီမံပေးရေး ညွှန်ကြားချက် အပိုများကို ရယူခွင့်ပြုသည်။ သို့ဖြစ်၍ အက်ပ်သည် GPS သို့မဟုတ် အခြား တည်နေရာ ရင်းမြစ်ကို သုံးကြသူတို့၏ လုပ်ငန်းများကို ဝင်စွက်ခွင့် ပြုနိုင်သည်။"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"မျက်နှာစာတွင်သာ တည်နေရာအတိအကျ အသုံးပြုခြင်း"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"မျက်နှာစာတွင် ဖွင့်ထားမှသာ ဤအက်ပ်က သင်၏တည်နေရာအတိအကျကို ရယူနိုင်ပါသည်။ သင်၏ဖုန်းတွင် အက်ပ်ကအသုံးပြုရန်အတွက် ဤတည်နေရာဝန်ဆောင်မှုများကို ဖွင့်ထားပြီး အသုံးပြု၍ ရပါမည်။ ၎င်းက ဘက်ထရီ ပိုကုန်နိုင်ပါသည်။"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"မျက်နှာစာတွင်သာ (ကွန်ရက် အခြေပြု) တည်နေရာခန့်မှန်း အသုံးပြုခြင်း"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"ဤအက်ပ်က ဆဲလ်တာဝါများနှင့် Wi-Fi ကွန်ရက်များကဲ့သို့ ကွန်ရက်ရင်းမြစ်များအပေါ် အခြေခံပြီး သင်၏တည်နေရာကို ရယူနိုင်သော်လည်း အက်ပ်ကို မျက်နှာစာတွင်ဖွင့်ထားမှ ရပါမည်။ အက်ပ်က အသုံးပြုနိုင်ရန်အတွက် ဤတည်နေရာ ဝန်ဆောင်မှုများကို ဖွင့်ထားရမည် ဖြစ်ပြီး သင့်တက်ဘလက်ပေါ်တွင် ရရှိနိုင်ရပါမည်။"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"ဤအက်ပ်သည် ဆဲလ်တာဝါများနှင့် Wi-Fi ကွန်ရက်များကဲ့သို့ ကွန်ရက်ရင်းမြစ်များပေါ်တွင် အခြေခံပြီး သင်၏တည်နေရာကို ရယူနိုင်သည်၊ သို့သော် အက်ပ်ကို မျက်နှာစာတွင်ဖွင့်ထားရပါမည်။ အက်ပ်က အသုံးပြုနိုင်ရန်အတွက် ဤတည်နေရာ ဝန်ဆောင်မှုများကို ဖွင့်ထားရမည် ဖြစ်ပြီး သင့် Android TV ပေါ်တွင် ရှိမှသာ သုံးနိုင်ပါမည်။"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"ဤအက်ပ်က ဆဲလ်တာဝါများနှင့် Wi-Fi ကွန်ရက်များကဲ့သို့ ကွန်ရက်ရင်းမြစ်များအပေါ် အခြေခံပြီး သင်၏တည်နေရာကို ရယူနိုင်သော်လည်း အက်ပ်ကို မျက်နှာစာတွင်ဖွင့်ထားမှ ရပါမည်။ အက်ပ်က အသုံးပြုနိုင်ရန်အတွက် ဤတည်နေရာ ဝန်ဆောင်မှုများကို ဖွင့်ထားရမည် ဖြစ်ပြီး သင့်ဖုန်းပေါ်တွင် ရရှိနိုင်ရပါမည်။"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"မျက်နှာစာတွင် ဖွင့်ထားမှသာ ဤအက်ပ်က သင်၏ တည်နေရာအတိအကျကို ရယူနိုင်ပါသည်။ သင်၏ စက်တွင် အက်ပ်ကအသုံးပြုရန်အတွက် တည်နေရာဝန်ဆောင်မှုများကို ဖွင့်ထားပြီးမှ အသုံးပြု၍ ရပါမည်။ ၎င်းက ဘက်ထရီ ပိုကုန်နိုင်ပါသည်။"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"မျက်နှာစာတွင်သာ ခန့်မှန်းခြေ တည်နေရာ အသုံးပြုခြင်း"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"မျက်နှာစာတွင် ဖွင့်ထားမှသာ ဤအက်ပ်က သင်၏ အနီးစပ်ဆုံးတည်နေရာကို ရယူနိုင်ပါသည်။ အက်ပ်က ဤတည်နေရာဝန်ဆောင်မှုများကို အသုံးပြုရန်အတွက် သင်၏စက်တွင် ၎င်းတို့ရှိနေပြီး ဖွင့်ထားရပါမည်။"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"နောက်ခံတွင် တည်နေရာကို အသုံးပြုရန်"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"ခန့်မှန်းခြေ သို့မဟုတ် တိကျသော တည်နေရာ ဝင်သုံးခွင့်အတွက် ၎င်းကို နောက်ဆက်တွဲ ခွင့်ပြုထားပါက နောက်ခံတွင် လုပ်ဆောင်နေစဉ် အက်ပ်က တည်နေရာကို ရယူအသုံးပြုနိုင်ပါသည်။"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"နောက်ခံတွင် လုပ်ဆောင်နေစဉ် ဤအက်ပ်က တည်နေရာကို ရယူအသုံးပြုနိုင်သည်သာမက မျက်နှာစာတည်နေရာကိုပါ အသုံးပြုနိုင်မည်။"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"သင့်အသံအပြင်အဆင်အားပြောင်းခြင်း"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"အပလီကေးရှင်းအား အသံအတိုးအကျယ်နှင့် အထွက်ကို မည်သည့်စပီကာကို သုံးရန်စသည်ဖြင့် စက်တစ်ခုလုံးနှင့်ဆိုင်သော အသံဆိုင်ရာ ဆက်တင်များ ပြင်ဆင်ခွင့် ပြုရန်"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"အသံဖမ်းခြင်း"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"အပလီကေးရှင်းအား တက်ဘလက်ပေါ်မှ ဘလူးတုသ် အပြင်အဆင်အား ကြည့်ခွင့်၊ တခြားစက်များနဲ့ ဆက်သွယ်ခြင်း၊ ဆက်သွယ်ခြင်းကို လက်ခံခွင့်ပြုပါ။"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"သင့် Android TV စက်ပစ္စည်းပေါ်ရှိ ဘလူးတုသ် စီစဉ်သတ်မှတ်ချက်များကို ကြည့်ရှုခွင့်အပြင် တွဲချိတ်ထားသည့် စက်ပစ္စည်းများနှင့် ချိတ်ဆက်မှုပြုလုပ်ခြင်းနှင့် လက်ခံခြင်းတို့ကို အက်ပ်အား ပြုလုပ်ခွင့်ပေးသည်။"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"အပလီကေးရှင်းအား ဖုန်းမှဘလူးတု အပြင်အဆင်အား ကြည့်ခွင့်၊ တခြားစက်များနဲ့ ဆက်သွယ်ခြင်း၊ ဆက်သွယ်ခြင်းကို လက်ခံခွင့်ပြုပါ။"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communicationအား ထိန်းချုပ်ရန်"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"အက်ပ်အား တာတို စက်ကွင်း ဆက်သွယ်ရေး (NFC) တဲဂ်များ၊ ကဒ်များ နှင့် ဖတ်ကြသူတို့နှင့် ဆက်သွယ်ပြောဆိုခွင့် ပြုသည်။"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"ဖန်သားပြင် သော့ချခြင်းအား မလုပ်နိုင်အောင် ပိတ်ရန်"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ချိတ်ဆက်ထားသည်"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ဖိုင်များကိုကြည့်ရန် တို့ပါ"</string>
<string name="pin_target" msgid="8036028973110156895">"တွဲပါ"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"ဖြုတ်ပါ"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"အက်ပ်အချက်အလက်"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"သရုပ်ပြချက်ကို စတင်နေသည်…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"ဤအချက်အလက်များကို "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"တွင် အပ်ဒိတ်လုပ်လိုပါသလား- <xliff:g id="TYPE_0">%1$s</xliff:g>၊ <xliff:g id="TYPE_1">%2$s</xliff:g> နှင့် <xliff:g id="TYPE_2">%3$s</xliff:g>။"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"သိမ်းရန်"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"မလိုပါ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"ယခုမလုပ်ပါ"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"ဘယ်တော့မှ"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"အပ်ဒိတ်လုပ်ရန်"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"ရှေ့ဆက်ရန်"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"စကားဝှက်"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းကို နှိပ်ပါ"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"လော့ခ်မျက်နှာပြင်"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"ပေါ့ပ်အပ်ဝင်းဒိုးတွင်ရှိသော <xliff:g id="APP_NAME">%1$s</xliff:g>အက်ပ်။"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>၏ ခေါင်းစီး ဘား။"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 69e341e..dc3ce6e 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Administratorappen for jobbprofilen mangler eller er skadet. Dette har ført til at jobbprofilen og alle data knyttet til den, har blitt slettet. Ta kontakt med administratoren for å få hjelp."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jobbprofilen din er ikke lenger tilgjengelig på denne enheten"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"For mange passordforsøk"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratoren overførte enheten til personlig bruk"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Enheten administreres"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasjonen din kontrollerer denne enheten og kan overvåke nettverkstrafikk. Trykk for å få mer informasjon."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Enheten blir slettet"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Lar appen sende varige kringkastinger («sticky broadcasts»), som ikke avsluttes etter at kringkastingen er over. Overdreven bruk kan gjøre Android TV-enheten din treg eller ustabil ved at den bruker for mye minne."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Lar appen sende faste kringkastinger («sticky broadcasts») som blir værende etter at kringkastingen er over. Overdreven bruk kan gjøre telefonen treg eller ustabil ved å bruke for mye minne."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"lese kontaktene dine"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Lar appen lese informasjon om kontaktene lagret på nettbrettet ditt, inkludert hvor ofte du har ringt, sendt e-post til, eller på andre måter kommunisert med spesifikke personer. Denne tillatelsen lar apper lagre kontaktdata. Merk at skadelige apper kan dele disse dataene uten at du vet om det."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Lar appen lese data om kontaktene som er lagret på Android TV-enheten din, inkludert hvor hyppig du har ringt, sendt e-post eller på andre måter har kommunisert med bestemte kontakter. Denne tillatelsen lar apper lagre kontaktdata, og skadelige apper kan dele dem uten ditt samtykke."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Lar appen lese informasjon om kontaktene lagret på telefonen din, inkludert hvor ofte du har ringt, sendt e-post til eller på andre måter kommunisert med spesifikke personer. Denne tillatelsen lar apper lagre kontaktdata. Merk at skadelige apper kan dele disse dataene uten at du vet om det."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Lar appen lese data om kontaktene dine som er lagret på nettbrettet ditt. Apper får også tilgang til kontoene på nettbrettet ditt som har opprettet kontakter. Dette kan inkludere kontoer som er opprettet av apper du har installert. Denne tillatelsen lar apper lagre kontaktdataene dine. Vær oppmerksom på at skadelige apper kan dele disse dataene uten at du vet om det."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Lar appen lese data om kontaktene dine som er lagret på Android TV-enheten din. Apper får også tilgang til kontoene på Android TV-enheten din som har opprettet kontakter. Dette kan inkludere kontoer som er opprettet av apper du har installert. Denne tillatelsen lar apper lagre kontaktdataene dine. Vær oppmerksom på at skadelige apper kan dele disse dataene uten at du vet om det."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Lar appen lese data om kontaktene dine som er lagret på telefonen din. Apper får også tilgang til kontoene på telefonen din som har opprettet kontakter. Dette kan inkludere kontoer som er opprettet av apper du har installert. Denne tillatelsen lar apper lagre kontaktdataene dine. Vær oppmerksom på at skadelige apper kan dele disse dataene uten at du vet om det."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"endre kontaktene dine"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Lar appen endre informasjon om kontaktene lagret på nettbrettet ditt, inkludert hvor ofte du har ringt, sendt e-post til eller på andre måter kommunisert med bestemte kontakter. Denne tillatelsen lar apper slette kontaktdata."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Lar appen endre informasjon om kontaktene som er lagret på Android TV-enheten din, inkludert hvor ofte du har ringt, sendt e-post til eller på andre måter kommunisert med bestemte kontakter. Denne tillatelsen lar apper slette kontaktdata."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Lar appen endre informasjon om kontaktene lagret på telefonen din, inkludert hvor ofte du har ringt, sendt e-post til eller på andre måter kommunisert med bestemte kontakter. Denne tillatelsen lar apper slette kontaktdata."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Lar appen endre informasjon om kontaktene som er lagret på nettbrettet ditt. Denne tillatelsen lar apper slette kontaktdata."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Lar appen endre informasjon om kontaktene som er lagret på Android TV-enheten din. Denne tillatelsen lar apper slette kontaktdata."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Lar appen endre informasjon om kontaktene som er lagret på telefonen din. Denne tillatelsen lar apper slette kontaktdata."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"lese anropsloggen"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Denne appen kan lese anropsloggen din."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"endre anropsloggen"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"bruke ekstra posisjonskommandoer"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Appen gis tillatelse til å bruke ekstra kommandoer fra posisjonsleverandører. Dette kan gi appen tillatelse til å påvirke bruken av GPS eller andre posisjonskilder."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"bare tilgang til nøyaktig posisjon i forgrunnen"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Denne appen kan bare få den nøyaktige posisjonen din når den er på i forgrunnen. Disse posisjonstjenestene må være slått på og tilgjengelige på telefonen din for at appen skal kunne bruke dem. Dette kan øke batteriforbruket."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"bare tilgang til omtrentlig posisjon (nettverksbasert) i forgrunnen"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Denne appen kan bare få posisjonen din basert på nettverkskilder, for eksempel mobilmaster og Wi-Fi-nettverk, når den er på i forgrunnen. Disse posisjonstjenestene må være slått på og tilgjengelige på nettbrettet ditt for at appen skal kunne bruke dem."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Denne appen kan bare få posisjonen din basert på nettverkskilder, for eksempel mobilmaster og Wi-Fi-nettverk, når den er på i forgrunnen. Disse posisjonstjenestene må være slått på og tilgjengelige på Android TV-en din for at appen skal kunne bruke dem."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Denne appen kan bare få posisjonen din basert på nettverkskilder, for eksempel mobilmaster og Wi-Fi-nettverk, når den er på i forgrunnen. Disse posisjonstjenestene må være slått på og tilgjengelige på telefonen din for at appen skal kunne bruke dem."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Denne appen kan bare få den nøyaktige posisjonen din når den er på i forgrunnen. Posisjonstjenestene må være slått på og tilgjengelige på enheten din for at appen skal kunne bruke dem. Dette kan øke batteriforbruket."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"bare tilgang til omtrentlig posisjon i forgrunnen"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Denne appen kan bare få den omtrentlige posisjonen din når den er i forgrunnen. Posisjonstjenestene må være slått på og tilgjengelige på enheten din for at appen skal kunne bruke dem."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"tilgang til posisjon i bakgrunnen"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Hvis du gir denne tillatelsen, får appen tilgang til posisjonen mens den kjører i bakgrunnen, i tillegg til tilgang til omtrentlig eller presis posisjon."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Denne appen har tilgang til posisjon når den kjører i bakgrunnen, i tillegg til tilgang til posisjonen i forgrunnen."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"endre lydinnstillinger"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Lar appen endre globale lydinnstillinger slik som volum og hvilken høyttaler som brukes for lydavspilling."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ta opp lyd"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Lar appen se Bluetooth-konfigurasjonen på nettbrettet, samt opprette og godta tilkoblinger med sammenkoblede enheter."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Lar appen se Bluetooth-konfigurasjonen på Android TV-enheten din samt opprette og godta tilkoblinger med sammenkoblede enheter."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Lar appen se Bluetooth-konfigurasjonen på telefonen, samt opprette og godta tilkoblinger med sammenkoblede enheter."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"kontroller overføring av data med NFC-teknologi"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Lar appen kommunisere med etiketter, kort og lesere som benytter NFC-teknologi."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"deaktivere skjermlåsen"</string>
@@ -846,7 +847,7 @@
<string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Du har prøvd å låse opp Android TV-enheten din <xliff:g id="NUMBER">%d</xliff:g> ganger. Android TV-enheten din tilbakestilles nå til fabrikkstandard."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Du har foretatt <xliff:g id="NUMBER">%d</xliff:g> mislykkede opplåsinger av telefonen. Telefonen blir nå tilbakestilt til fabrikkinnstillingene."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Prøv igjen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
- <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Glemt mønsteret?"</string>
+ <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Har du glemt mønsteret?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Opplåsing av konto"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"For mange forsøk på tegning av mønster"</string>
<string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Logg på med Google-kontoen din for å låse opp."</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Koblet til <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Trykk for å se filer"</string>
<string name="pin_target" msgid="8036028973110156895">"Fest"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Løsne"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Info om appen"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Starter demo …"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Vil du oppdatere disse elementene i "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> og <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Lagre"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nei takk"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ikke nå"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Aldri"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Oppdater"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Fortsett"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"passord"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Slå delt skjerm av/på"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Låseskjerm"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skjermdump"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g>-appen i forgrunnsvindu."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Tekstingsfelt i <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 0fb2213..19d6ccf7 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"उक्त कार्य प्रोफाइलको प्रशासकीय अनुप्रयोग छैन वा बिग्रेको छ। त्यसले गर्दा, तपाईंको कार्य प्रोफाइल र सम्बन्धित डेटालाई मेटिएको छ। सहायताका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्।"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"तपाईंको कार्य प्रोफाइल अब उप्रान्त यस यन्त्रमा उपलब्ध छैन"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"पासवर्ड प्रविष्ट गर्ने अत्यधिक गलत प्रयासहरू भए"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"व्यवस्थापकले यन्त्रलाई व्यक्तिगत प्रयोगका लागि अस्वीकार गर्नुभयो"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"यन्त्र व्यवस्थित गरिएको छ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"तपाईंको संगठनले यस यन्त्रको व्यवस्थापन गर्दछ र नेटवर्क ट्राफिकको अनुगमन गर्न सक्छ। विवरणहरूका लागि ट्याप गर्नुहोस्।"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"तपाईंको यन्त्र मेटिनेछ"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"अनुप्रयोगलाई प्रसारण समाप्त भइसकेपछि पनि रहिरहने स्टिकी प्रसारणहरू पठाउने अनुमति दिन्छ। यो सुविधाको अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग हुने भएकाले तपाईंको Android TV यन्त्र सुस्त वा अस्थिर हुन सक्छ।"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"औपचारिक प्रसारणलाई पठाउनको लागि एक अनुप्रयोगलाई अनुमति दिन्छ, जुन प्रसारण समाप्त भएपछि बाँकी रहन्छ। अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग गरेको कारणले फोनलाई ढिलो र अस्थिर बनाउन सक्छ।"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"तपाईँका सम्पर्कहरू पढ्नुहोस्"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"अनुप्रयोगलाई निर्दिष्ट व्यक्तिगतसँग अन्य तरिकाहरूबाट कल गर्नु भएका, इमेल गर्नु भएका वा अन्तर्क्रिया गर्नुभएका आवृतिसहितको तपाईंको ट्याब्लेटमा भण्डारण गरिएका सम्पर्कहरूको डेटा पढ्न अनुमति दिन्छ। यो अनुमतिले तपाईंको सम्पर्क डेटा बचत गर्न अनुमति दिन्छ, र खराब अनुप्रयोगहरूले तपाईंको जानकारी बिना सम्पर्क डेटा साझेदारी गर्न सक्दछन्।"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"अनुप्रयोगलाई तपाईंले निश्चित व्यक्तिहरूलाई कति पटक फोन, इमेल वा अन्य तरिकाले सम्पर्क गर्नुभयो भन्ने डेटासहित तपाईंको Android TV यन्त्रमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। यस अनुमतिले अनुप्रयोगहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक अनुप्रयोगहरूले सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"तपाईँले विशेष व्यक्तिहरूसँग अर्को तरिकाबाट कल गर्नुभएका, इमेल गर्नुभएका वा संचार गर्नुभएका आवृतिसहित तपाईँको फोनमा भण्डारण भएका डेटाको बारेमा पढ्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। यो अनुमतिले अनुप्रयोगलाई तपाईँको सम्पर्क डेटा बचत गर्नको लागि अनुमति दिन्छ, र तपाईँको ज्ञान बिना नै खराब अनुप्रयोगहरूले सायद सम्पर्क डेटा साझेदारी गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"अनुप्रयोगलाई तपाईंको ट्याब्लेटमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। अनुप्रयोगहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको ट्याब्लेटमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका अनुप्रयोगहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले अनुप्रयोगहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक अनुप्रयोगहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"अनुप्रयोगलाई तपाईंको Android TV यन्त्रमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा पढ्न अनुमति दिन्छ। अनुप्रयोगहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको Android TV यन्त्रमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका अनुप्रयोगहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले अनुप्रयोगहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक अनुप्रयोगहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"अनुप्रयोगलाई तपाईंको फोनमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। अनुप्रयोगहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको फोनमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका अनुप्रयोगहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले अनुप्रयोगहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक अनुप्रयोगहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"तपाईँका सम्पर्कहरू परिवर्तन गर्नुहोस्"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"अन्य तरिकाका आवृतिहरूसँग जुन तपाईँले कल, इमेल, वा विशेष सम्पर्क गर्नुभएकासहित तपाईँको ट्याब्लेटमा भण्डारण भएका सम्पर्कहरूको बारेको डेटालाई परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। यस अनुमतिले सम्पर्क डेटालाई मेटाउनको लागि अनुमति दिन्छ।"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"अनुप्रयोगलाई तपाईंले सम्पर्क सूचीमा भएका निश्चित व्यक्तिहरूलाई कति पटक फोन, इमेल वा अन्य तरिकाले सम्पर्क गर्नुभयो भन्ने डेटासहित तपाईंको Android TV यन्त्रमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा परिमार्जन गर्ने अनुमति दिन्छ। यस अनुमतिले अनुप्रयोगहरूलाई सम्पर्क ठेगानासम्बन्धी डेटा मेट्न दिन्छ।"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"तपाईँले बारम्बार कल गरेका, इमेल गरेका, वा विशेष सम्पर्कहरूसँग सञ्चार गरेका सहित तपाईँको फोनमा भण्डारण गरेका तपाईँका सम्पर्कहरू परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। यो अनुमतिले अनुप्रयोगलाई सम्पर्क डेटा मेटाउन दिन्छ।"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"अनुप्रयोगलाई तपाईंको ट्याब्लेटमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले अनुप्रयोगलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"अनुप्रयोगलाई तपाईंको Android TV यन्त्रमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले अनुप्रयोगलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"अनुप्रयोगलाई तपाईंको फोनमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले अनुप्रयोगलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"कल लग पढ्नुहोस्"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"यस अनुप्रयोगले तपाईंको फोन सम्पर्कको इतिहास पढ्न सक्छ।"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"कल लग लेख्नुहोस्"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"अधिक स्थान प्रदायक आदेशहरू पहुँच गर्नुहोस्"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"अनुप्रयोगलाई अतिरिक्त स्थान प्रदायक आदेशहरू पहुँच गर्न अनुमति दिन्छ। यो अनुप्रयोगलाई GPS वा अन्य स्थान स्रोतहरूको संचालन साथै हस्तक्षेप गर्न अनुमति दिन सक्छ।"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"अग्रभूमिमा मात्र सटीक स्थानमाथि पहुँच राख्नुहोस्"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"यो अनुप्रयोगले अग्रभागमा चलिरहेको अवस्थामा मात्र तपाईंलाई स्थानको सटिक जानकारी दिन सक्छ। यी स्थानसम्बन्धी सेवाहरू अनिवार्य रूपमा सक्रिय गरिएका हुनु पर्छ र अनुप्रयोगले यिनीहरूको प्रयोग गर्न सकोस् भन्नाका खातिर तपाईंको फोनमै उपलब्ध हुन्छन्। यस कार्यले गर्दा ब्याट्री बढी खर्च हुन सक्छ।"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"अग्रभूमिमा मात्र अनुमानित स्थान (नेटवर्कमा आधारित) माथि पहुँच राख्नुहोस्"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"यस अनुप्रयोगले सेलका टावर र Wi-Fi नेटवर्कहरू जस्ता नेटवर्कका स्रोतहरूको आधारमा तपाईंको स्थान बारे जानकारी प्राप्त गर्न सक्छ। यो अनुप्रयोग ती स्रोतहरूको प्रयोग गर्न सक्षम होस् भन्नका खातिर यी स्थानसम्बन्धी सेवाहरूलाई अनिवार्य रूपमा सक्रिय पार्नुपर्छ र यी तपाईंको ट्याब्लेटमा उपलब्ध हुनु पर्छ।"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"यो अनुप्रयोगले अग्रभूमिमा चलिरहेको बेला मात्र यसले मोबाइलको टावर र Wi-Fi का नेटवर्कहरू जस्ता स्रोतहरूका आधारमा तपाईंको स्थानसम्बन्धी जानकारी प्राप्त गर्न सक्छ। यस अनुप्रयोगले स्थानसम्बन्धी जानकारी प्रयोग गर्न सकोस् भन्नाका खातिर तपाईंको Android TV यन्त्रमा यी स्थानसम्बन्धी सेवाहरू अनिवार्य रूपमा उपलब्ध हुनुका साथै सक्रिय गरिएको हुनु पर्छ।"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"यस अनुप्रयोगले सेलका टावर र Wi-Fi नेटवर्कहरू जस्ता नेटवर्कका स्रोतहरूको आधारमा तपाईंको स्थान बारे जानकारी प्राप्त गर्न सक्छ। यो अनुप्रयोग ती स्रोतहरूको प्रयोग गर्न सक्षम होस् भन्नका खातिर यी स्थानसम्बन्धी सेवाहरूलाई अनिवार्य रूपमा सक्रिय पार्नुपर्छ र यी तपाईंको फोनमा उपलब्ध हुनु पर्छ।"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"यो अनुप्रयोगले अग्रभागमा चलिरहेको अवस्थामा मात्र तपाईंलाई स्थानको सटिक जानकारी दिन सक्छ। स्थानसम्बन्धी सेवाहरू अनिवार्य रूपमा सक्रिय गरिएका हुनु पर्छ र अनुप्रयोगले यिनीहरूको प्रयोग गर्न सकोस् भन्नाका खातिर तपाईंको यन्त्रमै उपलब्ध हुनु पर्छ। यस कार्यले गर्दा ब्याट्री बढी खर्च हुन सक्छ।"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"अग्रभागमा मात्र अनुमानित स्थानमाथि पहुँच राख्नुहोस्"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"यो अनुप्रयोगले अग्रभागमा चलिरहेको अवस्थामा मात्र तपाईंको स्थानको अनुमानित जानकारी दिन सक्छ। स्थानसम्बन्धी सेवाहरू अनिवार्य रूपमा सक्रिय गरिएका हुनु पर्छ र अनुप्रयोगले यिनीहरूको प्रयोग गर्न सकोस् भन्नाका खातिर तपाईंको यन्त्रमै उपलब्ध हुनु पर्छ।"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"पृष्ठभूमिमा स्थानसम्बन्धी पहुँच"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"यसका अतिरिक्त यसलाई अनुमानित वा सटिक स्थानमाथि पहुँच राख्ने अनुमति दिइएको छ भने उक्त अनुप्रयोगले पृष्ठभूमिमा चलिरहेको बेला स्थानमाथि पहुँच राख्न सक्छ।"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"यो अनुप्रयोगले अग्रभागमा चल्दा स्थानसम्बन्धी पहुँच प्राप्त गर्नुका साथै पृष्ठभूमिमा चल्दा पनि स्थानसम्बन्धी पहुँच प्राप्त गर्न सक्छ।"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"तपाईँका अडियो सेटिङहरू परिवर्तन गर्नुहोस्"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"अनुप्रयोगलाई ग्लोबल अडियो सेटिङहरू परिमार्जन गर्न अनुमति दिन्छ, जस्तै आवाजको मात्रा र आउटपुटको लागि कुन स्पिकर प्रयोग गर्ने।"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"अडियो रेकर्ड गर्नुहोस्"</string>
@@ -428,7 +425,7 @@
<string name="permdesc_systemCamera" msgid="544730545441964482">"यस विशेषाधिकार प्राप्त अनुप्रयोगले जुनसुकै समय प्रणालीको क्यामेरा प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ। अनुप्रयोगसँग पनि android.permission.CAMERA सम्बन्धी अनुमति हुनु पर्छ"</string>
<string name="permlab_vibrate" msgid="8596800035791962017">"कम्पन नियन्त्रण गर्नुहोस्"</string>
<string name="permdesc_vibrate" msgid="8733343234582083721">"अनुप्रयोगलाई भाइब्रेटर नियन्त्रण गर्न अनुमति दिन्छ।"</string>
- <string name="permlab_callPhone" msgid="1798582257194643320">"फोन नम्बरहरूमा सिधै कल गर्नुहोस्"</string>
+ <string name="permlab_callPhone" msgid="1798582257194643320">"फोन नम्बरहरूमा सीधै कल गर्नुहोस्"</string>
<string name="permdesc_callPhone" msgid="5439809516131609109">"तपाईँको हस्तक्षेप बेगरै फोन नम्बर कल गर्न अनुप्रयोगलाई अनुमति दिन्छ। यसले अनपेक्षित शुल्क वा कलहरू गराउन सक्छ। यसले अनुप्रयोगलाई आपतकालीन नम्बरहरू कल गर्न अनुमति दिँदैन विचार गर्नुहोस्। खराब अनुप्रयोगहरूले तपाईँको स्वीकार बिना कलहरू गरेर तपाईँलाई बढी पैसा तिराउन सक्छ।"</string>
<string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS कल सेवा पहुँच गर्नुहोस्"</string>
<string name="permdesc_accessImsCallService" msgid="6328551241649687162">"तपाईँको हस्तक्षेप बिना नै कल गर्न IMS सेवा प्रयोग गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ट्याब्लेटमा ब्लुटुथको कन्फिगुरेसनलाई हेर्न र बनाउन र जोडी उपकरणहरूसँग जडानहरूलाई स्वीकार गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"अनुप्रयोगलाई तपाईंको Android TV यन्त्रको ब्लुटुथको कन्फिगुरेसन हेर्ने तथा जोडा बनाइएका यन्त्रहरूसँग जोडिने वा ती यन्त्रहरूले पठाएका जोडिने अनुरोध स्वीकार्ने अनुमति दिन्छ।"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"अनुप्रयोगलाई फोनमा ब्लुटुथको कन्फिगरेसन हेर्न र जोडी भएका उपकरणहरूसँग जडानहरू बनाउन र स्वीकार गर्न अनुमति दिन्छ।"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"नजिक क्षेत्र संचार नियन्त्रणहरू"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"अनुप्रयोगलाई नयाँ क्षेत्र संचार (NFC) ट्यागहरू, कार्डहरू र पाठकहरूसँग अन्तर्क्रिया गर्न अनुमति दिन्छ।"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"स्क्रिन लक असक्षम पार्नुहोस्"</string>
@@ -1868,7 +1869,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> मा जडान गरिएको छ"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"फाइलहरू हेर्न ट्याप गर्नुहोस्"</string>
<string name="pin_target" msgid="8036028973110156895">"पिन गर्नुहोस्"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"अनपिन गर्नुहोस्"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"अनुप्रयोगका बारे जानकारी"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"डेमो सुरु गर्दै…"</string>
@@ -1911,6 +1916,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"यी वस्तुहरू "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" मा अद्यावधिक गर्नुहोस्: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> र <xliff:g id="TYPE_2">%3$s</xliff:g> हो?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"सुरक्षित गर्नुहोस्"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"पर्दैन, धन्यवाद"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"अहिले होइन"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"कहिल्यै होइन"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"अद्यावधिक गर्नुहोस्"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"जारी राख्नुहोस्"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"पासवर्ड"</string>
@@ -2006,5 +2013,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"विभाजित स्क्रिन टगल गर्नुहोस्"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"लक स्क्रिन"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"स्क्रिनसट"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"पपअप विन्डोमा <xliff:g id="APP_NAME">%1$s</xliff:g> अनुप्रयोग छ।"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> को क्याप्सन बार।"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 363c3c3..d935815 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"De beheer-app van het werkprofiel ontbreekt of is beschadigd. Als gevolg hiervan zijn je werkprofiel en alle gerelateerde gegevens verwijderd. Neem contact op met je beheerder voor hulp."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Je werkprofiel is niet meer beschikbaar op dit apparaat"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Te veel wachtwoordpogingen"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"De beheerder heeft het apparaat afgestaan voor persoonlijk gebruik"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Apparaat wordt beheerd"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Dit apparaat wordt beheerd door je organisatie. Het netwerkverkeer kan worden bijgehouden. Tik voor meer informatie."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Je apparaat wordt gewist"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Hiermee kan de app sticky broadcasts verzenden die worden behouden nadat de broadcast is beëindigd. Bij overmatig gebruik kan het Android TV-apparaat traag of instabiel worden omdat er te veel geheugenruimte wordt gebruikt."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Hiermee kan de app sticky broadcasts verzenden die behouden blijven nadat de broadcast is beëindigd. Bij overmatig gebruik kan de telefoon traag of instabiel worden omdat er te veel geheugenruimte wordt gebruikt."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"je contacten lezen"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je tablet, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps je contactgegevens opslaan, en schadelijke apps kunnen zonder je medeweten contactgegevens delen."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je Android TV-apparaat, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke personen. Met dit recht kunnen apps je contactgegevens opslaan en kunnen schadelijke apps zonder je medeweten contactgegevens delen."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je telefoon, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke personen. Met deze toestemming kunnen apps je contactgegevens opslaan, en schadelijke apps kunnen zonder je medeweten contactgegevens delen."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je tablet. Apps hebben ook toegang tot de accounts op je tablet waarvoor contacten zijn gemaakt. Dit kan accounts omvatten die zijn gemaakt door apps die je hebt geïnstalleerd. Met dit recht kunnen apps je contactgegevens opslaan en kunnen schadelijke apps zonder je medeweten contactgegevens delen."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je Android TV. Apps hebben ook toegang tot de accounts op je Android TV-apparaat waarvoor contacten zijn gemaakt. Dit kan accounts omvatten die zijn gemaakt door apps die je hebt geïnstalleerd. Met dit recht kunnen apps je contactgegevens opslaan en kunnen schadelijke apps zonder je medeweten contactgegevens delen."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Hiermee kan de app gegevens lezen over de contacten die zijn opgeslagen op je telefoon. Apps hebben ook toegang tot de accounts op je telefoon waarvoor contacten zijn gemaakt. Dit kan accounts omvatten die zijn gemaakt door apps die je hebt geïnstalleerd. Met dit recht kunnen apps je contactgegevens opslaan en kunnen schadelijke apps zonder je medeweten contactgegevens delen."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"je contacten aanpassen"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je tablet, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je Android TV-apparaat, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke contacten. Met dit recht kunnen apps contactgegevens verwijderen."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je telefoon, inclusief de frequentie waarmee je hebt gebeld, gemaild of op andere manieren hebt gecommuniceerd met specifieke contacten. Met deze toestemming kunnen apps contactgegevens verwijderen."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je tablet. Met dit recht kunnen apps contactgegevens verwijderen."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je Android TV. Met dit recht kunnen apps contactgegevens verwijderen."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Hiermee kan de app gegevens wijzigen over de contacten die zijn opgeslagen op je telefoon. Met dit recht kunnen apps contactgegevens verwijderen."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"gesprekslijst lezen"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Deze app kan je gespreksgeschiedenis lezen."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"gesprekslijst schrijven"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"toegang tot extra opdrachten van locatieaanbieder"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Hiermee kan de app toegang krijgen tot extra opdrachten voor de locatieprovider. De app kan hiermee de werking van gps of andere locatiebronnen te verstoren."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"alleen toegang tot precieze locatie op de voorgrond"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Deze app kan je exacte locatie ophalen wanneer de app op de voorgrond wordt uitgevoerd. De app kan alleen gebruikmaken van deze locatieservices als ze zijn ingeschakeld en beschikbaar zijn op je telefoon. Hierdoor kan het batterijverbruik toenemen."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"alleen toegang tot geschatte locatie (op basis van netwerk) op de voorgrond"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Deze app kan je locatie ophalen op basis van netwerkbronnen zoals zendmasten en wifi-netwerken, maar alleen wanneer de app zich op de voorgrond bevindt. De app kan alleen gebruikmaken van deze locatieservices als ze zijn ingeschakeld en beschikbaar zijn op je tablet."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Deze app kan je locatie ophalen op basis van netwerkbronnen zoals zendmasten en wifi-netwerken, maar alleen als de app zich op de voorgrond bevindt. De app kan alleen gebruikmaken van deze locatieservices als ze zijn ingeschakeld en beschikbaar zijn op je Android TV-apparaat."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Deze app kan je locatie ophalen op basis van netwerkbronnen zoals zendmasten en wifi-netwerken, maar alleen wanneer de app zich op de voorgrond bevindt. De app kan alleen gebruikmaken van deze locatieservices als ze zijn ingeschakeld en beschikbaar zijn op je telefoon."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Deze app kan je exacte locatie ophalen als de app op de voorgrond wordt uitgevoerd. De app kan alleen gebruikmaken van de locatieservices als die zijn ingeschakeld en beschikbaar zijn op je apparaat. Hierdoor kan het batterijverbruik toenemen."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"alleen toegang tot geschatte locatie op de voorgrond"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Deze app kan je geschatte locatie alleen opvragen als de app op de voorgrond wordt gebruikt. De app kan de locatieservices alleen gebruiken als ze zijn ingeschakeld en beschikbaar zijn op je apparaat."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"toegang tot locatie op de achtergrond"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Als dit wordt verleend als aanvulling op toegang tot de geschatte of precieze locatie, kan de app toegang tot de locatie krijgen terwijl de app actief is op de achtergrond."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Deze app heeft niet alleen op de voorgrond toegang tot je locatie, maar ook als deze actief is op de achtergrond."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"je audio-instellingen wijzigen"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Hiermee kan de app algemene audio-instellingen wijzigen zoals het volume en welke luidspreker wordt gebruikt voor de uitvoer."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"audio opnemen"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Hiermee kan de app de Bluetooth-configuratie van de tablet bekijken en verbindingen met gekoppelde apparaten maken en accepteren."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Hiermee kan de app de Bluetooth-configuratie van het Android TV-apparaat bekijken en verbindingen met gekoppelde apparaten maken en accepteren."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Hiermee kan de app de Bluetooth-configuratie van de telefoon bekijken en verbindingen met gekoppelde apparaten maken en accepteren."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication regelen"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Hiermee kan de app communiceren met NFC-tags (Near Field Communication), kaarten en lezers."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"je schermvergrendeling uitschakelen"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Verbonden met <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Tik om bestanden te bekijken"</string>
<string name="pin_target" msgid="8036028973110156895">"Vastzetten"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Losmaken"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"App-info"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Demo starten…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Deze items updaten in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> en <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Opslaan"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nee, bedankt"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Niet nu"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nooit"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Updaten"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Doorgaan"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"Wachtwoord"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Gesplitst scherm schakelen"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Scherm vergrendelen"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"App <xliff:g id="APP_NAME">%1$s</xliff:g> in pop-upvenster."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Ondertitelingsbalk van <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 566d778..84ad4cf 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"ଆଡମିନ୍ ଆପ୍ ନାହିଁ କିମ୍ବା ଭୁଲ ଅଛି। ଫଳସ୍ୱରୂପ, ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଏବଂ ସମ୍ବନ୍ଧୀୟ ଡାଟା ଡିଲିଟ୍ କରାଯାଇଛି। ସହାୟତା ପାଇଁ ଆପଣଙ୍କ ଆଡମିନଙ୍କୁ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ଏହି ଡିଭାଇସରେ ଆପଣଙ୍କ ୱର୍କ ପ୍ରୋଫାଇଲ୍ ଆଉ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ବହୁତ ଥର ଭୁଲ ପାସ୍ୱର୍ଡ ଲେଖିଛନ୍ତି"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"ବ୍ୟକ୍ତିଗତ ବ୍ୟବହାର ପାଇଁ ଆଡ୍ମିନ୍ ଡିଭାଇସ୍କୁ ଅଲଗା କରିଛନ୍ତି"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"ଡିଭାଇସକୁ ପରିଚାଳନା କରାଯାଉଛି"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ଆପଣଙ୍କ ସଂସ୍ଥା ଏହି ଡିଭାଇସକୁ ପରିଚାଳନା କରନ୍ତି ଏବଂ ନେଟୱର୍କ ଟ୍ରାଫିକ୍ ନୀରିକ୍ଷଣ କରନ୍ତି। ବିବରଣୀ ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"ଆପଣଙ୍କ ଡିଭାଇସ୍ ବର୍ତ୍ତମାନ ଲିଭାଯିବ"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"ଷ୍ଟିକି ବ୍ରଡକାଷ୍ଟ୍ ପଠାଇବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ, ଯାହା ବ୍ରଡକାଷ୍ଟ୍ ଶେଷ ହେବାପରେ ରହିଥାଏ। ଅତ୍ୟଧିକ ବ୍ୟବହାର ଦ୍ୱାରା ଅଧିକ ମେମୋରୀ ବ୍ୟବହାର ହୋଇ ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍କୁ ଧୀର କିମ୍ବା ଅସ୍ଥିର କରିପାରେ।"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ଷ୍ଟିକୀ ବ୍ରଡ୍କାଷ୍ଟ ପଠାଇବାକୁ ଆପ୍କୁ ଅନୁମତି ଦିଏ, ଯାହା ବ୍ରଡ୍କାଷ୍ଟ ଶେଷ ହେବାପରେ ରହିଥାଏ। ଅତିରିକ୍ତ ବ୍ୟବହାର ଦ୍ୱାରା ଅଧିକ ମେମୋରୀ ବ୍ୟବହାର ହୋଇ ଫୋନ୍କୁ ମନ୍ଥର କିମ୍ବା ଅସ୍ଥିର କରିପାରେ।"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"ଆପଣଙ୍କ ଯୋଗାଯୋଗ ପଢ଼ନ୍ତୁ"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"ଜଣେ ନିର୍ଦ୍ଦିଷ୍ଟ ବ୍ୟକ୍ତିଙ୍କ ସହ ଆପଣ କେତେଥର କଲ୍, ଇମେଲ୍, ତଥା ଯୋଗାଯୋଗ କରିଛନ୍ତି, ତାହାର ନିୟମିତତା ସମେତ ଆପଣଙ୍କ ଟାବଲେଟ୍ରେ ଷ୍ଟୋର୍ ହୋଇଥିବା ଯୋଗାଯୋଗ ବିଷୟରେ ଡାଟା ପଢ଼ିବାକୁ ଆପ୍କୁ ଅନୁମତି ଦିଏ। ଏହ ଅନୁମତି ଦ୍ୱାରା ଆପଣଙ୍କ କଲ୍ ଲଗ୍ ସେଭ୍ କରିବାକୁ ଆପ୍କୁ ଅନୁମତି ଦିଏ ତଥା ହାନୀକାରକ ଆପ୍ ଆପଣଙ୍କ ଅଜ୍ଞାତରେ କଲ୍ ଲଗ୍ ଡାଟା ଶେୟାର କରିପାରନ୍ତି।"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"ଅନ୍ୟ ପ୍ରକାରରେ ନିର୍ଦ୍ଦିଷ୍ଟ ବ୍ୟକ୍ତିମାନଙ୍କ ସହ ଆପଣ କେତେ ବ୍ୟବଧାନରେ କଲ୍, ଇମେଲ୍ ତଥା ଯୋଗାଯୋଗ କରିଛନ୍ତି, ସେସବୁକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରି ଆପଣଙ୍କ Android ଟିଭିର ଡିଭାଇସ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ଯୋଗାଯୋଗ ବିଷୟରେ ଡାଟା ପଢ଼ିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ। ଏହି ଅନୁମତି ଆପଣଙ୍କର ଯୋଗାଯୋଗ ଡାଟାକୁ ସେଭ୍ କରିବା ପାଇଁ ଏବଂ ଆପଣଙ୍କ ବିନା ଜ୍ଞାତସାରରେ କ୍ଷତିକାରକ ଆପ୍ଗୁଡ଼ିକୁ ହୁଏତ ସେୟାର୍ କରିବା ପାଇଁ ଆପ୍ଗୁଡ଼ିକୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"ଜଣେ ନିର୍ଦ୍ଦିଷ୍ଟ ବ୍ୟକ୍ତିଙ୍କ ସହ ଆପଣ କେତେ ବ୍ୟବଧାନରେ କଲ୍, ଇମେଲ ତଥା ଯୋଗାଯୋଗ କରିଛନ୍ତି, ସେସବୁ ଅନ୍ତର୍ଭୁକ୍ତ କରି ଆପଣଙ୍କ ଫୋନ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ଯୋଗାଯୋଗ ବିଷୟରେ ଡାଟା ପଢିବାକୁ ଆପ୍କୁ ଅନୁମତି ଦିଏ। ଏହି ଅନୁମତି ଦ୍ୱାରା ଆପ୍ଟି ଆପଣଙ୍କ ଯୋଗାଯୋଗ ଡାଟା ସେଭ୍ କରିପାରିବ ଏବଂ ହାନୀକାରକ ଆପ୍ ଆପଣଙ୍କ ବିନା ଜ୍ଞାତସାରରେ ଯୋଗାଯୋଗ ଡାଟା ସେୟାର୍ କରିପାରନ୍ତି।"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"ଏହା ଆପଣଙ୍କ ଟାବ୍ଲେଟ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ଯୋଗାଯୋଗଗୁଡ଼ିକ ବିଷୟରେ ଡାଟା ପଢ଼ିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ। ଆପଣଙ୍କର ଟାବ୍ଲେଟ୍ରେ ଥିବା ଆକାଉଣ୍ଟଗୁଡ଼ିକ ଯେଉଁଥିରେ ଯୋଗାଯୋଗଗୁଡ଼ିକ ତିଆରି ହୋଇଛି, ସେଗୁଡ଼ିକୁ ଆପ୍ସର ଆକ୍ସେସ୍ ରହିବ। ଆପଣ ଇନ୍ଷ୍ଟଲ୍ କରିଥିବା ଆପ୍ସ ମାଧ୍ୟମରେ ତିଆରି କରାଯାଇଥିବା ଆକାଉଣ୍ଟଗୁଡ଼ିକୁ ଏହା ସାମିଲ କରିପାରେ। ଏହି ଅନୁମତି ଆପ୍ସକୁ ଆପଣଙ୍କର ଯୋଗାଯୋଗ ଡାଟା ସେଭ୍ କରିବାକୁ ଦିଏ ଏବଂ ହାନୀକାରକ ଆପ୍ ଆପଣଙ୍କ ଅଜାଣତରେ ଯୋଗାଯୋଗ ଡାଟା ସେୟାର୍ କରିପାରେ।"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"ଏହା ଆପଣଙ୍କ Android TV ଡିଭାଇସ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ଯୋଗାଯୋଗ ବିଷୟରେ ଡାଟା ପଢ଼ିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ। ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍ରେ ଥିବା ଆକାଉଣ୍ଟଗୁଡ଼ିକ ଯେଉଁଥିରେ ଯୋଗାଯୋଗଗୁଡ଼ିକ ତିଆରି ହୋଇଛି, ସେଗୁଡ଼ିକୁ ମଧ୍ୟ ଆପ୍ସର ଆକ୍ସେସ୍ ରହିବ। ଆପଣ ଇନ୍ଷ୍ଟଲ୍ କରିଥିବା ଆପ୍ସ ମାଧ୍ୟମରେ ତିଆରି କରାଯାଇଥିବା ଆକାଉଣ୍ଟଗୁଡ଼ିକୁ ଏହା ସାମିଲ କରିପାରେ। ଏହି ଅନୁମତି ଆପ୍ସକୁ ଆପଣଙ୍କର ଯୋଗାଯୋଗ ଡାଟା ସେଭ୍ କରିବାକୁ ଦିଏ ଏବଂ ହାନୀକାରକ ଆପ୍ ଆପଣଙ୍କ ଅଜାଣତରେ ଯୋଗାଯୋଗ ଡାଟା ସେୟାର୍ କରିପାରେ।"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ଏହା ଆପଣଙ୍କ ଫୋନ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ଯୋଗାଯୋଗଗୁଡ଼ିକ ବିଷୟରେ ଡାଟା ପଢ଼ିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ। ଆପଣଙ୍କର ଫୋନ୍ରେ ଥିବା ଆକାଉଣ୍ଟଗୁଡ଼ିକ ଯେଉଁଥିରେ ଯୋଗାଯୋଗଗୁଡ଼ିକ ତିଆରି ହୋଇଛି, ସେଗୁଡ଼ିକୁ ଆପ୍ସର ଆକ୍ସେସ୍ ରହିବ। ଆପଣ ଇନ୍ଷ୍ଟଲ୍ କରିଥିବା ଆପ୍ସ ମାଧ୍ୟମରେ ତିଆରି କରାଯାଇଥିବା ଆକାଉଣ୍ଟଗୁଡ଼ିକୁ ଏହା ସାମିଲ କରିପାରେ। ଏହି ଅନୁମତି ଆପ୍ସକୁ ଆପଣଙ୍କର ଯୋଗାଯୋଗ ଡାଟା ସେଭ୍ କରିବାକୁ ଦିଏ ଏବଂ ହାନୀକାରକ ଆପ୍ ଆପଣଙ୍କ ଅଜାଣତରେ ଯୋଗାଯୋଗ ଡାଟା ସେୟାର୍ କରିପାରେ।"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"ନିଜ ଯୋଗାଯୋଗ ସଂଶୋଧନ କରନ୍ତୁ"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"ଜଣେ ନିର୍ଦ୍ଦିଷ୍ଟ ଯୋଗାଯୋଗଙ୍କ ସହ ଆପଣ କେତେ ବ୍ୟବଧାନରେ କଲ୍, ଇମେଲ ତଥା ଯୋଗାଯୋଗ କରିଛନ୍ତି, ସେସବୁ ଅନ୍ତର୍ଭୁକ୍ତ କରି ଆପଣଙ୍କ ଟାବଲେଟ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ଯୋଗାଯୋଗ ବିଷୟକ ଡାଟା ବଦଳାଇବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦିଏ। ଏହି ଅନୁମତି ଦ୍ୱାରା ଆପ୍ଟି ଯୋଗାଯୋଗ ଡାଟା ଡିଲିଟ୍ କରିପାରେ।"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"ଅନ୍ୟ ପ୍ରକାରରେ ନିର୍ଦ୍ଦିଷ୍ଟ ଯୋଗାଯୋଗ ସହ ଆପଣ କେତେ ବ୍ୟବଧାନରେ କଲ୍, ଇମେଲ୍ ତଥା ଯୋଗାଯୋଗ କରିଛନ୍ତି, ସେସବୁକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରି ଆପଣଙ୍କ Android ଟିଭି ଡିଭାଇସ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ଯୋଗାଯୋଗ ବିଷୟରେ ଡାଟା ସଂଶୋଧନ କରିବାକୁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ। ଯୋଗାଯୋଗ ଡାଟା ଡିଲିଟ୍ କରିବା ପାଇଁ ଆପ୍ସକୁ ଏହାର ଅନୁମତି ଦେଇଥାଏ।"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"ଜଣେ ନିର୍ଦ୍ଦିଷ୍ଟ ଯୋଗାଯୋଗଙ୍କ ସହ ଆପଣ କେତେ ବ୍ୟବଧାନରେ କଲ୍, ଇମେଲ ତଥା ଯୋଗାଯୋଗ କରିଛନ୍ତି, ସେସବୁ ଅନ୍ତର୍ଭୁକ୍ତ କରି ଆପଣଙ୍କ ଫୋନ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ଯୋଗାଯୋଗ ବିଷୟରେ ଡାଟା ବଦଳାଇବାକୁ ଆପ୍କୁ ଅନୁମତି ଦିଏ। ଏହି ଅନୁମତି ଦ୍ୱାରା ଆପ୍ଟି ଯୋଗାଯୋଗ ଡାଟା ଡିଲିଟ୍ କରିପାରେ।"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"ଏହା ଆପଣଙ୍କ ଟାବ୍ଲେଟ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ଯୋଗାଯୋଗ ବିଷୟରେ ଡାଟା ସଂଶୋଧନ କରିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ। ଏହି ଅନୁମତି ଆପ୍ସକୁ ଆପଣଙ୍କର ଯୋଗାଯୋଗ ଡାଟା ଡିଲିଟ୍ କରିବାକୁ ଦିଏ।"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"ଏହା ଆପଣଙ୍କ Android TV ଡିଭାଇସ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ଯୋଗାଯୋଗ ବିଷୟରେ ଡାଟା ସଂଶୋଧନ କରିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ। ଏହି ଅନୁମତି ଆପ୍ସକୁ ଆପଣଙ୍କର ଯୋଗାଯୋଗ ଡାଟା ଡିଲିଟ୍ କରିବାକୁ ଦିଏ।"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"ଏହା ଆପଣଙ୍କ ଫୋନ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ଯୋଗାଯୋଗ ବିଷୟରେ ଡାଟା ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ। ଏହି ଅନୁମତି ଆପ୍ସକୁ ଆପଣଙ୍କର ଯୋଗାଯୋଗ ଡାଟା ଡିଲିଟ୍ କରିବାକୁ ଦିଏ।"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"କଲ୍ ଲଗ୍ ପଢ଼ନ୍ତୁ"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"ଏହି ଆପ୍ ଆପଣଙ୍କ କଲ୍ ହିଷ୍ଟୋରୀ ପଢ଼ିପାରେ।"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"କଲ୍ ଲଗ୍ ଲେଖନ୍ତୁ"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"ଅତିରିକ୍ତ ଲୋକେସନ୍ ପ୍ରଦାନକାରୀ କମାଣ୍ଡକୁ ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"ଅତିରିକ୍ତ ଲୋକେସନ୍ ପ୍ରଦାନକାରୀ କମାଣ୍ଡ ଆକ୍ସେସ୍ କରିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦିଏ। GPS କିମ୍ବା ଅନ୍ୟ ଲୋକେସନ୍ ସୋର୍ସଗୁଡିକରେ ଆପ୍ଟି ପ୍ରଭାବ ପକାଇପାରେ।"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"କେବଳ ସମ୍ମୁଖଭାଗରେ ସଠିକ୍ ଲୋକେଶନ୍ର ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"ଏହି ଆପ୍ ଯେତେବେଳେ ସମ୍ମୁଖଭାଗରେ ଥିବାବେଳେ ଆପଣଙ୍କର ସଠିକ୍ ଲୋକେସନ୍ ପ୍ରାପ୍ତ କରିପାରିବ। ଏହି ଲୋକେସନ୍ ସେବାଗୁଡ଼ିକ ନିଶ୍ଚିତରୂପେ ଅନ୍ ରହିବା ଦରକାର ଏବଂ ଆପ୍ର ବ୍ୟବହାର ପାଇଁ ଫୋନ୍ରେ ଉପଲବ୍ଧ ଥିବା ଦରକାର। ଏହା ବ୍ୟାଟେରୀ ଅଧିକା ଖର୍ଚ୍ଚ କରିପାରେ।"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"କେବଳ ସମ୍ମୁଖଭାଗରେ ହାରାହାରି ଲୋକେସନ୍ (ନେଟ୍ୱର୍କ-ଆଧାରିତ)ର ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"ସେଲ୍ ଟାୱାର ଓ ୱାଇ-ଫାଇ ନେଟ୍ୱର୍କ ପରି ଉତ୍ସକୁ ଆଧାର କରି ଏହି ଆପ୍ ଆପଣଙ୍କ ଲୋକେସନ୍ ପ୍ରାପ୍ତ କରିପାରିବ। ଏହି ଲୋକେସନ୍ ସେବାଗୁଡ଼ିକର ବ୍ୟବହାର କରିବାକୁ ସେଗୁଡ଼ିକ ଚାଲୁ କରାଯିବା ଏବଂ ଆପଣଙ୍କ ଟାବ୍ଲେଟ୍ରେ ଉପଲବ୍ଧ ଥିବା ଜରୁରୀ ଅଟେ।"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"ଏହି ଆପ୍, ସେଲ୍ ଟାୱାର ଓ ୱାଇ-ଫାଇ ନେଟ୍ୱାର୍କ ପରି ଉତ୍ସକୁ ଆଧାର କରି ଆପଣଙ୍କ ଲୋକେସନ୍ ପ୍ରାପ୍ତ କରିପାରିବ, କିନ୍ତୁ ଯେତେବେଳେ ଆପ୍ କେବଳ ସମ୍ମୁଖଭାଗରେ ରହିଥାଏ। ଏହି ଲୋକେସନ୍ ସେବାଗୁଡ଼ିକୁ ଚାଲୁ କରାଯିବା ଏବଂ ଆପ୍ ସେଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବାକୁ ସକ୍ଷମ ହେବା ପାଇଁ ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍ରେ ଉପଲବ୍ଧ ହେବା ଉଚିତ।"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"ସେଲ୍ ଟାୱାର ଓ ୱାଇ-ଫାଇ ନେଟ୍ୱର୍କ ପରି ଉତ୍ସକୁ ଆଧାର କରି ଏହି ଆପ୍ ଆପଣଙ୍କ ଲୋକେସନ୍ ପ୍ରାପ୍ତ କରିପାରିବ। ଏହି ଲୋକେସନ୍ ସେବାଗୁଡ଼ିକର ବ୍ୟବହାର କରିବାକୁ ସେଗୁଡ଼ିକ ଚାଲୁ କରାଯିବା ଏବଂ ଆପଣଙ୍କ ଫୋନ୍ରେ ଉପଲବ୍ଧ ଥିବା ଜରୁରୀ ଅଟେ।"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"ଏହି ଆପ୍ କେବଳ ସମ୍ମୁଖ ପଟରେ ଥିବାବେଳେ ଆପଣଙ୍କର ସଠିକ୍ ଲୋକେସନ୍ ପ୍ରାପ୍ତ କରିପାରିବ। ଆପଣଙ୍କ ଡିଭାଇସ୍ରେ ଲୋକେସନ୍ ସେବା ଚାଲୁ ଏବଂ ଉପଲବ୍ଧ ହେବା ଦରକାର ଯେପରି ଆପ୍ ସେଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବାକୁ ସକ୍ଷମ ହେବ। ଏହା ବ୍ୟାଟେରୀ ଅଧିକା ଖର୍ଚ୍ଚ କରିପାରେ।"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"କେବଳ ସମ୍ମୁଖପଟରେ ହାରାହାରି ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"ଏହି ଆପ୍ କେବଳ ସେତେବେଳେ ଆପଣଙ୍କର ଆନୁମାନିକ ଲୋକେସନ୍ ପାଇପାରିବ, ଯେତେବେଳେ ଏହା ସମ୍ମୁଖପଟରେ ଥିବ। ଆପଣଙ୍କ ଡିଭାଇସ୍ରେ ଲୋକେସନ୍ ସେବାଗୁଡ଼ିକ ଚାଲୁ ଏବଂ ଉପଲବ୍ଧ ହେବା ଦରକାର ଯେପରି ଆପ୍ ସେଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିବାକୁ ସକ୍ଷମ ହେବ।"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"ବ୍ୟାକ୍ଗ୍ରାଉଣ୍ଡ୍ରେ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"ଅନୁମାନିତ କିମ୍ବା ବିଲ୍କୁଲ୍ ସଠିକ୍ ସ୍ଥାନ ଆକ୍ସେସ୍ କରିବାର ଅନୁମତି ଅତିରିକ୍ତ ଭାବରେ ଦିଆଗଲେ, ବ୍ୟାକ୍ଗ୍ରାଉଣ୍ଡରେ ଚାଲୁଥିବା ସମୟରେ ଆପ୍ ଆପଣଙ୍କର ସ୍ଥାନର ଆକ୍ସେସ୍ କରିପାରିବ।"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"ଏହି ଆପ୍ ସମ୍ମୁଖପଟ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରିବା ସହ ପୃଷ୍ଠପଟରେ ଚାଲିବା ସମୟରେ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରିପାରିବ।"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"ଆପଣଙ୍କ ଅଡିଓ ସେଟିଙ୍ଗକୁ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"ଆପ୍କୁ ଗ୍ଲୋବାଲ୍ ଅଡିଓ ସେଟିଙ୍ଗ, ଯେପରିକି ଭଲ୍ୟୁମ୍କୁ ସଂଶୋଧିତ କରିବାକୁ ଏବଂ ଆଉଟପୁଟ୍ ପାଇଁ ସ୍ପିକର୍ ବ୍ୟବହାର କରିବାକୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ଅଡିଓ ରେକର୍ଡ କରନ୍ତୁ"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ଟାବଲେଟ୍ରେ ଥିବା ବ୍ଲୁ-ଟୁଥ୍ର କନଫିଗରେଶନ୍ ଦେଖିବାକୁ ଏବଂ ପେୟାର୍ କରାଯାଇଥିବା ଡିଭାଇସ୍ ସହିତ ସଂଯୋଗ ସ୍ୱୀକାର କରିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"ଆପଣଙ୍କର Android ଟିଭି ଡିଭାଇସ୍ରେ ବ୍ଲୁଟୁଥ୍ର କନଫିଗ୍ରେସନ୍ ଦେଖିବା ପାଇଁ ଏବଂ ପେୟାର୍ କରାଯାଇଥିବା ଡିଭାଇସ୍ଗୁଡ଼ିକ ସହ ସଂଯୋଗଗୁଡ଼ିକୁ ତିଆରି ଏବଂ ସ୍ୱୀକାର କରିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ଫୋନ୍ରେ ଥିବା ବ୍ଲୁ-ଟୁଥ୍ର କନଫିଗରେଶନ୍ ଦେଖିବାକୁ ଏବଂ ପେୟାର୍ କରାଯାଇଥିବା ଡିଭାଇସ୍ ସହିତ ସଂଯୋଗ ସ୍ୱୀକାର କରିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ନିଅର୍ ଫିଲ୍ଡ କମ୍ୟୁନିକେଶନ୍ ଉପରେ ନିୟନ୍ତ୍ରଣ ରଖନ୍ତୁ"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"ନିଅର୍ ଫିଲ୍ଡ କମ୍ୟୁନିକେସନ୍ନ (NFC) ଟାଗ୍, କାର୍ଡ ଓ ରିଡରଗୁଡ଼ିକ ସହ ଯୋଗାଯୋଗ କରିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"ଆପଣଙ୍କ ସ୍କ୍ରୀନ୍ ଲକ୍ ଅକ୍ଷମ କରନ୍ତୁ"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ସହ କନେକ୍ଟ କରାଗଲା"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ଫାଇଲ୍ ଦେଖିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="pin_target" msgid="8036028973110156895">"ପିନ୍"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"ଅନପିନ୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"ଆପ୍ ସୂଚନା"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ଡେମୋ ଆରମ୍ଭ କରାଯାଉଛି…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"ରେ: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ଏବଂ <xliff:g id="TYPE_2">%3$s</xliff:g> ଆଇଟମ୍ଗୁଡ଼ିକ ଅପ୍ଡେଟ୍ କରିବେ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"ସେଭ୍ କରନ୍ତୁ"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"ନାଁ, ପଚାରିଥିବାରୁ ଧନ୍ୟବାଦ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"ଏବେ ନୁହେଁ"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"କେବେ ବି ନୁହେଁ"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"ଅପ୍ଡେଟ୍ କରନ୍ତୁ"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"ଜାରି ରଖନ୍ତୁ"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"ପାସୱର୍ଡ୍"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ଦୁଇଟି ସ୍କ୍ରିନ୍ ମଧ୍ୟରେ ଟୋଗଲ୍ କରନ୍ତୁ"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ସ୍କ୍ରିନ୍ ଲକ୍ କରନ୍ତୁ"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ସ୍କ୍ରିନ୍ସଟ୍ ନିଅନ୍ତୁ"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"ପପ୍-ଅପ୍ ୱିଣ୍ଡୋରେ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପ୍"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>ର କ୍ୟାପ୍ସନ୍ ବାର୍।"</string>
</resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 7760db0..be40fa3 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਜਾਂ ਤਾਂ ਗੁੰਮਸ਼ੁਦਾ ਹੈ ਜਾਂ ਖਰਾਬ ਹੈ। ਨਤੀਜੇ ਵਜੋਂ, ਤੁਹਾਡੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਸਬੰਧਿਤ ਡਾਟਾ ਮਿਟਾਇਆ ਗਿਆ ਹੈ। ਸਹਾਇਤਾ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹੁਣ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ਕਈ ਵਾਰ ਗਲਤ ਪਾਸਵਰਡ ਦਾਖਲ ਕੀਤਾ ਗਿਆ"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨਿੱਜੀ ਵਰਤੋਂ ਲਈ ਡੀਵਾਈਸ ਤਿਆਗਿਆ"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਨ ਅਧੀਨ ਹੈ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ਤੁਹਾਡਾ ਸੰਗਠਨ ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦਾ ਹੈ ਅਤੇ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਮਿਟਾਇਆ ਜਾਏਗਾ"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"ਐਪ ਨੂੰ ਸਟਿੱਕੀ ਪ੍ਰਸਾਰਨ ਭੇਜਣ ਦਿੰਦੀ ਹੈ, ਜੋ ਪ੍ਰਸਾਰਨ ਦੇ ਖਤਮ ਹੋਣ ਤੋਂ ਬਾਅਦ ਵੀ ਰਹਿੰਦੇ ਹਨ। ਹੱਦੋਂ ਵੱਧ ਵਰਤੋਂ ਇਸ ਵੱਲੋਂ ਬਹੁਤ ਜ਼ਿਆਦਾ ਮੈਮੋਰੀ ਵਰਤੇ ਜਾਣ ਦਾ ਕਾਰਨ ਬਣਕੇ ਡੀਵਾਈਸ ਨੂੰ ਧੀਮਾ ਜਾਂ ਅਸਥਿਰ ਬਣਾ ਸਕਦੀ ਹੈ।"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ਐਪ ਨੂੰ ਸਟਿਕੀ ਪ੍ਰਸਾਰਨ ਭੇਜਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜੋ ਪ੍ਰਸਾਰਨ ਦੇ ਖਤਮ ਹੋਣ ਤੋਂ ਬਾਅਦ ਰਹਿੰਦੇ ਹਨ। ਵਾਧੂ ਵਰਤੋਂ ਫ਼ੋਨ ਨੂੰ ਹੌਲੀ ਜਾਂ ਬਹੁਤ ਜ਼ਿਆਦਾ ਮੈਮਰੀ ਵਰਤ ਕੇ ਇਸਨੂੰ ਅਸਥਿਰ ਬਣਾ ਸਕਦੀ ਹੈ।"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"ਆਪਣੇ ਸੰਪਰਕ ਪੜ੍ਹੋ"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ ਹੈ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ ਅਤੇ ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡਾਟਾ ਸਾਂਝਾ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦਿੰਦੀ ਹੈ, ਇਸ ਵਿੱਚ ਸ਼ਾਮਲ ਹੈ ਕਿ ਤੁਸੀਂ ਵਿਅਕਤੀ ਵਿਸ਼ੇਸ਼ਾਂ ਨਾਲ ਕਿਸ ਬਾਰੰਬਾਰਤਾ ਨਾਲ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਦਿੰਦੀ ਹੈ ਅਤੇ ਭੈੜੀਆਂ ਐਪਾਂ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡਾਟਾ ਸਾਂਝਾ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ ਹੈ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ ਅਤੇ ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡਾਟਾ ਸਾਂਝਾ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦਿੰਦੀ ਹੈ। ਐਪਾਂ ਕੋਲ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਦੇ ਉਹਨਾਂ ਖਾਤਿਆਂ ਤੱਕ ਵੀ ਪਹੁੰਚ ਹੋਵੇਗੀ ਜਿਨ੍ਹਾਂ ਨੇ ਸੰਪਰਕ ਬਣਾਏ ਹਨ। ਇਸ ਵਿੱਚ ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਐਪਾਂ ਵੱਲੋਂ ਬਣਾਏ ਗਏ ਖਾਤੇ ਸ਼ਾਮਲ ਹੋ ਸਕਦੇ ਹਨ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਦਿੰਦੀ ਹੈ ਅਤੇ ਨੁਕਸਾਨਦੇਹ ਐਪਾਂ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡਾਟਾ ਸਾਂਝਾ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦਿੰਦੀ ਹੈ। ਐਪਾਂ ਕੋਲ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ ਦੇ ਉਹਨਾਂ ਖਾਤਿਆਂ ਤੱਕ ਵੀ ਪਹੁੰਚ ਹੋਵੇਗੀ ਜਿਨ੍ਹਾਂ ਨੇ ਸੰਪਰਕ ਬਣਾਏ ਹਨ। ਇਸ ਵਿੱਚ ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਐਪਾਂ ਵੱਲੋਂ ਬਣਾਏ ਗਏ ਖਾਤੇ ਸ਼ਾਮਲ ਹੋ ਸਕਦੇ ਹਨ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਦਿੰਦੀ ਹੈ ਅਤੇ ਨੁਕਸਾਨਦੇਹ ਐਪਾਂ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡਾਟਾ ਸਾਂਝਾ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦਿੰਦੀ ਹੈ। ਐਪਾਂ ਕੋਲ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੇ ਉਹਨਾਂ ਖਾਤਿਆਂ ਤੱਕ ਵੀ ਪਹੁੰਚ ਹੋਵੇਗੀ ਜਿਨ੍ਹਾਂ ਨੇ ਸੰਪਰਕ ਬਣਾਏ ਹਨ। ਇਸ ਵਿੱਚ ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਐਪਾਂ ਵੱਲੋਂ ਬਣਾਏ ਗਏ ਖਾਤੇ ਸ਼ਾਮਲ ਹੋ ਸਕਦੇ ਹਨ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਦਿੰਦੀ ਹੈ ਅਤੇ ਨੁਕਸਾਨਦੇਹ ਐਪਾਂ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਸੰਪਰਕ ਡਾਟਾ ਸਾਂਝਾ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"ਆਪਣੇ ਸੰਪਰਕ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਟੈਬਲੈੱਟ ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖ਼ਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਸੰਪਰਕ ਡਾਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਸੋਧਣ ਦਿੰਦੀ ਹੈ, ਇਸ ਵਿੱਚ ਉਹ ਬਾਰੰਬਾਰਤਾ ਵੀ ਸ਼ਾਮਲ ਹੈ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਵਿਸ਼ੇਸ਼ ਸੰਪਰਕਾਂ ਨੂੰ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ ਹੈ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਸੰਪਰਕ ਡਾਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਉਸ ਬਾਰੰਬਾਰਤਾ ਸਮੇਤ ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਕਾਲ ਕੀਤੀ ਹੈ, ਈਮੇਲ ਕੀਤੀ ਹੈ ਜਾਂ ਖ਼ਾਸ ਵਿਅਕਤੀਆਂ ਨਾਲ ਹੋਰ ਤਰੀਕਿਆਂ ਨਾਲ ਸੰਚਾਰ ਕੀਤਾ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਤੁਹਾਡਾ ਸੰਪਰਕ ਡਾਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਸੋਧਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਸੰਪਰਕ ਡਾਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਸੋਧਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਸੰਪਰਕ ਡਾਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਬਾਰੇ ਡਾਟਾ ਸੋਧਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ। ਇਹ ਇਜਾਜ਼ਤ ਐਪਾਂ ਨੂੰ ਸੰਪਰਕ ਡਾਟਾ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"ਕਾਲ ਲੌਗ ਪੜ੍ਹੋ"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"ਇਹ ਐਪ ਤੁਹਾਡਾ ਕਾਲ ਇਤਿਹਾਸ ਪੜ੍ਹ ਸਕਦੀ ਹੈ।"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"ਕਾਲ ਲੌਗ ਲਿਖੋ"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"ਵਾਧੂ ਟਿਕਾਣਾ ਪ੍ਰਦਾਤਾ ਕਮਾਂਡਾਂ ਤੱਕ ਪਹੁੰਚ"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"ਐਪ ਨੂੰ ਵਾਧੂ ਟਿਕਾਣਾ ਪ੍ਰਦਾਤਾ ਕਮਾਂਡਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ GPS ਜਾਂ ਹੋਰ ਟਿਕਾਣਾ ਸਰੋਤਾਂ ਦੇ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ।"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"ਸਿਰਫ਼ ਫੋਰਗ੍ਰਾਊਂਡ ਵਿੱਚ ਸਟੀਕ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"ਇਹ ਐਪ ਫੋਰਗ੍ਰਾਉਂਡ ਵਿੱਚ ਹੋਣ \'ਤੇ ਹੀ ਤੁਹਾਡਾ ਸਟੀਕ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ। ਇਸ ਨਾਲ ਬੈਟਰੀ ਦੀ ਖਪਤ ਵਧ ਸਕਦੀ ਹੈ।"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"ਸਿਰਫ਼ ਫੋਰਗ੍ਰਾਊਂਡ ਵਿੱਚ ਅਨੁਮਾਨਿਤ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ (ਨੈੱਟਵਰਕ-ਆਧਾਰਿਤ)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ, ਪਰ ਸਿਰਫ਼ ਐਪ ਦੇ ਫੋਰਗ੍ਰਾਊਂਡ ਹੋਣ \'ਤੇ ਹੀ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੀ ਟੈਬਲੈੱਟ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ, ਪਰ ਸਿਰਫ਼ ਐਪ ਦੇ ਫੋਰਗ੍ਰਾਊਂਡ ਹੋਣ \'ਤੇ ਹੀ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ Android TV ਟੀਵੀ ਡੀਵਾਈਸ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ, ਪਰ ਸਿਰਫ਼ ਐਪ ਦੇ ਫੋਰਗ੍ਰਾਊਂਡ ਹੋਣ \'ਤੇ ਹੀ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"ਇਹ ਐਪ ਸਿਰਫ਼ ਉਦੋਂ ਤੁਹਾਡਾ ਸਟੀਕ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ, ਜਦੋਂ ਇਹ ਸਕ੍ਰੀਨ \'ਤੇ ਹੋਵੇ। ਐਪ ਦੇ ਵਰਤਣ ਲਈ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦਾ ਚਾਲੂ ਹੋਣਾ ਅਤੇ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਉਪਲਬਧ ਹੋਣਾ ਲਾਜ਼ਮੀ ਹੈ। ਇਸ ਨਾਲ ਬੈਟਰੀ ਦੀ ਖਪਤ ਵਧ ਸਕਦੀ ਹੈ।"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"ਸਿਰਫ਼ ਸਕ੍ਰੀਨ \'ਤੇ ਅੰਦਾਜ਼ਨ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"ਇਹ ਐਪ ਸਿਰਫ਼ ਉਦੋਂ ਤੁਹਾਡਾ ਅੰਦਾਜ਼ਨ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ, ਜਦੋਂ ਇਹ ਸਕ੍ਰੀਨ \'ਤੇ ਹੋਵੇ। ਐਪ ਦੇ ਵਰਤਣ ਲਈ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦਾ ਚਾਲੂ ਹੋਣਾ ਅਤੇ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਉਪਲਬਧ ਹੋਣਾ ਲਾਜ਼ਮੀ ਹੈ।"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"ਐਪ ਨੂੰ ਵਧੀਕ ਤੌਰ \'ਤੇ ਅਨੁਮਾਨਿਤ ਜਾਂ ਸਟੀਕ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਦੇਣ \'ਤੇ ਇਹ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ ਵੇਲੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"ਸਕ੍ਰੀਨ \'ਤੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਤੋਂ ਇਲਾਵਾ, ਇਹ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ ਵੇਲੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ।"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"ਆਪਣੀਆਂ ਆਡੀਓ ਸੈਟਿੰਗਾਂ ਬਦਲੋ"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"ਐਪ ਨੂੰ ਗਲੋਬਲ ਆਡੀਓ ਸੈਟਿੰਗਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਜਿਵੇਂ ਅਵਾਜ਼ ਅਤੇ ਆਊਟਪੁਟ ਲਈ ਕਿਹੜਾ ਸਪੀਕਰ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ।"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">" ਆਡੀਓ ਰਿਕਾਰਡ ਕਰਨ"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ਐਪ ਨੂੰ ਟੈਬਲੈੱਟ ਤੇ ਬਲੂਟੁੱਥ ਦਾ ਸੰਰੂਪਣ ਦੇਖਣ, ਜੋੜਾਬੱਧ ਕੀਤੇ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਸ਼ਨ ਬਣਾਉਣ ਅਤੇ ਸਵੀਕਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਬਲੂਟੁੱਥ ਦਾ ਸੰਰੂਪਣ ਦੇਖਣ, ਜੋੜਾਬੱਧ ਕੀਤੇ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਸ਼ਨ ਬਣਾਉਣ ਅਤੇ ਸਵੀਕਾਰ ਕਰਨ ਦਿੰਦੀ ਹੈ।"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ਐਪ ਨੂੰ ਬਲੂਟੁੱਥ ਤੇ ਬਲੂਟੁੱਥ ਦਾ ਸੰਰੂਪਣ ਦੇਖਣ, ਜੋੜਾਬੱਧ ਕੀਤੇ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਸ਼ਨ ਬਣਾਉਣ ਅਤੇ ਸਵੀਕਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ਨਜ਼ਦੀਕੀ ਖੇਤਰ ਸੰਚਾਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਖੇਤਰ ਸੰਚਾਰ (NFC) ਟੈਗਾਂ, ਕਾਰਡਾਂ ਅਤੇ ਰੀਡਰਾਂ ਨਾਲ ਸੰਚਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"ਆਪਣਾ ਸਕ੍ਰੀਨ ਲਾਕ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋਈ"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ਫ਼ਾਈਲਾਂ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="pin_target" msgid="8036028973110156895">"ਪਿੰਨ ਕਰੋ"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"ਅਨਪਿੰਨ ਕਰੋ"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"ਐਪ ਜਾਣਕਾਰੀ"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ਡੈਮੋ ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"ਕੀ ਤੁਸੀਂ "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ਵਿੱਚ ਇਹਨਾਂ ਆਈਟਮਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, ਅਤੇ <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"ਰੱਖਿਅਤ ਕਰੋ"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"ਹੁਣੇ ਨਹੀਂ"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"ਕਦੇ ਵੀ ਨਹੀਂ"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"ਅੱਪਡੇਟ ਕਰੋ"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"ਜਾਰੀ ਰੱਖੋ"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"ਪਾਸਵਰਡ"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ਲਾਕ ਸਕ੍ਰੀਨ"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"ਪੌਪ-ਅੱਪ ਵਿੰਡੋ ਵਿੱਚ <xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ।"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਦੀ ਸੁਰਖੀ ਪੱਟੀ।"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 4ff7cc4..bc97691 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -192,8 +192,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Brakuje aplikacji administratora profilu do pracy lub jest ona uszkodzona. Dlatego Twój profil służbowy i związane z nim dane zostały usunięte. Skontaktuj się ze swoim administratorem, by uzyskać pomoc."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Twój profil służbowy nie jest już dostępny na tym urządzeniu"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Zbyt wiele prób podania hasła"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator odstąpił urządzenie do użytku osobistego"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Urządzenie jest zarządzane"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Twoja organizacja zarządza tym urządzeniem i może monitorować ruch w sieci. Kliknij, by dowiedzieć się więcej."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Twoje urządzenie zostanie wyczyszczone"</string>
@@ -387,13 +386,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Pozwala aplikacji wysyłać trwałe transmisje, które są zachowywane po ich zakończeniu. Nadmierne korzystanie z tej funkcji może powodować wolne lub niestabilne działanie urządzenia z Androidem TV z powodu użycia zbyt dużej ilości pamięci."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Pozwala aplikacji na wysyłanie transmisji trwałych, które pozostają aktywne po zakończeniu połączenia. Nadmierne używanie może spowolnić lub zdestabilizować telefon przez wymuszenie zbyt dużego użycia pamięci."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"odczytywanie kontaktów"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Pozwala aplikacji na odczyt danych o kontaktach zapisanych na tablecie, w tym informacji o częstotliwości rozmawiania, przesyłania e-maili i komunikowania się w inny sposób z poszczególnymi osobami. Aplikacje z tym uprawnieniem mogą zapisywać dane kontaktów, a złośliwe aplikacje mogą je udostępniać bez Twojej wiedzy."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Pozwala aplikacji odczytywać dane o Twoich kontaktach zapisanych na urządzeniu z Androidem TV, wraz z informacjami o tym, jak często dzwonisz lub piszesz e-maile do określonych osób albo komunikujesz się z nimi na inne sposoby. Aplikacje z tym uprawnieniem mogą zapisywać dane kontaktów, a złośliwe aplikacje mogą je udostępniać bez Twojej wiedzy."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Pozwala aplikacji na odczyt danych o kontaktach zapisanych na telefonie, w tym informacji o częstotliwości rozmawiania, przesyłania e-maili i komunikowania się w inny sposób z poszczególnymi osobami. Aplikacje z tym uprawnieniem mogą zapisywać dane kontaktów, a złośliwe aplikacje mogą je udostępniać bez Twojej wiedzy."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Pozwala aplikacji odczytywać dane Twoich kontaktów zapisane na tablecie. Aplikacje będą również miały dostęp do kont na tablecie, na których utworzono kontakty. Może to obejmować konta utworzone przez zainstalowane aplikacje. Aplikacje z tymi uprawnieniami mogą zapisywać dane kontaktów, a złośliwe aplikacje mogą je udostępniać bez Twojej wiedzy."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Pozwala aplikacji odczytywać dane Twoich kontaktów zapisane na urządzeniu z Androidem TV. Aplikacje będą również miały dostęp do kont na urządzeniu z Androidem TV, na których utworzono kontakty. Może to obejmować konta utworzone przez zainstalowane aplikacje. Aplikacje z tymi uprawnieniami mogą zapisywać dane kontaktów, a złośliwe aplikacje mogą je udostępniać bez Twojej wiedzy."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Pozwala aplikacji odczytywać dane Twoich kontaktów zapisane na telefonie. Aplikacje będą również miały dostęp do kont na telefonie, na których utworzono kontakty. Może to obejmować konta utworzone przez zainstalowane aplikacje. Aplikacje z tymi uprawnieniami mogą zapisywać dane kontaktów, a złośliwe aplikacje mogą je udostępniać bez Twojej wiedzy."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modyfikowanie kontaktów"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Pozwala aplikacji na modyfikowanie danych o kontaktach zapisanych na tablecie, w tym informacji o częstotliwości rozmawiania, przesyłania e-maili i komunikowania się w inny sposób z poszczególnymi kontaktami. Aplikacje z tym uprawnieniem mogą usuwać dane kontaktów."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Pozwala aplikacji modyfikować dane o Twoich kontaktach zapisane na urządzeniu z Androidem TV, wraz z informacjami o tym, jak często dzwonisz lub piszesz e-maile do określonych osób albo komunikujesz się z nimi na inne sposoby. Aplikacje z tym uprawnieniem mogą usuwać dane kontaktów."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Pozwala aplikacji na modyfikowanie danych o kontaktach zapisanych na telefonie, w tym informacji o częstotliwości rozmawiania, przesyłania e-maili i komunikowania się w inny sposób z poszczególnymi kontaktami. Aplikacje z tym uprawnieniem mogą usuwać dane kontaktów."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Pozwala aplikacji odczytywać dane Twoich kontaktów zapisane na tablecie. Aplikacje z tymi uprawnieniami mogą usuwać dane kontaktów."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Pozwala aplikacji odczytywać dane Twoich kontaktów zapisane na urządzeniu z Androidem TV. Aplikacje z tymi uprawnieniami mogą usuwać dane kontaktów."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Pozwala aplikacji odczytywać dane Twoich kontaktów zapisane na telefonie. Aplikacje z tymi uprawnieniami mogą usuwać dane kontaktów."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"czytanie rejestru połączeń"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Ta aplikacja może odczytywać historię połączeń."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"zapisywanie rejestru połączeń"</string>
@@ -413,13 +412,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"dostęp do dodatkowych poleceń dostawcy informacji o lokalizacji"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Pozwala aplikacji na dostęp do dodatkowych poleceń dostawcy informacji o lokalizacji. Aplikacje z tym uprawnieniem mogą wpływać na działanie GPS-a lub innych źródeł lokalizacji."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"dostęp do dokładnej lokalizacji tylko na pierwszym planie"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Ta aplikacja może określić Twoją dokładną lokalizację tylko wtedy, gdy działa na pierwszym planie. Te usługi lokalizacyjne muszą być włączone i dostępne na telefonie, by aplikacja mogła z nich korzystać. Może to zwiększyć zużycie baterii."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"dostęp do przybliżonej lokalizacji (na podstawie sieci) tylko na pierwszym planie"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Ta aplikacja może określać Twoją lokalizację na podstawie źródeł sieciowych takich jak stacje bazowe i sieci Wi-Fi, ale tylko wtedy, gdy działa na pierwszym planie. Wymienione usługi lokalizacyjne muszą być włączone i dostępne na tablecie, by aplikacja mogła z nich korzystać."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Ta aplikacja może określać Twoją lokalizację na podstawie źródeł sieciowych takich jak stacje bazowe i sieci Wi-Fi, ale tylko wtedy, gdy działa na pierwszym planie. Aby aplikacja mogła korzystać z tych usług lokalizacyjnych, muszą one być włączone i dostępne na urządzeniu z Androidem TV."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Ta aplikacja może określać Twoją lokalizację na podstawie źródeł sieciowych takich jak stacje bazowe i sieci Wi-Fi, ale tylko wtedy, gdy działa na pierwszym planie. Wymienione usługi lokalizacyjne muszą być włączone i dostępne na telefonie, by aplikacja mogła z nich korzystać."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Ta aplikacja może określić Twoją dokładną lokalizację tylko wtedy, gdy działa na pierwszym planie. Usługi lokalizacyjne muszą być włączone i dostępne na urządzeniu, by aplikacja mogła z nich korzystać. Może to zwiększyć zużycie baterii."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"dostęp do przybliżonej lokalizacji tylko na pierwszym planie"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Ta aplikacja może określić Twoją przybliżoną lokalizację tylko wtedy, gdy działa na pierwszym planie. Usługi lokalizacyjne muszą być włączone i dostępne na urządzeniu, by aplikacja mogła z nich korzystać."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"dostęp do lokalizacji w tle"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Jeśli te uprawnienia zostaną przyznane wraz z dostępem do dokładnej lub przybliżonej lokalizacji, aplikacja będzie mogła uzyskiwać dostęp do lokalizacji podczas działania w tle."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Ta aplikacja może korzystać z lokalizacji, gdy działa w tle, niezależnie od dostępu do lokalizacji na pierwszym planie."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"zmienianie ustawień audio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Pozwala aplikacji na modyfikowanie globalnych ustawień dźwięku, takich jak głośność oraz urządzenie wyjściowe."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"nagrywanie dźwięku"</string>
@@ -500,6 +497,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Pozwala aplikacji na dostęp do konfiguracji Bluetooth na tablecie oraz na nawiązywanie i akceptowanie połączeń ze sparowanych urządzeń."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Pozwala aplikacji odczytywać konfigurację Bluetootha na urządzeniu z Androidem TV oraz nawiązywać i akceptować połączenia ze sparowanymi urządzeniami."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Pozwala aplikacji na dostęp do konfiguracji Bluetooth na telefonie oraz na nawiązywanie i akceptowanie połączeń ze sparowanych urządzeń."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolowanie łączności Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Pozwala aplikacji na komunikowanie się z tagami, kartami i czytnikami NFC (Near Field Communication)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"wyłączanie blokady ekranu"</string>
@@ -1926,7 +1927,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Połączono z: <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Dotknij, by wyświetlić pliki"</string>
<string name="pin_target" msgid="8036028973110156895">"Przypnij"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Odepnij"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"O aplikacji"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Uruchamiam tryb demo…"</string>
@@ -1971,6 +1976,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Zaktualizować w: "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" te elementy: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Zapisz"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nie, dziękuję"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Nie teraz"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nigdy"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Zaktualizuj"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Dalej"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"hasło"</string>
@@ -2068,5 +2075,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Przełącz podzielony ekran"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ekran blokady"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Zrzut ekranu"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> w wyskakującym okienku."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Pasek napisów w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 1750d2a..108d187 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"O app para administrador do perfil de trabalho não foi encontrado ou está corrompido. Consequentemente, seu perfil de trabalho e os dados relacionados foram excluídos. Entre em contato com seu administrador para receber assistência."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Seu perfil de trabalho não está mais disponível neste dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Muitas tentativas de senha"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador renunciou ao dispositivo para uso pessoal"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerenciado"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Sua organização gerencia este dispositivo e pode monitorar o tráfego de rede. Toque para ver detalhes."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Seu dispositivo será limpo"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permite ao app enviar transmissões fixas, que permanecem após o fim da transmissão. O uso excessivo pode causar lentidão ou instabilidade no seu dispositivo Android TV, devido ao aumento do uso de memória."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permite que o app envie transmissões fixas, que permanecem depois que a transmissão termina. O uso excessivo pode deixar o telefone lento ou instável, fazendo com que ele use muita memória."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"ler seus contatos"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Permite que o app leia dados dos contatos armazenados no tablet, incluindo a frequência com que você chamou, enviou e-mails ou se comunicou de qualquer outra forma com indivíduos específicos. Esta permissão autoriza o app a salvar seus dados de contato, e apps maliciosos podem compartilhar esses dados de contato sem seu conhecimento."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Permite que o app leia os dados sobre os contatos armazenados no seu dispositivo Android TV, incluindo a frequência de chamadas, e-mails e outras comunicações com pessoas específicas. Essa autorização permite que os apps salvem os dados dos seus contatos,. Tenha cuidado porque apps maliciosos podem compartilhar esses dados sem seu conhecimento."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Permite que o app leia dados dos contatos armazenados no telefone, incluindo a frequência com que você chamou, enviou e-mails ou se comunicou de qualquer outra forma com indivíduos específicos. Esta permissão autoriza o app a salvar seus dados de contato, e apps maliciosos podem compartilhar esses dados de contato sem seu conhecimento."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permite que o app leia dados sobre seus contatos armazenados no tablet. Os apps também terão acesso às contas no tablet que criaram contatos. Isso pode incluir contas criadas pelos apps que você instalou. Essa permissão autoriza os apps a salvarem os dados dos seus contatos, e apps maliciosos podem compartilhar esses dados sem seu conhecimento."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permite que o app leia dados sobre seus contatos armazenados no dispositivo Android TV. Os apps também terão acesso às contas no dispositivo Android TV que criaram contatos. Isso pode incluir contas criadas pelos apps que você instalou. Essa permissão autoriza os apps a salvarem os dados dos seus contatos, e apps maliciosos podem compartilhar esses dados sem seu conhecimento."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permite que o app leia dados sobre seus contatos armazenados no smartphone. Os apps também terão acesso às contas no smartphone que criaram contatos. Isso pode incluir contas criadas pelos apps que você instalou. Essa permissão autoriza os apps a salvarem os dados dos seus contatos, e apps maliciosos podem compartilhar esses dados sem seu conhecimento."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modificar seus contatos"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Permite que o app modifique os dados sobre os contatos armazenados no tablet, incluindo a frequência com que você fez chamadas, enviou e-mails ou se comunicou de outras formas com contatos específicos. Esta permissão autoriza o app a excluir dados de contatos."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Permite que o app modifique os dados dos contatos armazenados no seu dispositivo Android TV, incluindo a frequência de chamadas, e-mails e outras comunicações com contatos específicos. Essa permissão autoriza os apps a excluir dados dos contatos."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Permite que o app modifique os dados dos contatos armazenados no telefone, incluindo a frequência com que você fez chamadas, enviou e-mails ou se comunicou de outras formas com contatos específicos. Esta permissão autoriza o app a excluir dados de contatos."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permite que o app modifique os dados sobre os contatos armazenados no tablet. Essa permissão autoriza os apps a excluírem dados de contato."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permite que o app modifique os dados sobre os contatos armazenados no dispositivo Android TV. Essa permissão autoriza os apps a excluírem dados de contato."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permite que o app modifique os dados sobre os contatos armazenados no smartphone. Essa permissão autoriza os apps a excluírem dados de contato."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"ler registro de chamadas"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Este app pode ler seu histórico de chamadas."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"salvar no registo de chamadas"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acessar comandos extras do provedor de localização"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar localização precisa apenas em primeiro plano"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Este app pode ver sua localização exata a qualquer momento apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu smartphone para que o app possa usá-los. Isso pode aumentar o consumo de bateria."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"acessar localização aproximada (baseada em rede) apenas em primeiro plano"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu tablet para que o app possa usá-los."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu dispositivo Android TV para que o app possa usá-los."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu smartphone para que o app possa usá-los."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Este app pode ver seu local exato apenas quando está em primeiro plano. Os \"Serviços de localização\" precisam estar ativados e disponíveis no seu dispositivo para que o app possa usá-los. Isso pode aumentar o consumo de bateria."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acessar local aproximado apenas em primeiro plano"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Este app poderá acessar seu local aproximado somente quando estiver em primeiro plano. Os \"Serviços de localização\" precisam estar ativados e disponíveis no dispositivo para que o app possa usá-los."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"acessar a localização em segundo plano"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Se essa permissão for concedida, além do acesso à localização precisa ou aproximada, o app poderá acessar a localização durante a execução em segundo plano."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Esse app pode acessar o local em segundo plano, além do acesso em primeiro plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"alterar as suas configurações de áudio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permite que o app modifique configurações de áudio globais como volume e alto-falantes de saída."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"gravar áudio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permite que o app acesse a configuração do Bluetooth no tablet, além de fazer e aceitar conexões com dispositivos pareados."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permite que o app acesse a configuração do Bluetooth no dispositivo Android TV, além de fazer e aceitar conexões com dispositivos pareados."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permite que o app acesse a configuração do Bluetooth no telefone, além de fazer e aceitar conexões com dispositivos pareados."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Permite que o app se comunique com leitores, cartões e etiqueta NFC (comunicação a curta distância)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"desativar o bloqueio de tela"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Toque para ver os arquivos"</string>
<string name="pin_target" msgid="8036028973110156895">"Fixar guia"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Liberar guia"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Informações do app"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Iniciando demonstração…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Atualizar estes itens em "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Salvar"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Não, obrigado"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Agora não"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nunca"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Atualizar"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continuar"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"senha"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Ativar tela dividida"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Bloquear tela"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Capturar tela"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"App <xliff:g id="APP_NAME">%1$s</xliff:g> na janela pop-up."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de legendas do app <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 5c21c0d..0d2310d 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"A aplicação de administração do perfil de trabalho está em falta ou danificada. Consequentemente, o seu perfil de trabalho e os dados relacionados foram eliminados. Contacte o gestor para obter assistência."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"O seu perfil de trabalho já não está disponível neste dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Demasiadas tentativas de introdução da palavra-passe"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador anulou o dispositivo para utilização pessoal."</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerido"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede. Toque para obter mais detalhes."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"O seu dispositivo será apagado"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permite à aplicação enviar transmissões fixas que permanecem após o fim da transmissão. Uma utilização excessiva pode tornar o seu dispositivo Android TV lento ou instável, fazendo com que utilize demasiada memória."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permite que a aplicação envie difusões fixas, que permanecem após o fim da difusão. Uma utilização excessiva pode tornar o telemóvel lento ou instável, fazendo com que utilize demasiada memória."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"ler os contactos"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Permite que a aplicação leia dados acerca de contactos guardados no tablet, incluindo a frequência com que telefonou, enviou emails ou comunicou através de outras formas com determinadas pessoas. Esta autorização permite que a aplicação guarde dados de contactos e as aplicações maliciosas podem partilhar dados de contactos sem o seu conhecimento."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Permite à aplicação ler dados acerca dos contactos armazenados no seu dispositivo Android TV, incluindo a frequência com que efetuou chamadas, enviou emails ou comunicou de outras formas com indivíduos específicos. Esta autorização permite às aplicações guardarem dados de contactos e as aplicações maliciosas podem partilhá-los sem o seu conhecimento."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Permite que a aplicação leia dados acerca de contactos guardados no telemóvel, incluindo a frequência com que telefonou, enviou emails ou comunicou através de outras formas com determinadas pessoas. Esta autorização permite que a aplicação guarde dados de contactos e as aplicações maliciosas podem partilhar dados de contactos sem o seu conhecimento."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permite à aplicação ler dados acerca dos contactos armazenados no seu tablet. As aplicações também terão acesso às contas no tablet que criaram contactos. Pode incluir contas criadas pelas aplicações instaladas. Esta autorização permite às aplicações guardarem dados de contactos e as aplicações maliciosas podem partilhá-los sem o seu conhecimento."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permite à aplicação ler dados acerca dos contactos armazenados no seu dispositivo Android TV. As aplicações terão acesso às contas no dispositivo Android TV que criaram contactos. Pode incluir contas criadas pelas aplicações instaladas. Esta autorização permite às aplicações guardarem dados de contactos e as aplicações maliciosas podem partilhá-los sem o seu conhecimento."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permite à aplicação ler dados acerca dos contactos armazenados no seu telemóvel. As aplicações também terão acesso às contas no telemóvel que criaram contactos. Pode incluir contas criadas pelas aplicações instaladas. Esta autorização permite às aplicações guardarem dados de contactos e as aplicações maliciosas podem partilhá-los sem o seu conhecimento."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modificar os contactos"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Permite que a aplicação modifique dados acerca dos contactos guardados no tablet, incluindo a frequência com que telefonou, enviou emails ou comunicou através de outras formas com determinadas pessoas. Esta autorização permite que as aplicações eliminem dados de contactos."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Permite à aplicação modificar dados acerca dos contactos armazenados no seu dispositivo Android TV, incluindo a frequência com que efetuou chamadas, enviou emails ou comunicou de outras formas com pessoas específicas. Esta autorização permite às aplicações eliminarem dados de contactos."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Permite que a aplicação modifique dados acerca dos contactos guardados no telemóvel, incluindo a frequência com que telefonou, enviou emails ou comunicou através de outras formas com determinadas pessoas. Esta autorização permite que as aplicações eliminem dados de contactos."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permite que a aplicação modifique dados acerca dos contactos armazenados no tablet. Esta autorização permite que as aplicações eliminem dados de contactos."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permite à aplicação modificar dados acerca dos contactos armazenados no seu dispositivo Android TV. Esta autorização permite que as aplicações eliminem dados de contactos."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permite que a aplicação modifique dados acerca dos contactos guardados no telemóvel. Esta autorização permite que as aplicações eliminem dados de contactos."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"ler registo de chamadas"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Esta aplicação pode ler o seu histórico de chamadas."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"escrever registo de chamadas"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"aceder a comandos adicionais do fornecedor de localização"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que a aplicação aceda a comandos adicionais do fornecedor de localização. Esta opção pode permitir que a aplicação interfira com o funcionamento do GPS ou de outras fontes de localização."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"apenas aceder à localização exata em primeiro plano"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Esta aplicação apenas pode obter a sua localização exata quando estiver em primeiro plano. É necessário que estes Serviços de localização estejam ativados e disponíveis no seu telemóvel para que a aplicação os possa utilizar. Esta ação pode aumentar o consumo da bateria."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"aceder à localização aproximada (baseada na rede) apenas em primeiro plano"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Esta aplicação pode obter a sua localização com base em fontes de rede, tais como torres de redes móveis e redes Wi-Fi, mas apenas quando estiver em primeiro plano. É necessário que estes Serviços de localização estejam ativados e disponíveis no seu tablet para que a aplicação os possa utilizar."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Esta aplicação pode obter a sua localização com base em fontes de rede, tais como torres de redes móveis e redes Wi-Fi, mas apenas quando estiver em primeiro plano. É necessário que estes Serviços de localização estejam ativados e disponíveis no seu dispositivo Android TV para que a aplicação os possa utilizar."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Esta aplicação pode obter a sua localização com base em fontes de rede, tais como torres de redes móveis e redes Wi-Fi, mas apenas quando estiver em primeiro plano. É necessário que estes Serviços de localização estejam ativados e disponíveis no seu telemóvel para que a aplicação os possa utilizar."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Esta aplicação apenas pode obter a sua localização exata quando estiver em primeiro plano. É necessário que os Serviços de localização estejam ativados e disponíveis no seu dispositivo para que a aplicação os possa utilizar. Esta ação pode aumentar o consumo da bateria."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"apenas aceder à localização aproximada em primeiro plano"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Esta aplicação apenas pode obter a sua localização aproximada quando estiver em primeiro plano. É necessário que os Serviços de localização estejam ativados e disponíveis para que a aplicação os possa utilizar."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"aceder à localização em segundo plano"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Se tal for concedido em conjunto com o acesso à localização aproximada ou exata, a aplicação pode aceder à localização mesmo estando em segundo plano."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Esta aplicação pode aceder à localização mesmo estando em segundo plano, além do acesso à localização em primeiro plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"alterar as suas definições de áudio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permite que a aplicação modifique definições de áudio globais, tais como o volume e qual o altifalante utilizado para a saída de som."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"gravar áudio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permite que a aplicação visualize a configuração do Bluetooth no tablet e que estabeleça e aceite ligações com dispositivos emparelhados."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permite que a aplicação visualize a configuração do Bluetooth no seu dispositivo Android TV e que estabeleça e aceite ligações com dispositivos sincronizados."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permite que a aplicação visualize a configuração do Bluetooth no telemóvel e que estabeleça e aceite ligações com dispositivos emparelhados."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"controlo Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Permite que a aplicação comunique com etiquetas, cartões e leitores Near Field Communication (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"desativar o bloqueio do ecrã"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Ligado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Tocar para ver ficheiros"</string>
<string name="pin_target" msgid="8036028973110156895">"Fixar"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Soltar"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Info. da aplicação"</string>
<string name="negative_duration" msgid="1938335096972945232">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"A iniciar a demonstração…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Pretende atualizar estes itens em "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Guardar"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Não, obrigado"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Agora não"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nunca"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Atualizar"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continuar"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"palavra-passe"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Ativar/desativar o ecrã dividido"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ecrã de bloqueio"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de ecrã"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplicação <xliff:g id="APP_NAME">%1$s</xliff:g> numa janela de pop-up."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de legendas da aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 1750d2a..108d187 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"O app para administrador do perfil de trabalho não foi encontrado ou está corrompido. Consequentemente, seu perfil de trabalho e os dados relacionados foram excluídos. Entre em contato com seu administrador para receber assistência."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Seu perfil de trabalho não está mais disponível neste dispositivo"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Muitas tentativas de senha"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador renunciou ao dispositivo para uso pessoal"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerenciado"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Sua organização gerencia este dispositivo e pode monitorar o tráfego de rede. Toque para ver detalhes."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Seu dispositivo será limpo"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permite ao app enviar transmissões fixas, que permanecem após o fim da transmissão. O uso excessivo pode causar lentidão ou instabilidade no seu dispositivo Android TV, devido ao aumento do uso de memória."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permite que o app envie transmissões fixas, que permanecem depois que a transmissão termina. O uso excessivo pode deixar o telefone lento ou instável, fazendo com que ele use muita memória."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"ler seus contatos"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Permite que o app leia dados dos contatos armazenados no tablet, incluindo a frequência com que você chamou, enviou e-mails ou se comunicou de qualquer outra forma com indivíduos específicos. Esta permissão autoriza o app a salvar seus dados de contato, e apps maliciosos podem compartilhar esses dados de contato sem seu conhecimento."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Permite que o app leia os dados sobre os contatos armazenados no seu dispositivo Android TV, incluindo a frequência de chamadas, e-mails e outras comunicações com pessoas específicas. Essa autorização permite que os apps salvem os dados dos seus contatos,. Tenha cuidado porque apps maliciosos podem compartilhar esses dados sem seu conhecimento."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Permite que o app leia dados dos contatos armazenados no telefone, incluindo a frequência com que você chamou, enviou e-mails ou se comunicou de qualquer outra forma com indivíduos específicos. Esta permissão autoriza o app a salvar seus dados de contato, e apps maliciosos podem compartilhar esses dados de contato sem seu conhecimento."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permite que o app leia dados sobre seus contatos armazenados no tablet. Os apps também terão acesso às contas no tablet que criaram contatos. Isso pode incluir contas criadas pelos apps que você instalou. Essa permissão autoriza os apps a salvarem os dados dos seus contatos, e apps maliciosos podem compartilhar esses dados sem seu conhecimento."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permite que o app leia dados sobre seus contatos armazenados no dispositivo Android TV. Os apps também terão acesso às contas no dispositivo Android TV que criaram contatos. Isso pode incluir contas criadas pelos apps que você instalou. Essa permissão autoriza os apps a salvarem os dados dos seus contatos, e apps maliciosos podem compartilhar esses dados sem seu conhecimento."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permite que o app leia dados sobre seus contatos armazenados no smartphone. Os apps também terão acesso às contas no smartphone que criaram contatos. Isso pode incluir contas criadas pelos apps que você instalou. Essa permissão autoriza os apps a salvarem os dados dos seus contatos, e apps maliciosos podem compartilhar esses dados sem seu conhecimento."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modificar seus contatos"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Permite que o app modifique os dados sobre os contatos armazenados no tablet, incluindo a frequência com que você fez chamadas, enviou e-mails ou se comunicou de outras formas com contatos específicos. Esta permissão autoriza o app a excluir dados de contatos."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Permite que o app modifique os dados dos contatos armazenados no seu dispositivo Android TV, incluindo a frequência de chamadas, e-mails e outras comunicações com contatos específicos. Essa permissão autoriza os apps a excluir dados dos contatos."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Permite que o app modifique os dados dos contatos armazenados no telefone, incluindo a frequência com que você fez chamadas, enviou e-mails ou se comunicou de outras formas com contatos específicos. Esta permissão autoriza o app a excluir dados de contatos."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permite que o app modifique os dados sobre os contatos armazenados no tablet. Essa permissão autoriza os apps a excluírem dados de contato."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permite que o app modifique os dados sobre os contatos armazenados no dispositivo Android TV. Essa permissão autoriza os apps a excluírem dados de contato."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permite que o app modifique os dados sobre os contatos armazenados no smartphone. Essa permissão autoriza os apps a excluírem dados de contato."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"ler registro de chamadas"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Este app pode ler seu histórico de chamadas."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"salvar no registo de chamadas"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acessar comandos extras do provedor de localização"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar localização precisa apenas em primeiro plano"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Este app pode ver sua localização exata a qualquer momento apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu smartphone para que o app possa usá-los. Isso pode aumentar o consumo de bateria."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"acessar localização aproximada (baseada em rede) apenas em primeiro plano"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu tablet para que o app possa usá-los."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu dispositivo Android TV para que o app possa usá-los."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu smartphone para que o app possa usá-los."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Este app pode ver seu local exato apenas quando está em primeiro plano. Os \"Serviços de localização\" precisam estar ativados e disponíveis no seu dispositivo para que o app possa usá-los. Isso pode aumentar o consumo de bateria."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acessar local aproximado apenas em primeiro plano"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Este app poderá acessar seu local aproximado somente quando estiver em primeiro plano. Os \"Serviços de localização\" precisam estar ativados e disponíveis no dispositivo para que o app possa usá-los."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"acessar a localização em segundo plano"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Se essa permissão for concedida, além do acesso à localização precisa ou aproximada, o app poderá acessar a localização durante a execução em segundo plano."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Esse app pode acessar o local em segundo plano, além do acesso em primeiro plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"alterar as suas configurações de áudio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permite que o app modifique configurações de áudio globais como volume e alto-falantes de saída."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"gravar áudio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permite que o app acesse a configuração do Bluetooth no tablet, além de fazer e aceitar conexões com dispositivos pareados."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permite que o app acesse a configuração do Bluetooth no dispositivo Android TV, além de fazer e aceitar conexões com dispositivos pareados."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permite que o app acesse a configuração do Bluetooth no telefone, além de fazer e aceitar conexões com dispositivos pareados."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Permite que o app se comunique com leitores, cartões e etiqueta NFC (comunicação a curta distância)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"desativar o bloqueio de tela"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Toque para ver os arquivos"</string>
<string name="pin_target" msgid="8036028973110156895">"Fixar guia"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Liberar guia"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Informações do app"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Iniciando demonstração…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Atualizar estes itens em "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Salvar"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Não, obrigado"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Agora não"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nunca"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Atualizar"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continuar"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"senha"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Ativar tela dividida"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Bloquear tela"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Capturar tela"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"App <xliff:g id="APP_NAME">%1$s</xliff:g> na janela pop-up."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de legendas do app <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 397525a..2725f6b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -190,8 +190,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplicația de administrare a profilului de serviciu lipsește sau este deteriorată. Prin urmare, profilul de serviciu și datele asociate au fost șterse. Pentru asistență, contactați administratorul."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profilul de serviciu nu mai este disponibil pe acest dispozitiv"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Prea multe încercări de introducere a parolei"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratorul a retras dispozitivul pentru uz personal"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Dispozitivul este gestionat"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organizația dvs. gestionează acest dispozitiv și poate monitoriza traficul în rețea. Atingeți pentru mai multe detalii."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Datele de pe dispozitiv vor fi șterse"</string>
@@ -384,13 +383,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permite aplicației să trimită mesaje difuzate persistente, care se păstrează după terminarea difuzării mesajului. Utilizarea excesivă a acestei funcții poate să încetinească sau să destabilizeze dispozitivul Android TV, determinându-l să utilizeze prea multă memorie."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permite aplicației să trimită mesaje difuzate persistente, care se păstrează după terminarea difuzării mesajului. Utilizarea excesivă a acestei funcții poate să încetinească sau să destabilizeze telefonul, determinându-l să utilizeze prea multă memorie."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"citește agenda"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Permite aplicației să citească datele despre persoanele din agenda stocată pe tabletă, inclusiv frecvența cu care ați apelat, ați trimis e-mailuri sau ați comunicat în alte moduri cu anumite persoane. Cu această permisiune aplicația salvează datele dvs. de contact, iar aplicațiile rău intenționate pot distribui datele de contact fără știrea dvs."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Permite aplicației să citească datele despre persoanele de contact salvate pe dispozitivul Android TV, inclusiv frecvența cu care ați apelat, ați trimis e-mailuri sau ați comunicat în alte moduri cu anumite persoane. Cu această permisiune, aplicațiile pot salva datele de contact, iar aplicațiile rău-intenționate pot permite accesul la datele de contact fără cunoștința dvs."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Permite aplicației să citească datele despre persoanele din agenda stocată pe telefon, inclusiv frecvența cu care ați apelat, ați trimis e-mailuri sau ați comunicat în alte moduri cu anumite persoane. Cu această permisiune aplicația salvează datele dvs. de contact, iar aplicațiile rău intenționate pot distribui datele de contact fără știrea dvs."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permite aplicației să citească datele despre persoanele din agenda stocată pe tabletă. Aplicațiile vor avea și acces la conturile de pe tabletă care au creat agenda. Aici pot fi incluse conturile create de aplicațiile pe care le-ați instalat. Cu această permisiune, aplicațiile pot salva datele de contact, iar aplicațiile rău-intenționate pot permite accesul la datele de contact fără cunoștința dvs."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permite aplicației să citească datele despre persoanele de contact din agenda stocată pe dispozitivul Android TV. Aplicațiile vor avea și acces la conturile de pe dispozitivul Android TV care au creat agenda. Aici pot fi incluse conturile create de aplicațiile pe care le-ați instalat. Cu această permisiune, aplicațiile pot salva datele de contact, iar aplicațiile rău-intenționate pot permite accesul la datele de contact fără cunoștința dvs."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permite aplicației să citească datele despre persoanele de contact salvate pe telefon. Aplicațiile vor avea și acces la conturile de pe telefon care au creat agenda. Aici pot fi incluse conturile create de aplicațiile pe care le-ați instalat. Cu această permisiune, aplicațiile pot salva datele de contact, iar aplicațiile rău-intenționate pot permite accesul la datele de contact fără cunoștința dvs."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modifică agenda"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe tabletă, inclusiv frecvența cu care ați apelat, ați trimis e-mailuri sau ați comunicat în alte moduri cu anumite persoane din agendă. Cu această permisiune aplicația poate șterge datele de contact."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Permite aplicației să modifice datele despre persoanele de contact salvate pe dispozitivul Android TV, inclusiv frecvența cu care ați apelat, ați trimis e-mailuri sau ați comunicat în alte moduri cu anumite persoane de contact. Cu această permisiune, aplicația poate șterge datele de contact."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe telefon, inclusiv frecvența cu care ați apelat, ați trimis e-mailuri sau ați comunicat în alte moduri cu anumite persoane din agendă. Cu această permisiune aplicația poate șterge datele de contact."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe tabletă. Cu această permisiune, aplicația poate șterge datele de contact."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe dispozitivul Android TV. Cu această permisiune, aplicația poate șterge datele de contact."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permite aplicației să modifice datele despre persoanele din agenda stocată pe telefon. Cu această permisiune, aplicația poate șterge datele de contact."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"citește jurnalul de apeluri"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Această aplicație poate citi istoricul apelurilor."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"scrie jurnalul de apeluri"</string>
@@ -410,13 +409,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"accesare comenzi suplimentare ale furnizorului locației"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite aplicației să acceseze comenzi suplimentare pentru furnizorul locației. Aplicația ar putea să utilizeze această permisiune pentru a influența operațiile GPS sau ale altor surse de locații."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"să acceseze locația exactă în prim-plan"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Aplicația vă poate obține locația exactă numai când rulează în prim-plan. Serviciile de localizare trebuie să fie activate și disponibile pe telefon pentru ca aplicația să le poată folosi. Acest lucru poate accelera descărcarea bateriei."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"să acceseze locația aproximativă (bazată pe rețea) doar în prim-plan"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Aplicația vă poate determina locația folosind sursele din rețea, cum ar fi turnurile de telefonie mobilă și rețelele Wi-Fi, însă numai când rulează în prim-plan. Aceste servicii de localizare trebuie să fie activate și disponibile pe tabletă pentru ca aplicația să le poată folosi."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Aplicația vă poate determina locația folosind sursele din rețea, cum ar fi turnurile de telefonie mobilă și rețelele Wi-Fi, însă numai când rulează în prim-plan. Aceste servicii de localizare trebuie să fie activate și disponibile pe dispozitivul Android TV pentru ca aplicația să le poată folosi."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Aplicația vă poate determina locația folosind sursele din rețea, cum ar fi turnurile de telefonie mobilă și rețelele Wi-Fi, însă numai când rulează în prim-plan. Aceste servicii de localizare trebuie să fie activate și disponibile pe telefon pentru ca aplicația să le poată folosi."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Aplicația vă poate obține locația exactă numai când rulează în prim-plan. Serviciile de localizare trebuie să fie activate și disponibile pe dispozitiv pentru ca aplicația să le poată folosi. Acest lucru poate accelera descărcarea bateriei."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"să acceseze locația aproximativă numai în prim-plan."</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Aplicația vă poate determina locația aproximativă numai când rulează în prim-plan. Serviciile de localizare trebuie să fie activate și disponibile pe dispozitiv pentru ca aplicația să le poată folosi."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"accesați locația în fundal"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Dacă se acordă în plus față de accesul la locație aproximativă sau exactă, aplicația poate accesa locația în timp ce rulează în fundal."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Această aplicație poate accesa locația cât timp rulează în fundal, pe lângă accesul la locație din prim-plan."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"modificare setări audio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permite aplicației să modifice setările audio globale, cum ar fi volumul și difuzorul care este utilizat pentru ieșire."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"înregistreze sunet"</string>
@@ -497,6 +494,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permite aplicației să vadă configurația tabletei Bluetooth, să efectueze și să accepte conexiuni cu dispozitive împerecheate."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permite aplicației să vadă configurația conexiunii prin Bluetooth a dispozitivului Android TV, să efectueze și să accepte conexiuni cu dispozitive împerecheate."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permite aplicației să vadă configurația telefonului Bluetooth, să efectueze și să accepte conexiuni cu dispozitive împerecheate."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"controlare schimb de date prin Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Permite aplicației să comunice cu etichetele, cardurile și cititoarele NFC (Near Field Communication)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"dezactivează blocarea ecranului"</string>
@@ -1894,7 +1895,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Conectat la <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Atingeți pentru a vedea fișierele"</string>
<string name="pin_target" msgid="8036028973110156895">"Fixați"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Anulați fixarea"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Informații despre aplicație"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Se pornește demonstrația…"</string>
@@ -1938,6 +1943,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Actualizați aceste articole în "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> și <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Salvați"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nu, mulțumesc"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Nu acum"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Niciodată"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Actualizați"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Continuați"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"parolă"</string>
@@ -2034,5 +2041,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activați ecranul împărțit"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ecran de blocare"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captură de ecran"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> în fereastră pop-up."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Bară cu legenda pentru <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index a7abbff..3290591 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -192,8 +192,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Приложение для администрирования рабочего профиля отсутствует или повреждено. Из-за этого рабочий профиль и связанные с ним данные были удалены. Если у вас возникли вопросы, обратитесь к администратору."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Ваш рабочий профиль больше не доступен на этом устройстве"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Слишком много попыток ввести пароль."</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Администратор освободил устройство для личного использования"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Это управляемое устройство"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик. Подробнее…"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Все данные с устройства будут удалены"</string>
@@ -387,13 +386,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Приложение сможет делать бессрочные рассылки, которые не удаляются после отправки. Злоупотребление ими может замедлить работу устройства Android TV или сделать ее нестабильной из-за чрезмерной загрузки памяти."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Приложение сможет делать несрочные рассылки, которые не удаляются после их отправки. Злоупотребление этими рассылками может замедлить работу телефона или сделать ее нестабильной из-за чрезмерного использования памяти."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"Просмотр контактов"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Приложение сможет просматривать и сохранять все данные о контактах на устройстве, включая то, как часто вы звоните, отправляете письма и другими способами связываетесь с определенными людьми. Вредоносные программы смогут передавать данные о контактах без уведомления."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Приложение получит доступ к контактам, сохраненным на устройстве Android TV, а также к данным о частоте звонков, отправки сообщений электронной почты и других сеансов связи с определенными людьми. Приложения смогут сохранять данные о контактах. Вредоносные программы смогут публиковать их без вашего ведома."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Приложение сможет просматривать и сохранять все данные о контактах на устройстве, включая то, как часто вы звоните, отправляете письма и другими способами связываетесь с определенными людьми. Вредоносные программы смогут передавать данные о контактах без уведомления."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Приложение сможет считывать данные о контактах, сохраненных на вашем планшете. Кроме того, у приложения будет доступ к аккаунтам на планшете, в которых есть контакты. В их число могут входить аккаунты, созданные приложениями, которые вы установили. Получив возможность сохранять данные контактов, вредоносные программы смогут передавать их без вашего ведома."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Приложение сможет считывать данные о контактах, сохраненных на вашем устройстве Android TV. Кроме того, у приложения будет доступ к аккаунтам на устройстве Android TV, в которых есть контакты. В их число могут входить аккаунты, созданные приложениями, которые вы установили. Получив возможность сохранять данные контактов, вредоносные программы смогут передавать их без вашего ведома."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Приложение сможет считывать данные о контактах, сохраненных на вашем телефоне. Кроме того, у приложения будет доступ к аккаунтам на телефоне, в которых есть контакты. В их число могут входить аккаунты, созданные приложениями, которые вы установили. Получив возможность сохранять данные контактов, вредоносные программы смогут передавать их без вашего ведома."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"Изменение контактов"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Приложение сможет изменять сведения о контактах на вашем планшетном ПК, включая то, как часто вы звоните, отправляете письма и другими способами связываетесь с определенными людьми. С этим разрешением приложения смогут удалять данные о контактах."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Приложение сможет изменять сведения о контактах на вашем устройстве Android TV, включая то, как часто вы звоните, отправляете письма и другими способами связываетесь с определенными людьми. С этим разрешением приложения смогут удалять данные о контактах."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Приложение сможет изменять сведения о контактах на вашем телефоне, включая то, как часто вы звоните, отправляете письма и другими способами связываетесь с определенными людьми. С этим разрешением приложения смогут удалять данные о контактах."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Приложение сможет изменять сведения о контактах, сохраненных на вашем планшете. Это разрешение позволяет приложениям удалять данные о контактах."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Приложение сможет изменять сведения о контактах, сохраненных на вашем устройстве Android TV. Это разрешение позволяет приложениям удалять данные о контактах."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Приложение сможет изменять сведения о контактах, сохраненных на вашем телефоне. Это разрешение позволяет приложениям удалять данные о контактах."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"Просмотр журнала вызовов"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Приложение может считывать данные журнала звонков."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"Изменение журнала вызовов"</string>
@@ -413,13 +412,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"Доступ к дополнительным командам управления источниками геоданных"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Доступ к дополнительным командам управления источниками геоданных и вмешательство в работу системы GPS или других источников геоданных."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"Доступ к точному местоположению только в фоновом режиме"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Приложение может получать сведения о вашем точном местоположении только в фоновом режиме. Для этого необходимо включить соответствующие параметры на телефоне и разрешить использовать геоданные. Может увеличиться расход заряда батареи."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"Доступ к примерному местоположению (по координатам сети) только в фоновом режиме"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Приложение может получать сведения о вашем местоположении от источников сетей, таких как вышки сотовой связи и точки доступа Wi-Fi, но только в фоновом режиме. Для этого необходимо включить соответствующие параметры на планшете и разрешить использовать геоданные."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Приложение может получать сведения о вашем местоположении от сетевых источников, таких как вышки сотовой связи и точки доступа Wi-Fi, но только в активном режиме. Для этого необходимо включить на устройстве Android TV соответствующие сервисы геолокации и разрешить приложению использовать их."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Приложение может получать сведения о вашем местоположении от источников сетей, таких как вышки сотовой связи и точки доступа Wi-Fi, но только в фоновом режиме. Для этого необходимо включить соответствующие параметры на телефоне и разрешить использовать геоданные."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Приложение сможет получать сведения о вашем точном местоположении только в активном режиме. Для этого нужно включить геолокацию на устройстве и разрешить приложению использовать геоданные. Расход заряда батареи может увеличиться."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"Доступ к приблизительному местоположению только в активном режиме"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Приложение сможет получать сведения о вашем приблизительном местоположении только в активном режиме. Для этого нужно включить геолокацию на устройстве и разрешить приложению использовать геоданные."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"доступ к геоданным в фоновом режиме"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Если помимо доступа к данным о точном или приблизительном местоположении вы предоставите это разрешение, приложение сможет получать доступ к геоданным в фоновом режиме."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Приложение сможет получать сведения о вашем местоположении как в фоновом, так и в активном режиме."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"Изменение настроек аудио"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Приложение сможет изменять системные настройки звука, например уровень громкости и активный динамик."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"Запись аудио"</string>
@@ -500,6 +497,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Приложение сможет просматривать конфигурацию Bluetooth на планшетном ПК, а также запрашивать и подтверждать соединение с другими устройствами."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Приложение сможет просматривать конфигурацию Bluetooth на устройстве Android TV, а также запрашивать и подтверждать соединение с другими устройствами."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Приложение сможет просматривать конфигурацию Bluetooth на телефоне, а также запрашивать и подтверждать соединение с другими устройствами."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"Управление NFC-модулем"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Приложение сможет обмениваться данными с NFC-метками, картами и устройствами считывания, используя NFC."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"Отключение функции блокировки экрана"</string>
@@ -1926,7 +1927,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Подключено к <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Нажмите, чтобы просмотреть файлы"</string>
<string name="pin_target" msgid="8036028973110156895">"Закрепить"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Открепить"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"О приложении"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Запуск деморежима…"</string>
@@ -1971,6 +1976,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Обновить данные (<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g>) в сервисе "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Сохранить"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Нет, спасибо"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Не сейчас"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Никогда"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Обновить"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Продолжить"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"Пароль"</string>
@@ -2068,5 +2075,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Включить или выключить разделение экрана"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Заблокированный экран"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Скриншот"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" в всплывающем окне."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Строка субтитров в приложении \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
</resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 7d3f80d..eb633b5 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"කාර්යාල පැතිකඩ පාලක යෙදුම නොමැති හෝ දූෂණය වී ඇත. ප්රතිඵලයක් ලෙස ඔබගේ කාර්යාල පැතිකඩ සහ අදාළ දත්ත මකා දමා ඇත. සහය සඳහා ඔබගේ පරිපාලකයා සම්බන්ධ කර ගන්න."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ඔබේ කාර්යාල පැතිකඩ මෙම උපාංගය මත තවදුරටත් ලබා ගැනීමට නොහැකිය"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"මුරපද උත්සාහ කිරීම් ඉතා වැඩි ගණනකි"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"පරිපාලක පුද්ගලික භාවිතය සඳහා උපාංගය අත්හැර දමන ලදී"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"උපාංගය කළමනාකරණය කෙරේ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"ඔබගේ ආයතනය මෙම උපාංගය කළමනාකරණය කරන අතර එය ජාල තදබදය නිරීක්ෂණය කළ හැක. විස්තර සඳහා තට්ටු කරන්න."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"ඔබගේ උපාංගය මකා දැමෙනු ඇත"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"යෙදුමට විකාශයෙන් පසුවද ඉතිරි වන, ඇලවෙන විකාශ යැවීමට ඉඩ දෙයි. වැඩියෙන් භාවිතය වැඩිපුර මතකය භාවිත කිරීම මගින් ඔබේ Android TV උපාංගය මන්දගාමී හෝ අස්ථායී බවට පත් කළ හැකිය."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ප්රචාරණයට පසුවද පවතින, ප්රචාරණයන් යැවීමට යෙදුමට අවසර දෙන්න. වැඩිපුර මතකය භාවිතය හේතු කොට, අධික භාවිතය මඟින් දුරකථනය පමා කිරීම හෝ අස්ථිර කළ හැක."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"ඔබගේ සම්බන්ධතා කියවීම"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"සඳහන් පුද්ගලයන් හට ඔබ ඇමතුම් ගත්, ඊ-තැපැල්, හෝ අනෙකුත් ආකාර වලින් සන්නිවේදනය කරගත් සංඛ්යතද ඇතුළුව, ඔබගේ ටැබ්ලටයේ ගබඩාවී ඇති සම්බන්ධතා පිළිබඳ දත්ත කියවීමට යෙදුමට අවසර දෙන්න. මෙම අවසරය මඟින් යෙදුම්වලට ඔබගේ සම්බන්ධතා පිළිබඳ දත්ත සුරැකීමට ඉඩ ලබා දෙන අතර, අනිෂ්ට යෙදුම් විසින් ඔබ නොදැනුවත්වම සම්බන්ධතා දත්ත බෙදා ගැනීමට ඉඩ ඇත."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"ඔබ නිශ්චිත පුද්ගලයන් ඇමතූ, ඉ-තැපැල් කළ හෝ වෙනත් ආකාරයකින් සන්නිවේදනය කළ වාර ගණනද ඇතුළුව, ඔබගේ Android TV උපාංගයේ ගබඩා කර ඇති ඔබගේ සම්බන්ධතා පිළිබඳ දත්ත කියවීමට යෙදුමට ඉඩ දෙයි. මෙම අවසරය යෙදුම්වලට ඔබගේ සම්බන්ධතා දත්ත සුරැකීමට ඉඩ දෙන අතර, අනිෂ්ට යෙදුම් ඔබගේ දැනුමෙන් තොරව සම්බන්ධතා දත්ත බෙදා ගත හැකිය."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"නියමිත පුද්ගලයන් සමග ඔබ ඇමතු, ඊ-තැපැල් කළ හෝ වෙනත් ආකාරයකින් සන්නිවේදනය කළ සංඛ්යාතය ඇතුලත් ඔබගේ දුරකථනයේ ආචයනය කරන ලද ඔබගේ සම්බන්ධතා ගැන දත්ත කියවීමට යෙදුමට අවසර දෙන්න. ඔබගේ සම්බන්ධතා දත්ත උපස්ථ කිරීමට මෙම අවසරය යෙදුමට අවසර දෙන අතර ඔබගේ දැනුමකින් තොරව අනිෂ්ට යෙදුම් සම්බන්ධතා දත්ත බෙදාගැනීම කළ හැක."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"ඔබගේ ටැබ්ලට් පරිගණකයේ ගබඩා කර ඇති ඔබගේ සම්බන්ධතා පිළිබඳ දත්ත කියවීමට යෙදුමට ඉඩ දෙයි. යෙදුම්වලට සම්බන්ධතා තැනූ ඔබගේ ටැබ්ලට් පරිගණකයේ ගිණුම්වලට ප්රවේශය ද ලැබෙනු ඇත. මෙයට ඔබ ස්ථාපනය කර ඇති යෙදුම් මගින් තැනූ ගිණුම් ඇතුළත් විය හැකිය. මෙම අවසරය යෙදුම්වලට ඔබගේ සම්බන්ධතා දත්ත සුරැකීමට ඉඩ දෙන අතර, අනිෂ්ට යෙදුම් ඔබගේ දැනුමෙන් තොරව සම්බන්ධතා දත්ත බෙදා ගත හැකිය."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"ඔබගේ Android TV උපාංගයේ ගබඩා කර ඇති ඔබගේ සම්බන්ධතා පිළිබඳ දත්ත කියවීමට යෙදුමට ඉඩ දෙයි. යෙදුම්වලට සම්බන්ධතා තැනූ ඔබගේ Android TV උපාංගයේ ගිණුම්වලට ප්රවේශය ද ලැබෙනු ඇත. මෙයට ඔබ ස්ථාපනය කර ඇති යෙදුම් මගින් තැනූ ගිණුම් ඇතුළත් විය හැකිය. මෙම අවසරය යෙදුම්වලට ඔබගේ සම්බන්ධතා දත්ත සුරැකීමට ඉඩ දෙන අතර, අනිෂ්ට යෙදුම් ඔබගේ දැනුමෙන් තොරව සම්බන්ධතා දත්ත බෙදා ගත හැකිය."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ඔබගේ දුරකථනයේ ගබඩා කර ඇති ඔබගේ සම්බන්ධතා පිළිබඳ දත්ත කියවීමට යෙදුමට ඉඩ දෙයි. යෙදුම්වලට සම්බන්ධතා තැනූ ඔබගේ දුරකථනයේ ගිණුම්වලට ප්රවේශය ද ලැබෙනු ඇත. මෙයට ඔබ ස්ථාපනය කර ඇති යෙදුම් මගින් තැනූ ගිණුම් ඇතුළත් විය හැකිය. මෙම අවසරය යෙදුම්වලට ඔබගේ සම්බන්ධතා දත්ත සුරැකීමට ඉඩ දෙන අතර, අනිෂ්ට යෙදුම් ඔබගේ දැනුමෙන් තොරව සම්බන්ධතා දත්ත බෙදා ගත හැකිය."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"ඔබගේ සම්බන්ධතා වෙනස් කිරීම"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"නියමිත පුද්ගලයන්ට ඔබ ඇමතූ, ඊ-තැපැල් කළ හෝ ඇමතුම් කළ සංඛ්යාත ඇතුලත් ඔබගේ ටැබ්ලටයේ ආචයනය කරන ලද සම්බන්ධතා (ලිපින) දත්ත වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙම අවසරයෙන් යෙදුමට සම්බන්ධතා දත්ත මැකීමට අවසර දෙයි."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"ඔබ නිශ්චිත සම්බන්ධතා ඇමතූ, ඉ-තැපැල් කළ හෝ වෙනත් ආකාරයකින් සන්නිවේදනය කළ වාර ගණනද ඇතුළුව, ඔබගේ Android TV උපාංගයේ ගබඩා කර ඇති ඔබගේ සම්බන්ධතා පිළිබඳ දත්ත වෙනස් කිරීමට යෙදුමට ඉඩ දෙයි. මෙම අවසරය යෙදුම්වලට සම්බන්ධතා දත්ත මැකීමට ඉඩ දෙයි."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"සඳහන් පුද්ගලයන්ට ඔබ ඇමතූ, ඊ-තැපැල් කළ හෝ ඇමතුම් කළ සංඛ්යාන ඇතුලත් ඔබගේ දුරකථනයේ ආචයනය කරන ලද සම්බන්ධතා (ලිපින) දත්ත වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙම අවසරයෙන් යෙදුමට සම්බන්ධතා දත්ත මැකීමට අවසර දෙයි."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"ඔබගේ ටැබ්ලට් පරිගණකයේ ගබඩා කර ඇති ඔබගේ සම්බන්ධතා පිළිබඳ දත්ත වෙනස් කිරීමට යෙදුමට ඉඩ දෙයි. මෙම අවසරය යෙදුම්වලට සම්බන්ධතා දත්ත මැකීමට ඉඩ දෙයි."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"ඔබගේ Android TV උපාංගයේ ගබඩා කර ඇති ඔබගේ සම්බන්ධතා පිළිබඳ දත්ත වෙනස් කිරීමට යෙදුමට ඉඩ දෙයි. මෙම අවසරය යෙදුම්වලට සම්බන්ධතා දත්ත මැකීමට ඉඩ දෙයි."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"ඔබගේ දුරකථනයේ ගබඩා කර ඇති ඔබගේ සම්බන්ධතා පිළිබඳ දත්ත වෙනස් කිරීමට යෙදුමට ඉඩ දෙයි. මෙම අවසරය යෙදුම්වලට සම්බන්ධතා දත්ත මැකීමට ඉඩ දෙයි."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"ඇමතුම් ලොගය කියවන්න"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"මෙම යෙදුමට ඔබේ ඇමතුම් ඉතිහාසය කියවීමට හැකිය."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"ඇමතුම් ලොගය ලිවීම"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"අමතර ස්ථාන සැපයුම්කරු විධාන වෙත ප්රවේශ වීම"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"ස්ථානය සපයන අමතර අණ වලට ප්රවේශය කිරීමට යෙදුමට අවසර දෙන්න. GPS ක්රියාවන් හෝ වෙනත් ස්ථාන මූලාශ්ර සමඟ මැදිහත් වීමට මෙයින් යෙදුමට ඉඩ ලැබේ."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"පෙරබිම තුළ පමණක් නිශ්චිත ස්ථානය වෙත පිවිසෙන්න"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"මෙම යෙදුම පෙරබිම තුළ ඇති විට පමණක් එයට ඔබේ නිශ්චිත ස්ථානය ලබා ගත හැකිය. යෙදුමට ඒවා භාවිත කිරීමට හැකි වීමට මෙම ස්ථාන සේවා ක්රියාත්මක කර සහ ඔබේ දුරකථනය මත ලබා ගත හැකිව තිබිය යුතුය. මෙය බැටරි පරිභෝජනය වැඩි කළ හැකිය."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"ඉදිරියේ ඇති ආසන්න ස්ථානය (ජාලය පදනම්වූ) පමණක් ප්ර වේශ වන්න"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"මෙම යෙදුමට ජංගම දුරකථන කුළුණු සහ Wi-Fi ජාල වැනි ජාල මූලාශ්ර පදනම්ව ඔබගේ ස්ථානය ලබා ගත හැකි නමුත් යෙදුම ඉදිරියේ ඇති විට පමණී. යෙදුමට ඒවා භාවිත කිරීමට හැකි වීමට මෙම ස්ථාන සේවා ක්රියාත්මක කර ඔබේ ටැබ්ලටය මත ලබා ගත හැකිව තිබිය යුතුය."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"මෙම යෙදුමට ජංගම දුරකථන කුළුණු සහ Wi-Fi ජාල වැනි ජාල මූලාශ්ර පදනම්ව ඔබගේ ස්ථානය ලබා ගත හැකි නමුත් යෙදුම ඉදිරියේ ඇති විට පමණී. යෙදුමට ඒවා භාවිත කිරීමට හැකි වීමට මෙම ස්ථාන සේවා ක්රියාත්මක කර ඔබේ ඔබගේ Android TV උපාංගය මත ලබා ගත හැකිව තිබිය යුතුය."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"මෙම යෙදුමට ජංගම දුරකථන කුළුණු සහ Wi-Fi ජාල වැනි ජාල මූලාශ්ර පදනම්ව ඔබගේ ස්ථානය ලබා ගත හැකි නමුත් යෙදුම ඉදිරියේ ඇති විට පමණී. යෙදුමට ඒවා භාවිත කිරීමට හැකි වීමට මෙම ස්ථාන සේවා ක්රියාත්මක කර ඔබේ දුරකථනය මත ලබා ගත හැකිව තිබිය යුතුය."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"මෙම යෙදුම පෙරබිම තුළ ඇති විට පමණක් එයට ඔබගේ නිශ්චිත ස්ථානය ලබා ගත හැකිය. යෙදුමට ඒවා භාවිත කිරීමට හැකියාව ලැබීමට ස්ථාන සේවා ක්රියාත්මක කර ඔබගේ දුරකථනයේ ලබා ගත හැකි විය යුතුය. මෙය බැටරි පරිභෝජනය වැඩි කළ හැකිය."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"පෙරබිම තුළ පමණක් ආසන්න ස්ථානයට ප්රවේශය"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"මෙම යෙදුම පෙරබිම තුළ ඇති විට පමණක් එයට ඔබගේ ආසන්න ස්ථානය ලබා ගත හැකිය. යෙදුමට ඒවා භාවිත කිරීමට හැකියාව ලැබීමට ස්ථාන සේවා ක්රියාත්මක කර ඔබගේ උපාංගයේ ලබා ගත හැකි විය යුතුය."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"පසුබිමේ ස්ථානය ප්රවේශ කිරීම"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"මෙය ආසන්න වශයෙන් හෝ නිශ්චිත ස්ථානයක ප්රවේශය ලබා දෙන්නේ නම් පසුබිම් ධාවන අතරතුරදී යෙදුමට ස්ථානය වෙත ප්රවේශය විය හැක."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"පෙරබිම ස්ථාන ප්රවේශයට අමතරව පසුබිමේ ධාවනය වන අතරතුර මෙම යෙදුමට ස්ථානය වෙත ප්රවේශ විය හැකිය."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"ඔබගේ ශ්රව්ය සැකසීම් වෙනස් කරන්න"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"ශබ්දය ආදී ගෝලීය ශබ්ද සැකසීම් වෙනස් කිරීමට සහ ප්රතිදානය සඳහා භාවිත කරන්නේ කුමන නාදකය දැයි තේරීමට යෙදුමට අවසර දෙන්න."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ශබ්ද පටිගත කරන්න"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ටැබ්ලටයේ බ්ලූටූත් වින්යාසය බැලිමට, සැකසීමට සහ යුගල කළ උපාංග සමඟ සම්බන්ධතාවන් පිළිගැනීමට යෙදුමට අවසර දෙන්න."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"ඔබගේ Android TV උපාංගයේ බ්ලූටූත් හි වින්යාසකරණය බැලීමට, සහ යුගල කළ උපාංග සමඟ සම්බන්ධතා ඇති කර ගැනීමට සහ පිළිගැනීමට යෙදුමට ඉඩ දෙයි."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"දුරකථනයේ බ්ලූටූත් වින්යාසය දැකීමට, යුගල උපාංග සමඟ සම්බන්ධතාවන් සැකසීමට සහ භාරගැනීමට යෙදුමට අවසර දෙයි."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ආසන්න ක්ෂේත්ර සන්නිවේදනය පාලනය කරන්න"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"ආසන්න ක්ෂේත්ර සන්නිවේදන (NFC) ටැග්, පත්, සහ කියවන්නන් සමඟ සන්නිවේදනය කිරීමට යෙදුමට අවසර දෙන්න."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"ඔබගේ තිරයේ අගුල අබල කරන්න"</string>
@@ -1864,7 +1865,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> වෙත සම්බන්ධ විය"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ගොනු බැලීමට තට්ටු කරන්න"</string>
<string name="pin_target" msgid="8036028973110156895">"අමුණන්න"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"ගලවන්න"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"යෙදුම් තොරතුරු"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ආදර්ශනය ආරම්භ කරමින්..."</string>
@@ -1907,6 +1912,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" තුළ යාවත්කාලීන කරන්නද?: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, සහ <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"සුරකින්න"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"එපා ස්තූතියි"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"දැන් නොවේ"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"කිසිදා නැත"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"යාවත්කාලීන කරන්න"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"ඉදිරියට යන්න"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"මුරපදය"</string>
@@ -2002,5 +2009,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"බෙදුම් තිරය ටොගල කරන්න"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"අගුලු තිරය"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"තිර රුව"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"උත්පතන කවුළුව තුළ <xliff:g id="APP_NAME">%1$s</xliff:g> යෙදුම."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> හි සිරස්තල තීරුව."</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 3a81468c..769c1b0 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -192,8 +192,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikácia na správu pracovného profilu buď chýba, alebo je poškodená. Z toho dôvodu bol odstránený pracovný profil aj k nemu priradené dáta. Ak potrebujete pomoc, kontaktujte svojho správcu."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Váš pracovný profil už v tomto zariadení nie je k dispozícii"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Príliš veľa pokusov o zadanie hesla"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Správca uvoľnil toto zariadenie na osobné používanie"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Zariadenie je spravované"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizácia spravuje toto zariadenie a môže sledovať sieťovú premávku. Klepnutím zobrazíte podrobnosti."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Vaše zariadenie bude vymazané"</string>
@@ -387,13 +386,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Umožňuje aplikácii odosielať trvalé vysielania, ktoré pretrvávajú aj po skončení vysielania. Nadmerné používanie môže zariadenie Android TV spomaliť alebo spôsobiť jeho nestabilitu, pretože bude používať príliš veľa pamäte."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Umožňuje aplikácii odosielať trvalé vysielania, ktoré pretrvávajú aj po skončení vysielania. Nadmerné používanie môže telefón spomaliť alebo spôsobiť jeho nestabilitu, pretože bude používať príliš veľa pamäte."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"čítať kontakty"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Umožňuje aplikácii čítať údaje o kontaktoch uložených v tablete vrátane informácií o frekvencii vašich telefonátov, odoslaných e-mailov alebo iných foriem komunikácie s konkrétnymi osobami. Toto povolenie umožňuje aplikáciám ukladať údaje o kontaktoch. Škodlivé aplikácie môžu zdieľať údaje o kontaktoch bez vášho vedomia."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Umožňuje aplikácii čítať údaje o kontaktoch, ktoré máte uložené v zariadení Android TV, vrátane informácií o frekvencii vašich volaní, odoslaných e‑mailov alebo iných foriem komunikácie s konkrétnymi osobami. Toto povolenie umožňuje aplikáciám ukladať údaje kontaktov. Škodlivé aplikácie môžu zdieľať údaje kontaktov bez vášho vedomia."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Umožňuje aplikácii čítať údaje o kontaktoch uložených v telefóne vrátane informácií o frekvencii vašich telefonátov, odoslaných e-mailov alebo iných foriem komunikácie s konkrétnymi osobami. Toto povolenie umožňuje aplikáciám ukladať údaje o kontaktoch. Škodlivé aplikácie môžu zdieľať údaje o kontaktoch bez vášho vedomia."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Umožňuje aplikácii čítať údaje o kontaktoch uložených v tablete. Aplikácie budú mať tiež prístup k účtom v tablete, ktoré vytvorili kontakty. Môže ísť o účty vytvorené aplikáciami, ktoré ste nainštalovali. Toto povolenie umožňuje aplikáciám ukladať údaje o kontaktoch. Škodlivé aplikácie môžu zdieľať údaje o kontaktoch bez vášho vedomia."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Umožňuje aplikácii čítať údaje o kontaktoch uložených v zariadení Android TV. Aplikácie budú mať tiež prístup k účtom v zariadení Android TV, ktoré vytvorili kontakty. Môže ísť o účty vytvorené aplikáciami, ktoré ste nainštalovali. Toto povolenie umožňuje aplikáciám ukladať údaje o kontaktoch. Škodlivé aplikácie môžu zdieľať údaje o kontaktoch bez vášho vedomia."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Umožňuje aplikácii čítať údaje o kontaktoch uložených v telefóne. Aplikácie budú mať tiež prístup k účtom v telefóne, ktoré vytvorili kontakty. Môže ísť o účty vytvorené aplikáciami, ktoré ste nainštalovali. Toto povolenie umožňuje aplikáciám ukladať údaje o kontaktoch. Škodlivé aplikácie môžu zdieľať údaje o kontaktoch bez vášho vedomia."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"upraviť kontakty"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Umožňuje aplikácii upraviť údaje o kontaktoch uložených v tablete vrátane informácií o frekvencii vašich telefonátov, odoslaných e-mailov alebo iných foriem komunikácie s konkrétnymi osobami. Toto povolenie umožňuje aplikáciám odstraňovať údaje o kontaktoch."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Umožňuje aplikácii upravovať údaje o kontaktoch, ktoré máte uložené v zariadení Android TV, vrátane informácií o frekvencii vašich volaní, odoslaných e‑mailov alebo iných foriem komunikácie s konkrétnymi kontaktmi. Toto povolenie umožňuje aplikáciám odstraňovať údaje kontaktov."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Umožňuje aplikácii upraviť údaje o kontaktoch uložených v telefóne vrátane informácií o frekvencii vašich telefonátov, odoslaných e-mailov alebo iných foriem komunikácie s konkrétnymi osobami. Toto povolenie umožňuje aplikáciám odstraňovať údaje o kontaktoch."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Umožňuje aplikácii upraviť údaje o kontaktoch uložených v tablete. Toto povolenie umožňuje aplikáciám odstraňovať údaje o kontaktoch."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Umožňuje aplikácii upraviť údaje o kontaktoch uložených v zariadení Android TV. Toto povolenie umožňuje aplikáciám odstraňovať údaje o kontaktoch."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Umožňuje aplikácii upraviť údaje o kontaktoch uložených v telefóne. Toto povolenie umožňuje aplikáciám odstraňovať údaje o kontaktoch."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"čítať denník hovorov"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Táto aplikácia môže čítať históriu vašich hovorov."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"zapisovať do denníka hovorov"</string>
@@ -413,13 +412,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"prístup k ďalším príkazom poskytovateľa polohy"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Umožňuje aplikácii pristupovať k ďalším príkazom poskytovateľa informácií o polohe. Aplikácii to môže umožniť zasahovať do činnosti systému GPS alebo iných zdrojov informácií o polohe."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"prístup k presnej polohe iba v popredí"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Táto aplikácia dokáže získať vašu presnú polohu iba vtedy, keď je spustená v popredí. Na to, aby mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii v telefóne. Môže to zvýšiť spotebu batérie."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"prístup k približnej polohe (pomocou siete) iba v popredí"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi, keď je spustená v popredí. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii v tablete."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú vysielače mobilnej siete a siete Wi‑Fi, keď je spustená v popredí. Tieto služby musia byť zapnuté a k dispozícii v zariadení Android TV, aby aplikácia mohla používať služby určovania polohy."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi, ale iba keď je spustená v popredí. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii v telefóne."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Táto aplikácia dokáže získať vašu presnú polohu iba vtedy, keď je spustená v popredí. Služby určovania polohy musia byť zapnuté a k dispozícii v zariadení, aby ich mohla aplikácia používať. Môže to zvýšiť spotrebu batérie."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"prístup k približnej polohe iba v popredí"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Táto aplikácia dokáže získať vašu približnú polohu iba vtedy, keď je spustená v popredí. Služby určovania polohy musia byť zapnuté a k dispozícii v zariadení, aby ich mohla aplikácia používať."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"prístup k polohe na pozadí"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Ak okrem prístupu k približnej alebo presnej polohe udelíte aj toto povolenie, aplikácia bude môcť používať polohu, keď bude spustená na pozadí."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Táto aplikácia môže používať polohu nielen vtedy, keď je spustená v popredí, ale aj na pozadí."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"meniť nastavenia zvuku"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Umožňuje aplikácii upraviť globálne nastavenia zvuku, ako je hlasitosť, alebo určiť, z ktorého reproduktora bude zvuk vychádzať."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"nahrávať zvuk"</string>
@@ -500,6 +497,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Umožňuje aplikácii zobraziť informácie o konfigurácii Bluetooth na tablete. Taktiež jej umožňuje nadväzovať a akceptovať spojenia so spárovanými zariadeniami."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Umožňuje aplikácii zobraziť konfiguráciu rozhrania Bluetooth v zariadení Android TV, ako aj nadväzovať a prijímať pripojenia so spárovanými zariadeniami."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Umožňuje aplikácii zobraziť informácie o konfigurácii Bluetooth na telefóne. Taktiež jej umožňuje nadväzovať a akceptovať spojenia so spárovanými zariadeniami."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ovládať technológiu NFC"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Umožňuje aplikácii komunikovať so značkami, kartami a čítačkami s podporou technológie NFC."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"deaktivácia zámky obrazovky"</string>
@@ -1926,7 +1927,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Pripojené k zariadeniu <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Klepnutím zobrazíte súbory"</string>
<string name="pin_target" msgid="8036028973110156895">"Pripnúť"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Uvoľniť"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Info o aplikácii"</string>
<string name="negative_duration" msgid="1938335096972945232">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Spúšťa sa ukážka…"</string>
@@ -1971,6 +1976,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Chcete tieto položky aktualizovať v službe "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> a <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Uložiť"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nie, vďaka"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Teraz nie"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nikdy"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Aktualizovať"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Pokračovať"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"heslo"</string>
@@ -2068,5 +2075,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Prepnúť rozdelenú obrazovku"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Uzamknúť obrazovku"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snímka obrazovky"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vo vyskakovacom okne."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Popis aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index c28384c..be173dd 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -192,8 +192,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Skrbniška aplikacija delovnega profila manjka ali pa je poškodovana, zaradi česar je bil delovni profil s povezanimi podatki izbrisan. Za pomoč se obrnite na skrbnika."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Vaš delovni profil ni več na voljo v tej napravi"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Preveč poskusov vnosa gesla"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Skrbnik je napravo prepustil osebni uporabi"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Naprava je upravljana"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja to napravo in lahko nadzira omrežni promet. Dotaknite se za podrobnosti."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Podatki v napravi bodo izbrisani"</string>
@@ -387,13 +386,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Aplikaciji dovoljuje pošiljanje fiksnih oddaj, ki ostanejo po koncu oddajanja. Zaradi prekomerne uporabe je delovanje naprave Android TV lahko počasno ali nestabilno, ker porabi preveč pomnilnika."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Aplikaciji omogoča hitro pošiljanje fiksnih oddaj, ki ostanejo po koncu oddajanja. Zaradi prekomerne uporabe je delovanje telefona lahko počasno ali nestabilno, ker porabi preveč pomnilnika."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"branje stikov"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Aplikaciji omogoča branje podatkov o stikih v tabličnem računalniku, vključno s pogostostjo klicev, pošiljanja e-poštnih sporočil in druge komunikacije s posamezniki. S tem dovoljenjem lahko aplikacije shranjujejo podatke o stikih in zlonamerne aplikacije lahko te podatke razkrijejo brez vaše vednosti."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Aplikaciji dovoljuje branje podatkov o stikih, shranjenih v napravi Android TV, vključno s pogostostjo klicev, pošiljanja e-poštnih sporočil in druge komunikacije s posamezniki. S tem dovoljenjem lahko aplikacije shranjujejo podatke o stikih in zlonamerne aplikacije lahko te podatke razkrijejo brez vaše vednosti."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Aplikaciji omogoča branje podatkov o stikih v telefonu, vključno s pogostostjo klicev, pošiljanja e-poštnih sporočil in druge komunikacije s posamezniki. S tem dovoljenjem lahko aplikacije shranjujejo podatke o stikih in zlonamerne aplikacije lahko te podatke razkrijejo brez vaše vednosti."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Aplikaciji dovoljuje branje podatkov o stikih, shranjenih v tabličnem računalniku. Aplikacije bodo imele dostop tudi do računov v tabličnem računalniku, ki so ustvarili stike. To lahko vključuje račune, ki so jih ustvarile nameščene aplikacije. S tem dovoljenjem lahko aplikacije shranjujejo podatke o stikih in zlonamerne aplikacije lahko te podatke razkrijejo brez vaše vednosti."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Aplikaciji dovoljuje branje podatkov o stikih, shranjenih v napravi Android TV. Aplikacije bodo imele dostop tudi do računov v napravi Android TV, ki so ustvarili stike. To lahko vključuje račune, ki so jih ustvarile nameščene aplikacije. S tem dovoljenjem lahko aplikacije shranjujejo podatke o stikih in zlonamerne aplikacije lahko te podatke razkrijejo brez vaše vednosti."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Aplikaciji dovoljuje branje podatkov o stikih, shranjenih v telefonu. Aplikacije bodo imele dostop tudi do računov v telefonu, ki so ustvarili stike. To lahko vključuje račune, ki so jih ustvarile nameščene aplikacije. S tem dovoljenjem lahko aplikacije shranjujejo podatke o stikih in zlonamerne aplikacije lahko te podatke razkrijejo brez vaše vednosti."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"spreminjanje stikov"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Aplikaciji omogoča spreminjanje podatkov o stikih v tabličnem računalniku, vključno s pogostostjo klicev, pošiljanja e-poštnih sporočil in druge komunikacije z določenimi stiki. S tem dovoljenjem lahko aplikacije brišejo podatke o stikih."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Aplikaciji dovoljuje spreminjanje podatkov o stikih, shranjenih v napravi Android TV, vključno s pogostostjo klicev, pošiljanja e-poštnih sporočil in druge komunikacije z določenimi stiki. S tem dovoljenjem lahko aplikacije brišejo podatke o stikih."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Aplikaciji omogoča spreminjanje podatkov o stikih v telefonu, vključno s pogostostjo klicev, pošiljanja e-poštnih sporočil in druge komunikacije z določenimi stiki. S tem dovoljenjem lahko aplikacije brišejo podatke o stikih."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Aplikaciji dovoljuje spreminjanje podatkov o stikih, shranjenih v tabličnem računalniku. S tem dovoljenjem lahko aplikacije brišejo podatke o stikih."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Aplikaciji dovoljuje spreminjanje podatkov o stikih, shranjenih v napravi Android TV. S tem dovoljenjem lahko aplikacije brišejo podatke o stikih."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Aplikaciji dovoljuje spreminjanje podatkov o stikih, shranjenih v telefonu. S tem dovoljenjem lahko aplikacije brišejo podatke o stikih."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"branje dnevnika klicev"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Ta aplikacija lahko prebere zgodovino klicev."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"pisanje v dnevnik klicev"</string>
@@ -413,13 +412,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"dostopanje do ukazov ponudnika dodatnih lokacij"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Aplikaciji omogoča dostop do dodatnih ukazov ponudnika lokacij. S tem lahko aplikacija moti delovanje sistema GPS ali drugih virov lokacije."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"dostop do točne lokacije samo, ko deluje v ospredju"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Ta aplikacija lahko pridobi vašo točno lokacijo samo, ko deluje v ospredju. Če želite aplikaciji omogočiti uporabo teh lokacijskih storitev, morajo biti te vklopljene in na voljo v telefonu. Poraba energije akumulatorja bo morda večja."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"dostop do približne lokacije (na podlagi omrežja) samo med delovanjem v ospredju"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Ta aplikacija lahko pridobi vašo lokacijo na podlagi omrežnih virov, kot so bazne postaje in omrežja Wi-Fi, vendar samo, ko deluje v ospredju. Če želite aplikaciji omogočiti uporabo teh lokacijskih storitev, morajo biti te vklopljene in na voljo v tabličnem računalniku."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Ta aplikacija lahko pridobi vašo lokacijo na podlagi omrežnih virov, kot so bazne postaje in omrežja Wi-Fi, vendar samo, ko deluje v ospredju. Če želite aplikaciji omogočiti uporabo teh lokacijskih storitev, morajo biti te vklopljene in na voljo v napravi Android TV."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Ta aplikacija lahko pridobi vašo lokacijo na podlagi omrežnih virov, kot so bazne postaje in omrežja Wi-Fi, vendar samo, ko deluje v ospredju. Če želite aplikaciji omogočiti uporabo teh lokacijskih storitev, morajo biti te vklopljene in na voljo v telefonu."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Ta aplikacija lahko pridobi vašo točno lokacijo samo, ko deluje v ospredju. Če želite aplikaciji omogočiti uporabo lokacijskih storitev, morajo biti te vklopljene in na voljo v napravi. Poraba energije baterije bo morda večja."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"dostop do približne lokacije samo, ko deluje v ospredju"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Ta aplikacija lahko pridobi vašo približno lokacijo samo, ko deluje v ospredju. Če želite aplikaciji omogočiti uporabo lokacijskih storitev, morajo biti te vklopljene in na voljo v napravi."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"dostop do lokacije med izvajanjem v ozadju"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Če to dovolite poleg dostopa do približne ali natančne lokacije, lahko aplikacija dostopa do lokacije, medtem ko se izvaja v ozadju."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Ta aplikacija lahko dostopa do lokacije, ko deluje v ospredju ali ozadju."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"spreminjanje nastavitev zvoka"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Aplikaciji omogoča spreminjanje splošnih zvočnih nastavitev, na primer glasnost in kateri zvočnik se uporablja."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"snemanje zvoka"</string>
@@ -500,6 +497,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Aplikaciji omogoča ogled konfiguracije Bluetootha tabličnega računalnika ter vzpostavljanje in sprejemanje povezave s seznanjenimi napravami."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Aplikaciji dovoljuje ogled konfiguracije vmesnika Bluetooth v napravi Android TV ter ustvarjanje in sprejemanje povezav s seznanjenimi napravami."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Aplikaciji omogoča ogled konfiguracije Bluetootha telefona ter ustvarjanje in sprejemanje povezave s seznanjenimi napravami."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"nadzor nad komunikacijo s tehnologijo bližnjega polja"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Podpira komunikacijo med računalnikom in oznakami, karticami in bralniki komunikacije s tehnologijo bližnjega polja."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"onemogočanje zaklepanja zaslona"</string>
@@ -1926,7 +1927,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Vzpostavljena povezava z napravo <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Dotaknite se, če si želite ogledati datoteke"</string>
<string name="pin_target" msgid="8036028973110156895">"Pripenjanje"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Odpenjanje"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Podatki o aplikacijah"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Začenjanje predstavitve …"</string>
@@ -1971,6 +1976,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Želite posodobiti te elemente v aplikaciji "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> in <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Shrani"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Ne, hvala"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne zdaj"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Nikoli"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Posodobi"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Naprej"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"geslo"</string>
@@ -2068,5 +2075,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Preklop razdeljenega zaslona"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaklenjen zaslon"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Posnetek zaslona"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v pojavnem oknu."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Vrstica s podnapisi aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 39f7377..4c02bc7 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikacioni i administratorit të profilit të punës mungon ose është dëmtuar. Si rezultat i kësaj, profili yt i punës dhe të dhënat përkatëse janë fshirë. Kontakto me administratorin për ndihmë."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profili yt i punës nuk është më i disponueshëm në këtë pajisje"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Shumë përpjekje për fjalëkalimin"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratori e refuzoi pajisjen për përdorim personal"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Pajisja është e menaxhuar"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organizata jote e menaxhon këtë pajisje dhe mund të monitorojë trafikun e rrjetit. Trokit për detaje."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Pajisja do të spastrohet"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Lejon aplikacionin të dërgojë transmetime ngjitëse të cilat mbeten pas përfundimit të transmetimit. Përdorimi i tepërt mund ta bëjë pajisjen tënde Android TV të ngadaltë ose të paqëndrueshme, duke e detyruar atë të përdorë më shumë memorie."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Lejon aplikacionin të dërgojë transmetime ngjitëse që qëndrojnë derisa të përfundojë transmetimi. Përdorimi i tepruar mund ta bëjë telefonin të ngadaltë ose të paqëndrueshëm duke e detyruar atë të përdorë shumë kujtesë."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"lexo kontaktet e tua"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Lejon aplikacionin të lexojë të dhëna rreth kontakteve të ruajtura në tabletin tënd, përfshirë shpeshtësinë me të cilën ke telefonuar, ke dërguar mail-a ose komunikuar në mënyra të tjera me individë të caktuar. Kjo leje u mundëson aplikacioneve të ruajnë të dhënat e tua të kontakteve, ndaj aplikacionet keqdashëse mund të ndajnë të dhëna të kontakteve pa dijeninë tënde."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Lejon aplikacionin të lexojë të dhënat rreth kontakteve të tua të ruajtura në pajisjen tënde Android TV, përfshi shpeshtësinë me të cilën ke telefonuar, ke dërguar email-e apo komunikuar në rrugë të tjera me kontakte të veçanta. Ky autorizim i lejon aplikacionet të ruajnë të dhënat e tua të kontakteve, dhe aplikacionet keqdashëse mund të ndajnë të dhëna të kontakteve pa dijeninë tënde."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Lejon aplikacionin të lexojë të dhëna rreth kontakteve të ruajtura në telefonin tënd, përfshirë shpeshtësinë me të cilën ke telefonuar, ke dërguar mail-a ose komunikuar në mënyra të tjera me individë të caktuar. Kjo leje u mundëson aplikacioneve të ruajnë të dhënat e tua të kontakteve, ndaj aplikacionet keqdashëse mund të ndajnë të dhëna të kontakteve pa dijeninë tënde."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Lejon aplikacionin të lexojë të dhëna për kontaktet e ruajtura në tabletin tënd. Aplikacionet do të kenë po ashtu qasje te llogaritë në tabletin tënd, të cilat i kanë krijuar kontaktet. Kjo mund të përfshijë llogaritë e krijuara nga aplikacionet që ke instaluar. Kjo leje lejon që aplikacionet të ruajnë të dhënat e tua të kontakteve dhe aplikacionet keqdashëse mund të ndajnë të dhëna të kontakteve pa dijeninë tënde."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Lejon aplikacionin të lexojë të dhëna për kontaktet e ruajtura në pajisjen tënde Android TV. Aplikacionet do të kenë po ashtu qasje te llogaritë në pajisjen tënde të Android TV, të cilat i kanë krijuar kontaktet. Kjo mund të përfshijë llogaritë e krijuara nga aplikacionet që ke instaluar. Kjo leje lejon që aplikacionet të ruajnë të dhënat e tua të kontakteve dhe aplikacionet keqdashëse mund të ndajnë të dhëna të kontakteve pa dijeninë tënde."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Lejon aplikacionin të lexojë të dhëna për kontaktet e ruajtura në telefonin tënd. Aplikacionet do të kenë po ashtu qasje te llogaritë në telefonin tënd, të cilat i kanë krijuar kontaktet. Kjo mund të përfshijë llogaritë e krijuara nga aplikacionet që ke instaluar. Kjo leje lejon që aplikacionet të ruajnë të dhënat e tua të kontakteve dhe aplikacionet keqdashëse mund të ndajnë të dhëna të kontakteve pa dijeninë tënde."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modifiko kontaktet"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Lejon aplikacionin të modifikojë të dhënat rreth kontakteve të tua të ruajtura në tabletin tënd, përfshi shpeshtësinë me të cilën ke telefonuar, ke dërguar mail-a apo ke komunikuar në rrugë të tjera me kontakte të veçanta. Kjo leje u mundëson aplikacioneve të fshijnë të dhënat e kontaktit."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Lejon aplikacionin të modifikojë të dhënat rreth kontakteve të tua të ruajtura në pajisjen tënde Android TV, përfshi shpeshtësinë me të cilën ke telefonuar, ke dërguar email-e apo komunikuar në rrugë të tjera me kontakte specifike. Ky autorizim i lejon aplikacionet të fshijnë të dhënat e kontaktit."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Lejon aplikacionin të modifikojë të dhënat e kontakteve të tua të ruajtura në telefon, përfshirë shpeshtësinë me të cilën ke telefonuar, ke dërguar mail-a apo ke komunikuar në rrugë të tjera me kontakte të veçanta. Kjo leje iu mundëson aplikacioneve të fshijnë të dhënat e kontakteve."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Lejon aplikacionin të modifikojë të dhënat rreth kontakteve të tua të ruajtura në tabletin tënd. Kjo leje lejon që aplikacionet të fshijnë të dhënat e kontakteve."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Lejon aplikacionin të modifikojë të dhënat rreth kontakteve të tua të ruajtura në pajisjen tënde Android TV. Kjo leje lejon që aplikacionet të fshijnë të dhënat e kontakteve."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Lejon aplikacionin të modifikojë të dhënat rreth kontakteve të tua të ruajtura në telefonin tënd. Kjo leje lejon që aplikacionet të fshijnë të dhënat e kontakteve."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"lexo ditarin e telefonatave"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Ky aplikacion mund të lexojë të gjithë historikun e telefonatave."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"shkruaj ditarin e telefonatave"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"qasje në komandat shtesë të ofruesit të vendndodhjes"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Lejon aplikacionin të ketë qasje në komandat shtesë të ofruesit për vendndodhjen. Kjo mund ta lejojë aplikacionin të ndërhyjë në operacionin e GPS-së apo të burimeve të tjera për vendndodhjen."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"qasu në vendndodhjen e saktë vetëm në plan të parë"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Ky aplikacion mund të marrë vendndodhjen tënde të saktë në çdo kohë kur është në plan të parë. Këto shërbime të vendndodhjes duhet të jenë të aktivizuara dhe në dispozicion në telefonin tënd që aplikacioni të mund t\'i përdorë. Kjo gjë mund të rritë konsumin e baterisë."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"qasu te vendndodhja e përafërt (bazuar te rrjeti) vetëm në plan të parë"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Ky aplikacion mund të marrë vendndodhjen tënde bazuar në burimet e rrjetit si antenat e operatorëve celulare dhe rrjetet Wi-Fi, por vetëm kur aplikacioni është në plan të parë. Këto shërbime të vendndodhjes duhet të jenë të aktivizuara dhe të ofrohen në tabletin tënd që aplikacioni të mund t\'i përdorë."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Ky aplikacion mund të marrë vendndodhjen tënde bazuar në burimet e rrjetit si antenat e operatorëve celulare dhe rrjetet Wi-Fi, por vetëm kur aplikacioni është në plan të parë. Këto shërbime të vendndodhjes duhet të jenë të aktivizuara dhe të ofrohen në pajisjen tënde Android TV që aplikacioni të mund t\'i përdorë."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Ky aplikacion mund të marrë vendndodhjen tënde bazuar në burimet e rrjetit si antenat e operatorëve celulare dhe rrjetet Wi-Fi, por vetëm kur aplikacioni është në plan të parë. Këto shërbime të vendndodhjes duhet të jenë të aktivizuara dhe të ofrohen në telefonin tënd që aplikacioni të mund t\'i përdorë."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Ky aplikacion mund të marrë vendndodhjen tënde të saktë vetëm kur është në plan të parë. Shërbimet e vendndodhjes duhet të jenë të aktivizuara dhe në dispozicion në pajisjen tënde që aplikacioni të mund t\'i përdorë. Kjo gjë mund të rrisë konsumin e baterisë."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"qasu në vendndodhjen e përafërt vetëm në plan të parë"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Ky aplikacion mund të marrë vendndodhjen tënde të përafërt vetëm kur është në plan të parë. Shërbimet e vendndodhjes duhet të jenë të aktivizuara dhe të ofrohen në pajisjen tënde që aplikacioni të mund t\'i përdorë."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"qasje te vendndodhja në sfond"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Nëse kjo jepet përveç qasjes te vendndodhja e përafërt ose të saktë, aplikacioni mund të qaset te vendndodhja ndërkohë që ekzekutohet në sfond."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Ky aplikacion mund të ketë qasje te vendndodhja ndërkohë që funksionon në sfond, përveç qasjes në plan të parë te vendndodhja."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"ndrysho cilësimet e audios"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Lejon aplikacionin të modifikojë cilësimet globale të audios siç është volumi dhe se cili altoparlant përdoret për daljen."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"regjistro audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Lejon aplikacionin të shikojë konfigurimin e \"bluetooth-it\" në tablet, të kryejë dhe të pranojë lidhje me pajisjet e çiftuara."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Lejon aplikacionin të shikojë konfigurimin e Bluetooth-it në pajisjen tënde Android TV dhe të kryejë dhe të pranojë lidhje me pajisjet e çiftuara."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Lejon aplikacionin të shohë konfigurimin e \"bluetooth-it\" në telefon dhe të kryejë e pranojë lidhje me pajisjet e çiftuara."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"kontrollo \"Komunikimin e fushës në afërsi\" NFC"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Lejon aplikacionin të komunikojë me etiketimet e \"Komunikimit të fushës së afërt (NFC)\", kartat dhe lexuesit."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"çaktivizo kyçjen e ekranit"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"U lidh me <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Trokit për të parë skedarët"</string>
<string name="pin_target" msgid="8036028973110156895">"Gozhdo"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Zhgozhdo"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Informacioni mbi aplikacionin"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Po nis demonstrimin..."</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Të përditësohen këta artikuj në "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> dhe <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Ruaj"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Jo, faleminderit"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Jo tani"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Asnjëherë"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Përditëso"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Vazhdo"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"fjalëkalimi"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Kalo tek ekrani i ndarë"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ekrani i kyçjes"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Pamja e ekranit"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikacioni <xliff:g id="APP_NAME">%1$s</xliff:g> në dritaren kërcyese."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Shiriti i nëntitullit të <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index e93c852..890d91e 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -190,8 +190,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Апликација за администраторе на профилу за Work недостаје или је оштећена. Због тога су профил за Work и повезани подаци избрисани. Обратите се администратору за помоћ."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Профил за Work више није доступан на овом уређају"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Превише покушаја уноса лозинке"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Администратор је уступио уређај за личну употребу"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Уређајем се управља"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Организација управља овим уређајем и може да надгледа мрежни саобраћај. Додирните за детаље."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Уређај ће бити обрисан"</string>
@@ -384,13 +383,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Дозвољава апликацији да шаље лепљива емитовања која остају по завршетку емитовања. Прекомерна употреба може да успори или дестабилизује Android TV уређај тако што ће га приморати да троши превише меморије."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Дозвољава апликацији да шаље пријемчива емитовања, која остају по завршетку емитовања. Прекомерна употреба може да успори или дестабилизује телефон тако што ће га приморати да троши превише меморије."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"читање контаката"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Дозвољава апликацији да чита податке о контактима ускладиштене на таблету, укључујући податке о томе колико често зовете одређене особе, шаљете им поруке е-поште или на други начин комуницирате са њима. Ова дозвола омогућава апликацијама да чувају податке о контактима, а злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Дозвољава апликацији да чита податке о контактима које чувате на Android TV уређају, укључујући учесталост позива, слања имејлова или других начина комуникације са одређеним појединцима. Ова дозвола омогућава апликацијама да чувају податке о контактима и злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Дозвољава апликацији да чита податке о контактима ускладиштене на телефону, укључујући податке о томе колико често зовете одређене особе, шаљете им поруке е-поште или на други начин комуницирате са њима. Ова дозвола омогућава апликацијама да чувају податке о контактима, а злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Дозвољава апликацији да чита податке о контактима које чувате на таблету. Апликације ће имати приступ и налозима на вашем таблету на којима су направљени контакти. Ту могу да спадају налози које су отвориле апликације које сте инсталирали. Ова дозвола омогућава апликацијама да чувају податке о контактима и злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Дозвољава апликацији да чита податке о контактима које чувате на Android TV уређају. Апликације ће имати приступ и налозима на вашем Android TV уређају на којима су направљени контакти. Ту могу да спадају налози које су отвориле апликације које сте инсталирали. Ова дозвола омогућава апликацијама да чувају податке о контактима и злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Дозвољава апликацији да чита податке о контактима које чувате на телефону. Апликације ће имати приступ и налозима на вашем телефону на којима су направљени контакти. Ту могу да спадају налози које су отвориле апликације које сте инсталирали. Ова дозвола омогућава апликацијама да чувају податке о контактима и злонамерне апликације могу да деле податке о контактима без вашег знања."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"измена контаката"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Дозвољава апликацији да мења податке о контактима ускладиштене на таблету, укључујући податке о томе колико често зовете одређене контакте, шаљете им поруке е-поште или на други начин комуницирате са њима. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Дозвољава апликацији да мења податке о контактима које чувате на Android TV уређају, укључујући учесталост позива, слања имејлова или других начина комуникације са одређеним контактима. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Дозвољава апликацији да мења податке о контактима ускладиштене на телефону, укључујући податке о томе колико често зовете одређене контакте, шаљете им поруке е-поште или на други начин комуницирате са њима. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Дозвољава апликацији да мења податке о контактима које чувате на таблету. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Дозвољава апликацији да мења податке о контактима које чувате на Android TV уређају. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Дозвољава апликацији да мења податке о контактима које чувате на телефону. Ова дозвола омогућава апликацијама да бришу податке о контактима."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"читање евиденције позива"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Ова апликација може да чита историју позива."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"писање евиденције позива"</string>
@@ -410,13 +409,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"приступ додатним командама добављача локације"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Омогућава апликацији да приступа додатним командама даваоца услуга локације. То може да омогући апликацији да утиче на рад GPS-а или других извора локације."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"приступ прецизној локацији само у првом плану"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Ова апликација може да одреди вашу тачну локацију само када ради у првом плану. Ове услуге локације морају да буду укључене и доступне на телефону да би апликација могла да их користи. То може да повећа потрошњу батерије."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"приступ приближној локацији (утврђеној преко мреже) само у првом плану"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Ова апликација може да приступи вашој локацији помоћу извора мреже, као што су мобилни предајници и Wi-Fi мреже, али само када апликација ради у првом плану. Ове услуге локације морају да буду укључене и доступне на таблету да би апликација могла да их користи"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Ова апликација може да приступи вашој локацији помоћу извора мреже, као што су мобилни предајници и Wi-Fi мреже, али само када апликација ради у првом плану. Ове услуге локације морају да буду укључене и доступне на Android TV уређају да би апликација могла да их користи."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Ова апликација може да приступи вашој локацији помоћу извора мреже, као што су мобилни предајници и Wi-Fi мреже, али само када апликација ради у првом плану. Ове услуге локације морају да буду укључене и доступне на телефону да би апликација могла да их користи."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Ова апликација може да одреди вашу тачну локацију само када ради у првом плану. Услуге локације морају да буду укључене и доступне на уређају да би апликација могла да их користи. То може да повећа потрошњу батерије."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"приступ приближној локацији само у првом плану"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Ова апликација може да одреди вашу приближну локацију само када ради у првом плану. Услуге локације морају да буду укључене и доступне на уређају да би апликација могла да их користи."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"приступ локацији у позадини"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Ако се поред приближног или прецизног приступа локација одобри и овај, апликација може да приступа локацији док је покренута у позадини."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Ова апликација може да приступа локацији док ради у позадини, као и када ради у првом плану."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"промена аудио подешавања"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Дозвољава апликацији да мења глобална аудио подешавања као што су јачина звука и избор звучника који се користи као излаз."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"снимање аудио записа"</string>
@@ -497,6 +494,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Дозвољава апликацији да прегледа конфигурацију Bluetooth-а на таблету, као и да успоставља и прихвата везе са упареним уређајима."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Дозвољава апликацији да прегледа конфигурацију Bluetooth-а на Android TV уређају и да успоставља и прихвата везе са упареним уређајима."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Дозвољава апликацији да прегледа конфигурацију Bluetooth-а на телефону, као и да успоставља и прихвата везе са упареним уређајима."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"контрола комуникације у ужем пољу (Near Field Communication)"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Дозвољава апликацији да комуницира са ознакама, картицама и читачима комуникације кратког домета (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"онемогућавање закључавања екрана"</string>
@@ -1894,7 +1895,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Повезано је са производом <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Додирните за преглед датотека"</string>
<string name="pin_target" msgid="8036028973110156895">"Закачи"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Откачи"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Информације о апликацији"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Покрећемо демонстрацију..."</string>
@@ -1938,6 +1943,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Желите ли да ажурирате ове ставке у услузи "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> и <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Сачувај"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Не, хвала"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Не сада"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Никада"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Ажурирај"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Настави"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"лозинка"</string>
@@ -2034,5 +2041,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Укључите/искључите подељени екран"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Закључани екран"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Снимак екрана"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> у искачућем прозору."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Трака са насловима апликације <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index cf0e0bb..eabcd8e 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Administratörsappen för jobbprofilen saknas eller är skadad. Det innebär att jobbprofilen och all relaterad data har raderats. Kontakta administratören om du vill ha hjälp."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jobbprofilen är inte längre tillgänglig på enheten"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"För många försök med lösenord"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratören tillåter inte längre privat bruk av enheten"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Enheten hanteras"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Organisationen hanterar den här enheten och kan övervaka nätverkstrafiken. Tryck om du vill veta mer."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Enheten kommer att rensas"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Tillåter att appen skickar sticky-sändningar som finns kvar när sändningen är slut. Vid intensiv användning kan Android TV-enheten bli långsam eller instabil eftersom för mycket minne används."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Tillåter att appen skickar sticky broadcast, som finns kvar när sändningen är slut. Vid intensiv användning kan mobilen bli långsam eller instabil eftersom minnet överbelastas."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"läsa dina kontakter"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Tillåter att appen läser kontaktuppgifter som sparats på surfplattan, inklusive information om hur ofta du har ringt, skickat e-post till eller på andra sätt kommunicerat med specifika personer. Med den här behörigheten tillåts appen att spara kontaktuppgifter. Skadliga appar kan dela uppgifterna med andra utan din vetskap."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Tillåter att appen läser kontaktuppgifter som sparats på Android TV-enheten, inklusive information om hur ofta du har ringt, skickat e-post till eller på andra sätt kommunicerat med enskilda personer. Med den här behörigheten tillåts appen att spara kontaktuppgifter. Skadliga appar kan dela uppgifterna med andra utan din vetskap."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Tillåter att appen läser kontaktuppgifter som sparats på mobilen, inklusive information om hur ofta du har ringt, skickat e-post till eller på andra sätt kommunicerat med specifika personer. Med den här behörigheten tillåts appen att spara kontaktuppgifter. Skadliga appar kan dela uppgifterna med andra utan din vetskap."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Tillåter att appen läser kontaktuppgifter som sparats på surfplattan. Appar har även åtkomst till de konton på surfplattan som har skapade kontakter. Detta kan inkludera konton som har skapats av appar som du har installerat. Med den här behörigheten tillåts appen att spara kontaktuppgifter. Skadliga appar kan dela uppgifterna med andra utan din vetskap."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Tillåter att appen läser kontaktuppgifter som sparats på Android TV-enheten. Appar har även åtkomst till de konton på Android TV-enheten som har skapade kontakter. Detta kan inkludera konton som har skapats av appar som du har installerat. Med den här behörigheten tillåts appen att spara kontaktuppgifter. Skadliga appar kan dela uppgifterna med andra utan din vetskap."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Tillåter att appen läser kontaktuppgifter som sparats på telefonen. Appar har även åtkomst till de konton på telefonen som har skapade kontakter. Detta kan inkludera konton som har skapats av appar som du har installerat. Med den här behörigheten tillåts appen att spara kontaktuppgifter. Skadliga appar kan dela uppgifterna med andra utan din vetskap."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"ändra kontakterna"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Tillåter att appen ändrar kontaktuppgifter som sparats på surfplattan, inklusive information om hur ofta du har ringt, skickat e-post till eller på andra sätt kommunicerat med specifika personer. Med den här behörigheten tillåts appar att ta bort kontaktuppgifter."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Tillåter att appen ändrar kontaktuppgifter som sparats på Android TV-enheten, inklusive information om hur ofta du har ringt, skickat e-post till eller på andra sätt kommunicerat med enskilda kontakter. Med den här behörigheten tillåts appar att ta bort kontaktuppgifter."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Tillåter att appen ändrar kontaktuppgifter som sparats på mobilen, inklusive information om hur ofta du har ringt, skickat e-post till eller på andra sätt kommunicerat med specifika personer. Med den här behörigheten tillåts appar att ta bort kontaktuppgifter."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Tillåter att appen ändrar kontaktuppgifter som sparats på surfplattan. Med den här behörigheten får appar även radera kontaktuppgifter."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Tillåter att appen ändrar kontaktuppgifter som sparats på Android TV-enheten. Med den här behörigheten får appar även radera kontaktuppgifter."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Tillåter att appen ändrar kontaktuppgifter som sparats på telefonen. Med den här behörigheten får appar även radera kontaktuppgifter."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"läs samtalslogg"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Appen kan läsa din samtalshistorik."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"skriv samtalslogg"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"få åtkomst till extra kommandon för platsleverantör"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Tillåter att appen får åtkomst till extra kommandon för platsleverantör. Detta kan innebära att appen tillåts störa funktionen för GPS eller andra platskällor."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"endast åtkomst till exakt plats i förgrunden"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Den här appen kan endast få information om din exakta plats när den körs i förgrunden. Platstjänsterna måste ha aktiverats och finnas på mobilen om appen ska kunna använda dem. Detta kan leda till ökad batteriförbrukning."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"endast åtkomst till beräknad plats (nätverksbaserad) i förgrunden"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Appen kan endast få information om din plats från källor i nätverket, som mobilmaster och Wi-Fi-nätverk, när den körs i förgrunden. Platstjänsterna måste ha aktiverats och finnas på surfplattan om appen ska kunna använda dem."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Appen kan få information om din plats från olika nätverkskällor, som mobilmaster och Wi-Fi-nätverk, men endast när den körs i förgrunden. Platstjänsterna måste ha aktiverats och finnas på Android TV-enheten om appen ska kunna använda dem."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Appen kan endast få information om din plats från källor i nätverket, som mobilmaster och Wi-Fi-nätverk, när den körs i förgrunden. Platstjänsterna måste ha aktiverats och finnas på mobilen om appen ska kunna använda dem."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Den här appen kan endast få information om din exakta plats när den körs i förgrunden. Platstjänsterna måste ha aktiverats och vara tillgängliga på enheten om appen ska kunna använda dem. Detta kan leda till ökad batteriförbrukning."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"endast åtkomst till ungefärlig plats i förgrunden"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Den här appen kan endast få information om din ungefärliga plats när den körs i förgrunden. Platstjänsterna måste ha aktiverats och vara tillgängliga på enheten om appen ska kunna använda dem."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"få åtkomst till platsinformation i bakgrunden"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Om denna behörighet ges utöver ungefärlig eller exakt platsåtkomst får appen åtkomst till platsinformation när den körs i bakgrunden."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Appen får åtkomst till platsinformation när appen körs i bakgrunden, förutom att den har åtkomst när den körs i förgrunden."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"ändra dina ljudinställningar"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Tillåter att appen ändrar globala ljudinställningar som volym och vilken högtalarutgång som används."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"spela in ljud"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Tillåter att appen kommer åt pekdatorns Bluetooth-konfiguration och upprättar och godkänner anslutningar till parkopplade enheter."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Tillåter att appen läser Android TV-enhetens Bluetooth-konfiguration och upprättar och godkänner anslutningar till parkopplade enheter."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Tillåter att appen kommer åt mobilens Bluetooth-konfiguration och upprättar och godkänner anslutningar till parkopplade enheter."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"kontrollera närfältskommunikationen"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Tillåter att appen kommunicerar med etiketter, kort och läsare för närfältskommunikation (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"inaktivera skärmlåset"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Ansluten till <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Filerna visas om du trycker här"</string>
<string name="pin_target" msgid="8036028973110156895">"Fäst"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Lossa"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Info om appen"</string>
<string name="negative_duration" msgid="1938335096972945232">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Demo startas …"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Vill du uppdatera dessa objekt i "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> och <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Spara"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Nej tack"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Inte nu"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Aldrig"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Uppdatera"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Fortsätt"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"lösenordet"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Aktivera och inaktivera delad skärm"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Låsskärm"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skärmdump"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g>-app i popup-fönster."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Textningsfält för <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index f8cd19c..2abcaff 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Programu ya msimamizi wa wasifu wa kazini imepotea au ina hitilafu. Kwa sababu hiyo, wasifu wako wa kazini na data husika imefutwa. Wasiliana na msimamizi wako kwa usaidizi."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Wasifu wako wa kazini haupatikani tena kwenye kifaa hiki"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Umejaribu kuweka nenosiri mara nyingi mno"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Msimamizi aliacha kutumia kifaa kwa matumizi ya binafsi"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Kifaa kinadhibitiwa"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Shirika lako linadhibiti kifaa hiki na huenda likafuatilia shughuli kwenye mtandao. Gusa ili upate maelezo zaidi."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Data iliyomo kwenye kifaa chako itafutwa"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Huruhusu programu itume matangazo yanayonata, ambayo hubaki baada ya matangazo kuisha. Huenda matumizi zaidi yakapunguza kasi ya kifaa chako cha Android TV au kukifanya kisiwe thabiti kwa kukifanya kitumie hifadhi kubwa zaidi."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Inaruhusu programu kutuma matangazo nata, ambayo hubakia baada ya matangazo kuisha. Matumizi zaidi yanaweza kufanya simu kufanya kazi polepole au kuifanya isiwe thabiti kwa kuisababisha itumie kumbukumbu kubwa zaidi."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"kusoma anwani zako"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta kibao yako, ikiwa ni pamoja na mara ngapi umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu fulani. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Huruhusu programu isome data kuhusu anwani zako zilizohifadhiwa kwenye kifaa chako cha Android TV, ikiwa ni pamoja na mara ambazo umepiga simu, umetuma barua pepe au umewasiliana kwa njia zingine na watu mahususi. Idhini hii huruhusu programu kuhifadhi data yako ya anwani na huenda programu hasidi zikashiriki data ya anwani bila idhini yako."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye simu yako, ikiwa ni pamoja na mara ngapi umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu fulani. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Huruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta yako kibao. Programu pia zitafikia akaunti zilizo kwenye kompyuta yako kibao zilizounda anwani. Hii inaweza kujumuisha akaunti zilizoundwa na programu ambazo umesakinisha. Idhini hii huruhusu programu kuhifadhi data yako ya anwani na programu hasidi zinaweza kushiriki data ya anwani bila wewe kujua."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Huruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye kifaa chako cha Android TV. Programu pia zitafikia akaunti zilizo kwenye kifaa chako cha Android TV zilizounda anwani. Hii inaweza kujumuisha akaunti zilizoundwa na programu ambazo umesakinisha. Idhini hii huruhusu programu kuhifadhi data yako ya anwani na programu hasidi zinaweza kushiriki data ya anwani bila wewe kujua."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Huruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye simu yako. Programu pia zitafikia akaunti zilizo kwenye simu yako zilizounda anwani. Hii inaweza kujumuisha akaunti zilizoundwa na programu ambazo umesakinisha. Idhini hii huruhusu programu kuhifadhi data yako ya anwani na programu hasidi zinaweza kushiriki data ya anwani bila wewe kujua."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"kurekebisha anwani zako"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Huruhusu programu kurekebisha data kuhusu anwani ulizohifadhi kwenye kompyuta kibao yako, ikiwa ni pamoja na mara ambazo umepiga simu, kutuma barua pepe au kuwasiliana kwa njia nyingine na anwani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Huruhusu programu ibadilishe data kuhusu anwani zako zilizohifadhiwa kwenye kifaa chako cha Android TV, ikiwa ni pamoja na mara ambazo umepiga simu, umetuma barua pepe au kuwasiliana kwa njia nyingine na anwani mahususi. Idhini hii huruhusu programu ifute data ya anwani."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Huruhusu programu kurekebisha data kuhusu anwani ulizohifadhi kwenye simu yako, ikiwa ni pamoja na mara ambazo umepiga simu, kutuma barua pepe au kuwasiliana kwa njia nyingine na anwani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Huruhusu programu kubadilisha data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta yako kibao. Idhini hii huruhusu programu kufuta data ya anwani."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Huruhusu programu kubadilisha data kuhusu anwani zako zilizohifadhiwa kwenye kifaa chako cha Android TV. Idhini hii huruhusu programu kufuta data ya anwani."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Huruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye simu yako. Idhini hii huruhusu programu kufuta data ya anwani."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"kusoma rekodi ya simu"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Programu hii inaweza kusoma rekodi yako ya simu zilizopigwa."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"kuandika rekodi ya simu"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"fikia amri za ziada za mtoa huduma ya mahali"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Ruhusu programu kufikia amri za ziada za mtoa huduma za mahali. Hii huenda ikaruhusu programu ikatize matumizi ya GPS au vyanzo vingine vya eneo."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"kufikia mahali mahususi ikiwa tu programu imefunguliwa kwenye skrini"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Programu hii inaweza kupata mahali halisi ikiwa tu umeifungua kwenye skrini. Ni lazima uwashe huduma hizi za mahali na zipatikane kwenye simu yako ili programu iweze kuzitumia. Hatua hii inaweza kuongeza utumiaji wa betri."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"fikia eneo linalokadiriwa (kulingana na mtandao) wakati tu programu inatumika kwenye skrini"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Programu hii inaweza kupata eneo lako kulingana na vyanzo vya mtandao kama vile minara ya simu na mitandao ya Wi-Fi, lakini hili hufanyika tu wakati programu inatumika kwenye skrini. Ni lazima uwashe huduma hizi za mahali na zipatikane kwenye simu kibao yako ili programu iweze kuzitumia."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Programu hii inaweza kupata maelezo ya mahali ulipo kulingana na vyanzo vya mtandao kama vile minara ya simu na mitandao ya Wi-Fi, lakini hili hufanyika tu wakati programu inatumika. Ni lazima huduma hizi za mahali ziwashwe na kupatikana kwenye kifaa chako cha Android TV ili programu iweze kuzitumia."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Programu hii inaweza kupata eneo lako kulingana na vyanzo vya mtandao kama vile minara ya simu na mitandao ya Wi-Fi, lakini hili hufanyika tu wakati programu inatumika kwenye skrini. Ni lazima uwashe huduma hizi za mahali na zipatikane kwenye simu yako ili programu iweze kuzitumia."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Programu hii inaweza kupata mahali halisi ikiwa tu umeifungua kwenye skrini. Ni lazima uwashe huduma za mahali na zipatikane kwenye kifaa chako ili programu iweze kuzitumia. Hatua hii inaweza kuongeza matumizi ya betri."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"kufikia mahali palipokadiriwa ikiwa tu programu imefunguliwa kwenye skrini"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Programu hii inaweza kukadiria mahali ulipo ikiwa tu umeifungua kwenye skrini. Ni lazima huduma za mahali ziwashwe na zipatikane kwenye kifaa chako ili programu iweze kuzitumia."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"ifikie mahali inapotumika chinichini"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Kama ruhusa hii itatolewa, mbali na idhini ya kufikia mahali panapokadiriwa au mahali mahususi, programu inaweza kufikia mahali wakati inatumika chinichini."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Programu hii inaweza kufikia maelezo ya mahali inapotumika chinichini, pamoja na ufikiaji wa mahali wakati umeifungua kwenye skrini."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"badilisha mipangilio yako ya sauti"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Inaruhusu programu kurekebisha mipangilio ya sauti kila mahali kama vile sauti na ni kipaza sauti kipi ambacho kinatumika kwa kutoa."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"kurekodi sauti"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Huruhusu programu kuona usanidi wa Bluetooth kwenye kompyuta kibao, na kutuma na kukubali miunganisho kwa vifaa vilivyooanishwa."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Huruhusu programu iangalie mipangilio iliyowekwa ya Bluetooth kwenye kifaa chako cha Android TV na kufanya na kukubali miunganisho na vifaa vilivyooanishwa."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Huruhusu programu kuona usanidi wa Bluetooth kwenye simu, na kutuma na kukubali miunganisho kwa vifaa vilivyooanishwa."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"kudhibiti Mawasiliano ya Vifaa Vilivyokaribu (NFC)"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Inaruhusu programu kuwasiliana na lebo, kadi na wasomaji wa Near Field Communication (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"zima kufuli la skrini yako"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Imeunganishwa na <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Gusa ili uangalie faili"</string>
<string name="pin_target" msgid="8036028973110156895">"Bandika"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Bandua"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Maelezo ya programu"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Inaanzisha onyesho..."</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Ungependa kusasisha vipengee hivi katika "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> na <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Hifadhi"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Hapana, asante"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Si sasa"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Kamwe"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Sasisha"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Endelea"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"nenosiri"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Geuza Skrini Iliyogawanywa"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Skrini Iliyofungwa"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Picha ya skrini"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Programu ya <xliff:g id="APP_NAME">%1$s</xliff:g> katika dirisha Ibukizi."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Upau wa manukuu wa <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index ac284d3..56a44dd 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"பணிக் கணக்கு நிர்வாகி ஆப்ஸ் இல்லை அல்லது அது சிதைந்துள்ளது. இதன் விளைவாக, உங்கள் பணிக் கணக்குமும் அதனுடன் தொடர்புடைய தரவும் நீக்கப்பட்டன. உதவிக்கு, நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"இந்தச் சாதனத்தில் இனி பணிக் கணக்கு கிடைக்காது"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"கடவுச்சொல்லை அதிக முறை தவறாக முயற்சித்துவிட்டீர்கள்"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"நிர்வாகியால் தனிப்பட்ட உபயோகத்திற்காக ஒதுக்கப்பட்ட சாதனம்"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"சாதனம் நிர்வகிக்கப்படுகிறது"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"உங்கள் நிறுவனம் இந்தச் சாதனத்தை நிர்வகிக்கும், அத்துடன் அது நெட்வொர்க் ட்ராஃபிக்கைக் கண்காணிக்கலாம். விவரங்களுக்கு, தட்டவும்."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"சாதனத் தரவு அழிக்கப்படும்"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"வலைபரப்பு முடிந்த பின்னரும் தங்கிவிடும் ஸ்டிக்கி வலைபரப்புகளை அனுப்ப ஆப்ஸை அனுமதிக்கும். அளவுக்கதிகமான உபயோகம் Android TVயின் வேகத்தைக் குறைக்கவோ நிலையற்றதாகவோ ஆக்கக்கூடும். இதனால் அதிகமான நினைவகம் பயன்படுத்தப்படும்."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"அலைபரப்பு முடிந்த பின்னும் இருக்கும், தொடர்ந்து அணுகத்தக்க அலைபரப்பை அனுப்பப் ஆப்ஸை அனுமதிக்கிறது. அதிகமாகப் பயன்படுத்தினால், மொபைலானது நினைவகத்தை மிக அதிகமாகப் பயன்படுத்துவதால் வேகம் குறைந்ததாகவும், நிலையற்றதாகவும் ஆகலாம்."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"உங்கள் தொடர்புகளைப் படித்தல்"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உட்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"உங்கள் Android TVயில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவைத் தெரிந்துகொள்ள ஆப்ஸை அனுமதிக்கும். குறிப்பிட்ட தனிநபரை எத்தனை முறை அழைத்தீர்கள், பிறவழிகளில் தொடர்புகொண்டீர்கள் அல்லது அவருக்கு எத்தனை முறை மின்னஞ்சல் அனுப்பினீர்கள் என்பதும் இதில் அடங்கும். இது உங்கள் தொடர்புத் தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கும், அத்துடன் தீங்குவிளைவிக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்புத் தரவைப் பகிரக்கூடும்."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்ட எண்ணிக்கை உட்பட, உங்கள் மொபைலில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"உங்கள் டேப்லெட்டில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவை அணுக ஆப்ஸை அனுமதிக்கும். உங்கள் டேப்லெட்டில் உள்ள தொடர்புகளை உருவாக்கிய கணக்குகளுக்கான அணுகலும் ஆப்ஸிற்கு இருக்கும். நீங்கள் நிறுவிய ஆப்ஸ் மூலம் உருவாக்கப்பட்ட அனைத்துக் கணக்குகளும் இதில் உள்ளடங்கக்கூடும். இந்த அனுமதி உங்கள் தொடர்புத் தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரக்கூடும்."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"உங்கள் Android TVயில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவை அணுக ஆப்ஸை அனுமதிக்கும். உங்கள் Android TVயில் உள்ள தொடர்புகளை உருவாக்கிய கணக்குகளுக்கான அணுகலும் ஆப்ஸிற்கு இருக்கும். நீங்கள் நிறுவிய ஆப்ஸ் மூலம் உருவாக்கப்பட்ட அனைத்துக் கணக்குகளும் இதில் உள்ளடங்கக்கூடும். இந்த அனுமதி உங்கள் தொடர்புத் தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரக்கூடும்."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"உங்கள் மொபைலில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவை அணுக ஆப்ஸை அனுமதிக்கும். உங்கள் மொபைலில் உள்ள தொடர்புகளை உருவாக்கிய கணக்குகளுக்கான அணுகலும் ஆப்ஸிற்கு இருக்கும். நீங்கள் நிறுவிய ஆப்ஸ் மூலம் உருவாக்கப்பட்ட அனைத்துக் கணக்குகளும் இதில் உள்ளடங்கக்கூடும். இந்த அனுமதி உங்கள் தொடர்புத் தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரக்கூடும்."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"உங்கள் தொடர்புகளை மாற்றுதல்"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"குறிப்பிட்ட தொடர்புகளுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உள்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதியானது தொடர்புத் தரவை நீக்க ஆப்ஸை அனுமதிக்கிறது."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"உங்கள் Android TVயில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவை மாற்ற ஆப்ஸை அனுமதிக்கும். குறிப்பிட்ட தொடர்பை எத்தனை முறை அழைத்தீர்கள், பிறவழிகளில் தொடர்புகொண்டீர்கள் அல்லது அவருக்கு எத்தனை முறை மின்னஞ்சல் அனுப்பினீர்கள் என்பதும் இதில் அடங்கும். தொடர்புத் தரவை நீக்க ஆப்ஸை இது அனுமதிக்கும்."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"குறிப்பிட்ட தொடர்புகளுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உள்பட, உங்கள் மொபைலில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதியானது தொடர்புத் தரவை நீக்க ஆப்ஸை அனுமதிக்கிறது."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"உங்கள் டேப்லெட்டில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவை மாற்ற ஆப்ஸை அனுமதிக்கும். இது தொடர்புத் தரவை நீக்கவும் ஆப்ஸை அனுமதிக்கும்."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"உங்கள் Android TVயில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவை மாற்ற ஆப்ஸை அனுமதிக்கும். இது தொடர்புத் தரவை நீக்கவும் ஆப்ஸை அனுமதிக்கும்."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"உங்கள் மொபைலில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவை மாற்ற ஆப்ஸை அனுமதிக்கும். இது தொடர்புத் தரவை நீக்கவும் ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"அழைப்புப் பதிவைப் படித்தல்"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"இந்த ஆப்ஸ் உங்கள் அழைப்பு வரலாற்றைப் படிக்கலாம்."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"அழைப்புப் பதிவை எழுதுதல்"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"கூடுதல் இட வழங்குநரின் கட்டளைகளின் அணுகல்"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"கூடுதல் இட வழங்குநர் கட்டளைகளை அணுகப் ஆப்ஸை அனுமதிக்கிறது. இது, GPS அல்லது பிற இருப்பிட மூலங்களின் செயல்பாட்டை இடைமறிக்க ஆப்ஸை அனுமதிக்கலாம்."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"முன்புலத்தில் இயங்கும்போது மட்டும் துல்லியமான இருப்பிடத்தைக் கண்டறிதல்"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"இந்த ஆப்ஸ் முன்புலத்தில் இயங்கும்போது மட்டுமே நீங்கள் இருக்கும் இடத்தைத் துல்லியமாகக் கண்டறியும். உங்கள் மொபைலில், இருப்பிடச் சேவைகளை ஆப்ஸ் பயன்படுத்துவதற்கு வசதியாக, அவை ஆன் செய்யப்பட்டிருக்க வேண்டும். இதனால் பேட்டரி அதிகம் பயன்படுத்தப்படலாம்."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"முன்புலத்தில் இயங்கும்போது மட்டும் தோராயமான இருப்பிடத்தைக் கண்டறிதல் (நெட்வொர்க் அடிப்படையில்)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"ஆப்ஸ் முன்புலத்தில் இயங்கும்போது மட்டுமே மொபைல் டவர்கள், வைஃபை நெட்வொர்க்குகள் போன்ற நெட்வொர்க் மூலங்கள் மூலம் ஆப்ஸால் உங்கள் இருப்பிடத்தைப் பெற முடியும். உங்கள் டேப்லெட்டில் \'இருப்பிடச் சேவைகளை\' ஆப்ஸ் பயன்படுத்துவதற்கு வசதியாக அவை ஆன் செய்யப்பட்டிருக்க வேண்டும்."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"மொபைல் டவர்கள், வைஃபை நெட்வொர்க்குகள் போன்ற நெட்வொர்க் ஆதாரங்களின் உதவியுடன் ஆப்ஸால் உங்கள் இருப்பிடத்தைப் பெற முடியும். அதற்கு ஆப்ஸ் முன்புலத்தில் இயங்க வேண்டும். இதனை ஆப்ஸ் பயன்படுத்துவதற்கேற்ப உங்கள் Android TVயில் இந்த இருப்பிடச் சேவைகள் இயக்கப்பட்டு கிடைக்கும்படி இருக்க வேண்டும்."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"ஆப்ஸ் முன்புலத்தில் இயங்கும்போது மட்டுமே மொபைல் டவர்கள், வைஃபை நெட்வொர்க்குகள் போன்ற நெட்வொர்க் மூலங்கள் மூலம் ஆப்ஸால் உங்கள் இருப்பிடத்தைப் பெற முடியும். உங்கள் மொபைலில் \'இருப்பிடச் சேவைகளை\' ஆப்ஸ் பயன்படுத்துவதற்கு வசதியாக அவை ஆன் செய்யப்பட்டிருக்க வேண்டும்."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"இந்த ஆப்ஸ் முன்புலத்தில் இயங்கும்போது மட்டுமே நீங்கள் இருக்கும் இடத்தைத் துல்லியமாகக் கண்டறியும். உங்கள் சாதனத்தில், இருப்பிடச் சேவைகளை ஆப்ஸ் பயன்படுத்துவதற்கு வசதியாக, அவை ஆன் செய்யப்பட்டிருக்க வேண்டும். இதனால் பேட்டரி அதிகம் பயன்படுத்தப்படக்கூடும்."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"முன்புலத்தில் இயங்கும்போது மட்டும் தோராயமான இருப்பிடத்தைக் கண்டறிதல்"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"முன்புலத்தில் இருக்கும்போது மட்டுமே இந்த ஆப்ஸால் தோராயமான இடத்தைக் கண்டறிய முடியும். இருப்பிட சேவைகள் ஆன் செய்யப்பட்டு சாதனத்தில் இருக்க வேண்டும், அப்போதுதான் அவற்றை ஆப்ஸால் பயன்படுத்த முடியும்."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"பின்புலத்தில் இருப்பிடத்தை அணுகுதல்"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"தோராயமான அல்லது துல்லியமான \'இருப்பிட அணுகலுடன்\' சேர்ந்து இதற்கும் அனுமதி வழங்கப்பட்டால், ஆப்ஸ் பின்புலத்தில் இயங்கினாலும் இருப்பிடத்தை அணுக இயலும்."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"முன்புல இருப்பிட அணுகலுடன் பின்புலத்தில் இயங்கும்போதும் இந்த ஆப்ஸால் இருப்பிடத்தை அணுக முடியும்."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"எனது ஆடியோ அமைப்புகளை மாற்றுதல்"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"ஒலியளவு மற்றும் வெளியீட்டிற்கு ஸ்பீக்கர்கள் பயன்படுத்தப்படுவது போன்ற ஒட்டுமொத்த ஆடியோ அமைப்புகளைக் கட்டுப்படுத்தப் ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ஆடியோவைப் பதிவுசெய்தல்"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"டேப்லெட்டில் புளூடூத் இன் உள்ளமைவைப் பார்க்க மற்றும் இணைந்த சாதனங்களுடன் இணைப்புகளை ஏற்படுத்த மற்றும் ஏற்க ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Android TVயில் புளூடூத்தின் உள்ளமைவைப் பார்க்கவும் இணைக்கப்பட்ட சாதனங்களுடன் இணைப்புகளை உருவாக்கவும் ஏற்கவும் ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"மொபைலில் புளூடூத் இன் உள்ளமைவைப் பார்க்க மற்றும் இணைந்த சாதனங்களுடன் இணைப்புகளை ஏற்படுத்த மற்றும் ஏற்க ஆப்ஸை அனுமதிக்கிறது."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"குறுகிய இடைவெளி தகவல்பரிமாற்றத்தைக் கட்டுப்படுத்துதல்"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"குறுகிய இடைவெளி தகவல்பரிமாற்றம் (NFC), குறிகள், கார்டுகள் மற்றும் ரீடர்கள் ஆகியவற்றுடன் தொடர்புகொள்ள, ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"உங்கள் திரைப் பூட்டை முடக்குதல்"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> உடன் இணைக்கப்பட்டது"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"கோப்புகளைப் பார்க்க, தட்டவும்"</string>
<string name="pin_target" msgid="8036028973110156895">"பின் செய்"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"பின்னை அகற்று"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"ஆப்ஸ் தகவல்"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"டெமோவைத் தொடங்குகிறது…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" இல் <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> மற்றும் <xliff:g id="TYPE_2">%3$s</xliff:g>ஐ மாற்றவா?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"சேமி"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"வேண்டாம்"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"இப்போது வேண்டாம்"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"ஒருபோதும் வேண்டாம்"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"புதுப்பி"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"தொடர்க"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"கடவுச்சொல்"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"திரைப் பிரிப்பை நிலைமாற்று"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"பூட்டுத் திரை"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ஸ்கிரீன்ஷாட்"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸில் உள்ள பாப் அப் சாளரம்."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸின் தலைப்புப் பட்டி."</string>
</resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 6641c41..47dcb2b 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"కార్యాలయ ప్రొఫైల్ నిర్వాహక యాప్ లేదు లేదా పాడైంది. తత్ఫలితంగా, మీ కార్యాలయ ప్రొఫైల్ మరియు సంబంధిత డేటా తొలగించబడ్డాయి. సహాయం కోసం మీ నిర్వాహకులను సంప్రదించండి."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ఈ పరికరంలో మీ కార్యాలయ ప్రొఫైల్ ఇప్పుడు అందుబాటులో లేదు"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"చాలా ఎక్కువ పాస్వర్డ్ ప్రయత్నాలు చేసారు"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"వ్యక్తిగత వినియోగం కోసం నిర్వాహకులు పరికరాన్ని తీసి వేశారు"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"పరికరం నిర్వహించబడింది"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"మీ సంస్థ ఈ పరికరాన్ని నిర్వహిస్తుంది మరియు నెట్వర్క్ ట్రాఫిక్ని పర్యవేక్షించవచ్చు. వివరాల కోసం నొక్కండి."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"మీ పరికరంలోని డేటా తొలగించబడుతుంది"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"ప్రసారం ముగిసిన తర్వాత భద్రపరచబడే ప్రసారాలను పంపడానికి యాప్ని అనుమతిస్తుంది. ఎక్కువగా వినియోగిస్తే అధిక పరిమాణంలో మెమరీని ఉపయోగించడం వలన టీవీ నెమ్మదిగా పని చేయవచ్చు లేదా అస్థిరంగా మారవచ్చు."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ప్రసారం ముగిసిన తర్వాత భద్రపరచబడే ప్రసారాలను పంపడానికి యాప్ను అనుమతిస్తుంది. అత్యధిక వినియోగం వలన ఫోన్ నెమ్మదిగా పని చేయవచ్చు లేదా అధిక పరిమాణంలో మెమరీని ఉపయోగించడం వలన అస్థిరంగా మారవచ్చు."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"మీ పరిచయాలను చదవడం"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"మీరు నిర్దిష్ట వ్యక్తులకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ టాబ్లెట్లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను చదవడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి మీ పరిచయ డేటాను సేవ్ చేయడానికి యాప్లను అనుమతిస్తుంది మరియు హానికరమైన యాప్లు మీకు తెలియకుండానే పరిచయ డేటాను షేర్ చేయవచ్చు."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"మీరు నిర్దిష్ట వ్యక్తులకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన ఫ్రీక్వెన్సీతో సహా మీ Android TV పరికరంలో నిల్వ చేసిన మీ పరిచయాలకు సంబంధించిన డేటాను చదవడానికి యాప్ని అనుమతిస్తుంది. ఈ అనుమతి మీ పరిచయ డేటాను సేవ్ చేయడానికి యాప్లను అనుమతిస్తుంది మరియు హానికరమైన యాప్లు మీకు తెలియకుండానే పరిచయ డేటాను షేర్ చేయవచ్చు."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"మీరు నిర్దిష్ట వ్యక్తులకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ ఫోన్లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను చదవడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి మీ పరిచయ డేటాను సేవ్ చేయడానికి యాప్లను అనుమతిస్తుంది మరియు హానికరమైన యాప్లు మీకు తెలియకుండానే పరిచయ డేటాను షేర్ చేయవచ్చు."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"టాబ్లెట్లో నిల్వ చేసిన మీ కాంటాక్ట్లకు సంబంధించిన డేటాను చదవడానికి యాప్ను అనుమతిస్తుంది. కాంటాక్ట్లను సృష్టించిన మీ టాబ్లెట్లోని ఖాతాలకు కూడా యాప్లకు యాక్సెస్ ఉంటుంది. ఇందులో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా సృష్టించబడిన ఖాతాలు ఉండవచ్చు. ఈ అనుమతి, మీ కాంటాక్ట్ డేటాను సేవ్ చేయడానికి యాప్లను అనుమతిస్తుంది, హానికరమైన యాప్లు మీకు తెలియకుండానే కాంటాక్ట్ డేటాను షేర్ చేయవచ్చు."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"మీ Android TV పరికరంలో నిల్వ చేసిన కాంటాక్ట్లకు సంబంధించిన డేటాను చదవడానికి యాప్ను అనుమతిస్తుంది. కాంటాక్ట్లను సృష్టించిన మీ Android TV పరికరంలోని ఖాతాలకు కూడా యాప్లకు యాక్సెస్ ఉంటుంది. ఇందులో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా సృష్టించబడిన ఖాతాలు ఉండవచ్చు. ఈ అనుమతి, మీ కాంటాక్ట్ డేటాను సేవ్ చేయడానికి యాప్లను అనుమతిస్తుంది, హానికరమైన యాప్లు మీకు తెలియకుండానే కాంటాక్ట్ డేటాను షేర్ చేయవచ్చు."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ఫోన్లో నిల్వ చేసిన మీ కాంటాక్ట్లకు సంబంధించిన డేటాను చదవడానికి యాప్ను అనుమతిస్తుంది. కాంటాక్ట్లను సృష్టించిన మీ ఫోన్లోని ఖాతాలను కూడా యాప్లు యాక్సెస్ చేయగలవు. ఇందులో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా సృష్టించబడిన ఖాతాలు ఉండవచ్చు. ఈ అనుమతి, మీ కాంటాక్ట్ డేటాను సేవ్ చేయడానికి యాప్లను అనుమతిస్తుంది, హానికరమైన యాప్లు మీకు తెలియకుండానే కాంటాక్ట్ డేటాను షేర్ చేయవచ్చు."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"మీ పరిచయాలను సవరించడం"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"మీరు నిర్దిష్ట పరిచయాలకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ టాబ్లెట్లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను సవరించడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి పరిచయ డేటాను తొలగించడానికి యాప్లను అనుమతిస్తుంది."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"మీరు నిర్దిష్ట పరిచయాలకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన ఫ్రీక్వెన్సీతో సహా మీ Android TV పరికరంలో నిల్వ చేసిన మీ పరిచయాలకు సంబంధించిన డేటాను సవరించడానికి యాప్ని అనుమతిస్తుంది. ఈ అనుమతి పరిచయ డేటాను తొలగించడానికి యాప్లను అనుమతిస్తుంది."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"మీరు నిర్దిష్ట పరిచయాలకు కాల్ చేసిన, ఇమెయిల్ చేసిన లేదా ఇతర మార్గాల్లో కమ్యూనికేట్ చేసిన తరచుదనంతో సహా మీ ఫోన్లో నిల్వ చేయబడిన మీ పరిచయాల గురించి డేటాను సవరించడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి పరిచయ డేటాను తొలగించడానికి యాప్లను అనుమతిస్తుంది."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"మీ టాబ్లెట్లో నిల్వ చేసి ఉన్న కాంటాక్ట్లకు సంబంధించిన డేటాను సవరించడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి, కాంటాక్ట్ డేటాను తొలగించడానికి యాప్లను అనుమతిస్తుంది."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"మీ Android TV పరికరంలో నిల్వ చేసి ఉన్న కాంటాక్ట్లకు సంబంధించిన డేటాను సవరించడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి, కాంటాక్ట్ డేటాను తొలగించడానికి యాప్లను అనుమతిస్తుంది."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"మీ ఫోన్లో నిల్వ చేసి ఉన్న కాంటాక్ట్లకు సంబంధించిన డేటాను సవరించడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి, కాంటాక్ట్ డేటాను తొలగించడానికి యాప్లను అనుమతిస్తుంది."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"కాల్ లాగ్ను చదవడం"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"ఈ యాప్ మీ కాల్ చరిత్రను చదవగలదు."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"కాల్ లాగ్ను వ్రాయడం"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"అదనపు స్థాన ప్రదాత ఆదేశాలను యాక్సెస్ చేయడం"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"అదనపు స్థాన ప్రదాత ఆదేశాలను యాక్సెస్ చేయడానికి యాప్ను అనుమతిస్తుంది. ఇది GPS లేదా ఇతర స్థాన మూలాల నిర్వహణలో యాప్ ప్రమేయం ఉండేలా అనుమతించవచ్చు."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"స్క్రీన్పై ఉన్నప్పుడు మాత్రమే ఖచ్చితమైన స్థానాన్ని యాక్సెస్ చేయండి"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"ఈ యాప్ స్క్రీన్పై ఉన్నప్పుడు మాత్రమే అది మీ ఖచ్చితమైన స్థానాన్ని తెలుసుకోగలదు. యాప్ ఉపయోగించడానికి మీ ఫోన్లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి. ఇది బ్యాటరీ వినియోగాన్ని పెంచవచ్చు."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"స్క్రీన్పై ఉన్నప్పుడు మాత్రమే సమీప స్థానాన్ని (నెట్వర్క్-ఆధారిత) యాక్సెస్ చేయండి"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"ఈ యాప్ సెల్ టవర్లు మరియు Wi-Fi నెట్వర్క్ల వంటి నెట్వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు, కానీ యాప్ తెరపై ఉన్నప్పుడు మాత్రమే. యాప్ ఉపయోగించడానికి మీ టాబ్లెట్లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"ఈ యాప్ సెల్ టవర్లు మరియు Wi-Fi నెట్వర్క్ల వంటి నెట్వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు, కానీ యాప్ తెరపై ఉన్నప్పుడు మాత్రమే. యాప్ ఉపయోగించడానికి మీ Android TV పరికరంలో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అవి అందుబాటులో ఉండాలి."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"ఈ యాప్ సెల్ టవర్లు మరియు Wi-Fi నెట్వర్క్ల వంటి నెట్వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు, కానీ యాప్ తెరపై ఉన్నప్పుడు మాత్రమే. యాప్ ఉపయోగించడానికి మీ ఫోన్లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"ఈ యాప్ స్క్రీన్పై ఉన్నప్పుడు మాత్రమే మీ ఖచ్చితమైన లొకేషన్ను తెలుసుకోగలదు. మీ పరికరంలో లొకేషన్ సర్వీస్లు అందుబాటులో ఉండి, అవి తప్పనిసరిగా ఆన్ చేసి ఉంటేనే, యాప్ వాటిని ఉపయోగించగలదు. దీని వలన బ్యాటరీ వినియోగం పెరగవచ్చు."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"స్క్రీన్పై ఉన్నప్పుడు మాత్రమే సుమారు లొకేషన్ను యాక్సెస్ చేయండి"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"ఈ యాప్ స్క్రీన్పై ఉన్నప్పుడు మాత్రమే మీ సుమారు లొకేషన్ను తెలుసుకోగలదు. మీ పరికరంలో లొకేషన్ సర్వీస్లు అందుబాటులో ఉండి, అవి తప్పనిసరిగా ఆన్ చేసి ఉంటేనే, యాప్ వాటిని ఉపయోగించగలదు."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"నేపథ్యంలో స్థానాన్ని యాక్సెస్ చేయి"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"సుమారుగా లేదా ఖచ్చితమైన స్థాన యాక్సెస్తో పాటు అదనందా ఇది మంజూరు చేయబడితే, యాప్ నేపథ్యంలో నడుస్తున్నప్పుడు స్థానాన్ని యాక్సెస్ చేయగలదు."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"స్క్రీన్పై ఉన్నప్పుడు లొకేషన్ను యాక్సెస్ చేయడంతో పాటు ఈ యాప్ బ్యాక్గ్రౌండ్లో నడుస్తున్నప్పుడు కూడా లొకేషన్ను యాక్సెస్ చేయగలదు."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"మీ ఆడియో సెట్టింగ్లను మార్చడం"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"వాల్యూమ్ మరియు అవుట్పుట్ కోసం ఉపయోగించాల్సిన స్పీకర్ వంటి సార్వజనీన ఆడియో సెట్టింగ్లను సవరించడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ఆడియోను రికార్డ్ చేయడం"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"టాబ్లెట్లో బ్లూటూత్ యొక్క కాన్ఫిగరేషన్ను వీక్షించడానికి మరియు జత చేయబడిన పరికరాలతో కనెక్షన్లను ఏర్పాటు చేయడానికి మరియు ఆమోదించడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"మీ Android TV పరికరం బ్లూటూత్ యొక్క కాన్ఫిగరేషన్ను చూడడానికి, జత చేయబడిన పరికరాలతో కనెక్షన్లను ఏర్పాటు చేయడానికి మరియు ఆమోదించడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ఫోన్లో బ్లూటూత్ యొక్క కాన్ఫిగరేషన్ను వీక్షించడానికి మరియు జత చేయబడిన పరికరాలతో కనెక్షన్లను ఏర్పాటు చేయడానికి మరియు ఆమోదించడానికి యాప్ను అనుమతిస్తుంది."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"సమీప క్షేత్ర కమ్యూనికేషన్ను నియంత్రించడం"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"సమీప ఫీల్డ్ కమ్యూనికేషన్ (NFC) ట్యాగ్లు, కార్డులు మరియు రీడర్లతో కమ్యూనికేట్ చేయడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"మీ స్క్రీన్ లాక్ను నిలిపివేయడం"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"ఫైల్లను వీక్షించడానికి నొక్కండి"</string>
<string name="pin_target" msgid="8036028973110156895">"పిన్ చేయి"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"అన్పిన్ చేయి"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"యాప్ సమాచారం"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"డెమోను ప్రారంభిస్తోంది..."</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"ఈ అంశాలను "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"లో అప్డేట్ చేయాలా: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> మరియు <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"సేవ్ చేయి"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"వద్దు, ధన్యవాదాలు"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"ఇప్పుడు కాదు"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"ఎప్పుడూ వద్దు"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"అప్డేట్ చేయి"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"కొనసాగించు"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"పాస్వర్డ్"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"స్క్రీన్ విభజనను టోగుల్ చేయి"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"స్క్రీన్ను లాక్ చేయి"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"స్క్రీన్షాట్"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"పాప్-అప్ విండోలో <xliff:g id="APP_NAME">%1$s</xliff:g> యాప్ ఉంది."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> క్యాప్షన్ బార్."</string>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index bc4b79e..cfdf4b5 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"แอปผู้ดูแลระบบโปรไฟล์งานไม่มีอยู่หรือเสียหาย ระบบจึงทำการลบโปรไฟล์งานและข้อมูลที่เกี่ยวข้องของคุณออก โปรดติดต่อผู้ดูแลระบบเพื่อรับความช่วยเหลือ"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"โปรไฟล์งานของคุณไม่สามารถใช้ในอุปกรณ์นี้อีกต่อไป"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ลองป้อนรหัสผ่านหลายครั้งเกินไป"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"ผู้ดูแลระบบปล่อยอุปกรณ์ให้คุณใช้งานส่วนตัว"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"อุปกรณ์มีการจัดการ"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"องค์กรของคุณจัดการอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย แตะเพื่อดูรายละเอียด"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"ระบบจะลบข้อมูลในอุปกรณ์ของคุณ"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"อนุญาตให้แอปส่งการแพร่ภาพแบบติดหนึบ ซึ่งจะยังคงอยู่หลังจากการแพร่ภาพจบไปแล้ว การใช้งานมากเกินไปอาจทำให้อุปกรณ์ Android TV ทำงานช้าลงหรือไม่เสถียรเนื่องจากมีการใช้หน่วยความจำมากเกิน"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"อนุญาตให้แอปพลิเคชันส่งการกระจายข้อมูลที่ติดหนึบ ซึ่งจะยังคงอยู่หลังจากการกระจายข้อมูลจบไปแล้ว การใช้งานมากเกินไปอาจทำให้โทรศัพท์ทำงานช้าลงหรือไม่เสถียรโดยการใช้หน่วยความจำมากเกินไป"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"อ่านผู้ติดต่อของคุณ"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"อนุญาตให้แอปพลิเคชันอ่านข้อมูลผู้ติดต่อที่จัดเก็บไว้ในแท็บเล็ต ซึ่งรวมถึงความถี่ในการโทร ส่งอีเมล หรือการติดต่อด้วยวิธีอื่นๆ กับบุคคลใดบุคคลหนึ่ง การอนุญาตนี้ทำให้แอปพลิเคชันสามารถบันทึกข้อมูลผู้ติดต่อของคุณ และแอปพลิเคชันที่เป็นอันตรายอาจแชร์ข้อมูลผู้ติดต่อโดยไม่แจ้งให้คุณทราบ"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"อนุญาตให้แอปอ่านข้อมูลเกี่ยวกับรายชื่อติดต่อที่จัดเก็บไว้ในอุปกรณ์ Android TV รวมถึงความถี่ที่คุณโทรหา ส่งอีเมล หรือสื่อสารในรูปแบบอื่นกับรายชื่อติดต่อแต่ละคน สิทธิ์นี้ทำให้แอปบันทึกข้อมูลรายชื่อติดต่อได้และแอปที่เป็นอันตรายอาจแชร์ข้อมูลรายชื่อติดต่อโดยไม่แจ้งให้คุณทราบ"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"อนุญาตให้แอปพลิเคชันอ่านข้อมูลผู้ติดต่อที่จัดเก็บไว้ในโทรศัพท์ ซึ่งรวมถึงความถี่ในการโทร ส่งอีเมล หรือการติดต่อด้วยวิธีอื่นๆ กับบุคคลใดบุคคลหนึ่ง การอนุญาตนี้ทำให้แอปพลิเคชันสามารถบันทึกข้อมูลผู้ติดต่อของคุณ และแอปพลิเคชันที่เป็นอันตรายอาจแชร์ข้อมูลผู้ติดต่อโดยไม่แจ้งให้คุณทราบ"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"อนุญาตให้แอปอ่านข้อมูลเกี่ยวกับรายชื่อติดต่อที่จัดเก็บไว้ในแท็บเล็ต แอปจะมีสิทธิ์เข้าถึงบัญชีในแท็บเล็ตที่มีการสร้างรายชื่อติดต่อด้วย โดยอาจรวมถึงบัญชีซึ่งแอปที่คุณได้ติดตั้งไว้สร้างขึ้น สิทธิ์นี้ทำให้แอปบันทึกข้อมูลรายชื่อติดต่อได้และแอปที่เป็นอันตรายอาจแชร์ข้อมูลรายชื่อติดต่อโดยไม่แจ้งให้คุณทราบ"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"อนุญาตให้แอปอ่านข้อมูลเกี่ยวกับรายชื่อติดต่อที่จัดเก็บไว้ในอุปกรณ์ Android TV แอปจะมีสิทธิ์เข้าถึงบัญชีในอุปกรณ์ Android TV ที่มีการสร้างรายชื่อติดต่อด้วย โดยอาจรวมถึงบัญชีซึ่งแอปที่คุณได้ติดตั้งไว้สร้างขึ้น สิทธิ์นี้ทำให้แอปบันทึกข้อมูลรายชื่อติดต่อได้และแอปที่เป็นอันตรายอาจแชร์ข้อมูลรายชื่อติดต่อโดยไม่แจ้งให้คุณทราบ"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"อนุญาตให้แอปอ่านข้อมูลเกี่ยวกับรายชื่อติดต่อที่จัดเก็บไว้ในโทรศัพท์ แอปจะมีสิทธิ์เข้าถึงบัญชีในโทรศัพท์ที่มีการสร้างรายชื่อติดต่อด้วย โดยอาจรวมถึงบัญชีซึ่งแอปที่คุณได้ติดตั้งไว้สร้างขึ้น สิทธิ์นี้ทำให้แอปบันทึกข้อมูลรายชื่อติดต่อได้และแอปที่เป็นอันตรายอาจแชร์ข้อมูลรายชื่อติดต่อโดยไม่แจ้งให้คุณทราบ"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"แก้ไขผู้ติดต่อของคุณ"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงข้อมูลผู้ติดต่อที่จัดเก็บไว้ในแท็บเล็ต ซึ่งรวมถึงความถี่ในการโทร ส่งอีเมล หรือการติดต่อด้วยวิธีอื่นๆ กับบุคคลใดบุคคลหนึ่ง การอนุญาตนี้ทำให้แอปพลิเคชันสามารถลบข้อมูลผู้ติดต่อได้"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"อนุญาตให้แอปแก้ไขข้อมูลเกี่ยวกับรายชื่อติดต่อที่จัดเก็บไว้ในอุปกรณ์ Android TV รวมถึงความถี่ที่คุณโทรหา ส่งอีเมล หรือสื่อสารในรูปแบบอื่นกับรายชื่อติดต่อแต่ละคน สิทธิ์นี้ทำให้แอปลบข้อมูลรายชื่อติดต่อได้"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงข้อมูลผู้ติดต่อที่จัดเก็บไว้ในโทรศัพท์ ซึ่งรวมถึงความถี่ในการโทร ส่งอีเมล หรือการติดต่อด้วยวิธีอื่นๆ กับบุคคลใดบุคคลหนึ่ง การอนุญาตนี้ทำให้แอปพลิเคชันสามารถลบข้อมูลผู้ติดต่อได้"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"อนุญาตให้แอปแก้ไขข้อมูลเกี่ยวกับรายชื่อติดต่อที่จัดเก็บไว้ในแท็บเล็ต สิทธิ์นี้ทำให้แอปลบข้อมูลรายชื่อติดต่อได้"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"อนุญาตให้แอปแก้ไขข้อมูลเกี่ยวกับรายชื่อติดต่อที่จัดเก็บไว้ในอุปกรณ์ Android TV สิทธิ์นี้ทำให้แอปลบข้อมูลรายชื่อติดต่อได้"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"อนุญาตให้แอปแก้ไขข้อมูลเกี่ยวกับรายชื่อติดต่อที่จัดเก็บไว้ในโทรศัพท์ สิทธิ์นี้ทำให้แอปลบข้อมูลรายชื่อติดต่อได้"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"อ่านประวัติการโทร"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"แอปนี้สามารถอ่านประวัติการโทรของคุณได้"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"เขียนประวัติการโทร"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"เข้าถึงคำสั่งของโปรแกรมแจ้งตำแหน่งพิเศษ"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"อนุญาตให้แอปเข้าถึงคำสั่งของผู้ให้บริการตำแหน่งเพิ่มเติม ซึ่งอาจทำให้แอปสามารถแทรกแซงการทำงานของ GPS หรือต้นทางของตำแหน่งอื่นๆ ได้"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"เข้าถึงตำแหน่งที่แม่นยำเมื่ออยู่เบื้องหน้าเท่านั้น"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"แอปนี้รับตำแหน่งที่แม่นยำของคุณได้เมื่อทำงานอยู่เบื้องหน้าเท่านั้น แอปจะใช้บริการตำแหน่งเหล่านี้ได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในโทรศัพท์ของคุณ ซึ่งอาจทำให้มีการใช้แบตเตอรี่มากขึ้น"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"เข้าถึงตำแหน่งโดยประมาณ (อิงตามเครือข่าย) เมื่อทำงานอยู่เบื้องหน้าเท่านั้น"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"แอปนี้รับตำแหน่งของคุณโดยอิงตามแหล่งที่มาของเครือข่าย เช่น เสาส่งสัญญาณมือถือและเครือข่าย Wi-Fi เมื่อทำงานอยู่เบื้องหน้าเท่านั้น แอปจะใช้บริการตำแหน่งเหล่านี้ได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในแท็บเล็ตของคุณ"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"แอปนี้รับตำแหน่งของคุณได้โดยอิงตามแหล่งที่มาของเครือข่าย เช่น เสาส่งสัญญาณมือถือและเครือข่าย Wi-Fi เมื่อแอปทำงานอยู่เบื้องหน้าเท่านั้น แอปจะใช้บริการตำแหน่งเหล่านี้ได้ต่อเมื่อคุณเปิดใช้งานและบริการพร้อมใช้งานในอุปกรณ์ Android TV ของคุณ"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"แอปนี้รับตำแหน่งของคุณโดยอิงตามแหล่งที่มาของเครือข่าย เช่น เสาส่งสัญญาณมือถือและเครือข่าย Wi-Fi เมื่อทำงานอยู่เบื้องหน้าเท่านั้น แอปจะใช้บริการตำแหน่งเหล่านี้ได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในโทรศัพท์ของคุณ"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"แอปนี้เข้าถึงตำแหน่งที่แม่นยำของคุณได้เมื่อทำงานอยู่เบื้องหน้าเท่านั้น แอปจะใช้บริการตำแหน่งได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในอุปกรณ์ของคุณ ซึ่งอาจทำให้มีการใช้แบตเตอรี่มากขึ้น"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"เข้าถึงตำแหน่งโดยประมาณเมื่ออยู่เบื้องหน้าเท่านั้น"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"แอปนี้เข้าถึงตำแหน่งโดยประมาณของคุณได้เมื่อทำงานอยู่เบื้องหน้าเท่านั้น แอปจะใช้บริการตำแหน่งได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในอุปกรณ์ของคุณ"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"เข้าถึงตำแหน่งในเบื้องหลัง"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"หากได้รับสิทธิ์นี้เพิ่มจากการเข้าถึงตำแหน่งโดยประมาณหรือตำแหน่งที่แม่นยำ แอปจะมีสิทธิ์เข้าถึงตำแหน่งระหว่างที่ทำงานในเบื้องหลังได้"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"แอปนี้เข้าถึงตำแหน่งในขณะที่ทำงานอยู่เบื้องหลังได้ด้วย นอกเหนือจากการเข้าถึงตำแหน่งเมื่อทำงานอยู่เบื้องหน้า"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"เปลี่ยนการตั้งค่าเสียงของคุณ"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"อนุญาตให้แอปพลิเคชันปรับเปลี่ยนการตั้งค่าเสียงทั้งหมดได้ เช่น ระดับเสียงและลำโพงที่จะใช้งาน"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"บันทึกเสียง"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"อนุญาตให้แอปพลิเคชันดูการกำหนดค่าบลูทูธของแท็บเล็ต ตลอดจนเชื่อมต่อและยอมรับการเชื่อมต่อกับอุปกรณ์ที่จับคู่ไว้"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"อนุญาตให้แอปดูการกำหนดค่าบลูทูธในอุปกรณ์ Android TV ตลอดจนเชื่อมต่อและยอมรับการเชื่อมต่อกับอุปกรณ์ที่จับคู่ไว้"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"อนุญาตให้แอปพลิเคชันดูการกำหนดค่าบลูทูธของโทรศัพท์ ตลอดจนเชื่อมต่อและยอมรับการเชื่อมต่อกับอุปกรณ์ที่จับคู่ไว้"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"ควบคุม Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"อนุญาตให้แอปพลิเคชันสื่อสารกับแท็ก Near Field Communication (NFC) การ์ด และโปรแกรมอ่าน"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"ปิดใช้งานการล็อกหน้าจอของคุณ"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"เชื่อมต่อ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> แล้ว"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"แตะเพื่อดูไฟล์"</string>
<string name="pin_target" msgid="8036028973110156895">"ปักหมุด"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"เลิกปักหมุด"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"ข้อมูลแอป"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"กำลังเริ่มการสาธิต…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"อัปเดตข้อมูล<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> และ<xliff:g id="TYPE_2">%3$s</xliff:g> ใน "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ไหม"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"บันทึก"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"ไม่เป็นไร"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"ไว้ทีหลัง"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"ไม่เลย"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"อัปเดต"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"ทำต่อ"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"รหัสผ่าน"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"เปิด/ปิดการแบ่งหน้าจอ"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"หน้าจอล็อก"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ภาพหน้าจอ"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"แอป <xliff:g id="APP_NAME">%1$s</xliff:g> ในหน้าต่างป๊อปอัป"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"แถบคำบรรยาย <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index b24e95a..cf4e33d 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Nawawala o nasira ang admin app ng profile sa trabaho. Dahil dito, na-delete ang profile mo sa trabaho at nauugnay na data. Makipag-ugnayan sa iyong admin para sa tulong."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Hindi na available sa device na ito ang iyong profile sa trabaho"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Masyadong maraming pagsubok sa password"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Inalis ng admin ang device para sa personal na paggamit"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Pinamamahalaan ang device"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Pinamamahalaan ng iyong organisasyon ang device na ito, at maaari nitong subaybayan ang trapiko sa network. I-tap para sa mga detalye."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Buburahin ang iyong device"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Nagbibigay-daan sa app na magpadala ng mga sticky broadcast, na nananatili pagkatapos ng broadcast. Posibleng bumagal o maging hindi stable ang iyong Android TV device dahil sa sobra-sobrang paggamit sa pamamagitan ng pagtulak dito na gumamit ng masyadong maraming memory."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Pinapayagan ang app na magpadala ng mga sticky na pag-broadcast, na nananatili pagkatapos ng pag-broadcast. Maaaring pabagalin o gawing hindi matatag ng labis na paggamit ang telepono sa pamamagitan ng pagdulot dito na gumamit ng masyadong maraming memory."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"basahin ang iyong mga contact"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Pinapayagan ang app na magbasa ng data tungkol sa mga contact na naka-imbak sa iyong tablet, kabilang ang dalas kung kailan ka tumawag, nag-email, o nakipag-ugnayan sa iba pang mga paraan sa mga tukoy na indibidwal. Pinapayagan ng pahintulot na ito ang apps na i-save ang data ng iyong contact, at maaaring magbahagi ang nakakahamak na apps ng data ng contact nang hindi mo nalalaman."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Nagbibigay-daan sa app na basahin ang data tungkol sa iyong mga contact na naka-store sa Android TV device mo, kasama ang dalas ng iyong pagtawag, pag-email, o pakikipag-ugnayan sa iba pang paraan sa mga partikular na indibidwal. Nagbibigay-daan sa mga app ang pahintulot na ito na i-save ang iyong data ng contact at posibleng magbahagi ng data ng contact ang mga nakakapinsalang app nang hindi mo nalalaman."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Pinapayagan ang app na magbasa ng data tungkol sa mga contact na naka-imbak sa iyong telepono, kabilang ang dalas kung kailan ka tumawag, nag-email, o nakipag-ugnayan sa iba pang mga paraan sa mga tukoy na indibidwal. Pinapayagan ng pahintulot na ito ang apps na i-save ang data ng iyong contact, at maaaring magbahagi ang nakakahamak na apps ng data ng contact nang hindi mo nalalaman."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Nagbibigay-daan sa app na magbasa ng data tungkol sa iyong mga contact na naka-store sa tablet mo. Magkakaroon din ang mga app ng access sa mga account sa iyong tablet na gumawa ng mga contact. Puwedeng kasama rito ang mga account na ginawa ng mga na-install mong app. Nagbibigay-daan ang pahintulot na ito sa mga app na i-save ang iyong data ng contact, at puwedeng magbahagi ng data ng contact ang mga nakakahamak na app nang hindi mo alam."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Nagbibigay-daan sa app na magbasa ng data tungkol sa iyong mga contact na naka-store sa Android TV device mo. Magkakaroon din ang mga app ng access sa mga account sa iyong Android TV device na gumawa ng mga contact. Puwedeng kasama rito ang mga account na ginawa ng mga na-install mong app. Nagbibigay-daan ang pahintulot na ito sa mga app na i-save ang iyong data ng contact, at puwedeng magbahagi ng data ng contact ang mga nakakahamak na app nang hindi mo alam."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Nagbibigay-daan sa app na magbasa ng data tungkol sa iyong mga contact na naka-store sa telepono mo. Magkakaroon din ang mga app ng access sa mga account sa iyong telepono na gumawa ng mga contact. Puwedeng kasama rito ang mga account na ginawa ng mga na-install mong app. Nagbibigay-daan ang pahintulot na ito sa mga app na i-save ang iyong data ng contact, at puwedeng magbahagi ng data ng contact ang mga nakakahamak na app nang hindi mo alam."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"baguhin ang iyong mga contact"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Pinapayagan ang app na baguhin ang data tungkol sa iyong mga contact na naka-imbak sa iyong tablet, kabilang ang dalas kung kailan ka tumawag, nag-email, o nakipag-ugnayan sa iba pang mga paraan sa mga tukoy na contact. Pinapayagan ng pahintulot na ito ang apps na magtanggal ng data ng contact."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Nagbibigay-daan sa app na baguhin ang data tungkol sa iyong mga contact na naka-store sa iyong Android TV device, kasama ang dalas ng iyong pagtawag, pag-email, o pakikipag-ugnayan sa iba pang paraan sa mga partikular na contact. Nagbibigay-daan ang pahintulot na ito sa mga app na mag-delete ng data ng contact."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Pinapayagan ang app na baguhin ang data tungkol sa iyong mga contact na naka-imbak sa iyong telepono, kabilang ang dalas kung kailan ka tumawag, nag-email, o nakipag-ugnayan sa iba pang mga paraan sa mga tukoy na contact. Pinapayagan ng pahintulot na ito ang apps na magtanggal ng data ng contact."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Nagbibigay-daan sa app na baguhin ang data tungkol sa iyong mga contact na naka-store sa tablet mo. Nagbibigay-daan ang pahintulot na ito sa mga app na mag-delete ng data ng contact."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Nagbibigay-daan sa app na baguhin ang data tungkol sa iyong mga contact na naka-store sa Android TV device mo. Nagbibigay-daan ang pahintulot na ito sa mga app na mag-delete ng data ng contact."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Nagbibigay-daan sa app na baguhin ang data tungkol sa iyong mga contact na naka-store sa telepono mo. Nagbibigay-daan ang pahintulot na ito sa mga app na mag-delete ng data ng contact."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"basahin ang log ng tawag"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Mababasa ng app na ito ang iyong history ng tawag."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"isulat ang log ng tawag"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"i-access ang mga dagdag na command ng provider ng lokasyon"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Nagbibigay-daan sa app na mag-access ng mga karagdagang command ng provider ng lokasyon. Maaari nitong bigyang-daan ang app na gambalain ang pagpapatakbo ng GPS o ng iba pang mga pinagmulan ng lokasyon."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"i-access lang ang tumpak na lokasyon sa foreground"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Makukuha lang ng app na ito ang iyong eksaktong lokasyon kapag nasa foreground ito. Ang mga serbisyo ng lokasyon na ito ay dapat naka-on at available sa iyong telepono para magamit ng app ang mga ito. Maaaring lumakas ang pagkonsumo ng baterya dahil dito."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"i-access lang ang tinatantiyang lokasyon (batay sa network) sa foreground"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Makukuha ng app na ito ang iyong lokasyon batay sa mga source ng network gaya ng mga cell tower at Wi-Fi network ngunit magagawa lang ito kapag nasa foreground ang app. Ang mga serbisyo ng lokasyon na ito ay dapat naka-on at available sa iyong tablet para magamit ng app ang mga ito."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Makukuha ng app na ito ang iyong lokasyon batay sa mga source ng network gaya ng mga cell site at Wi-Fi network, pero magagawa lang ito kapag nasa foreground ang app. Naka-on at available dapat ang mga serbisyo ng lokasyon na ito sa iyong Android TV device para magamit ng app ang mga ito."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Makukuha ng app na ito ang iyong lokasyon batay sa mga source ng network gaya ng mga cell tower at Wi-Fi network, ngunit magagawa lang ito kapag nasa foreground ang app. Ang mga serbisyo ng lokasyon na ito ay dapat naka-on at available sa iyong telepono para magamit ng app ang mga ito."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Makukuha lang ng app na ito ang iyong eksaktong lokasyon kapag nasa foreground ito. Naka-on at available dapat ang mga serbisyo ng lokasyon sa iyong device para magamit ng app ang mga ito. Posibleng lumakas ang pagkonsumo ng baterya dahil dito."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"i-access lang ang tinatantyang lokasyon sa foreground"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Makukuha lang ng app na ito ang iyong tinatantyang lokasyon kapag nasa foreground ito. Naka-on at available dapat ang mga serbisyo ng lokasyon sa iyong device para magamit ng app ang mga ito."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"i-access ang lokasyon sa background"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Kung papahintulutan ito bukod pa sa pag-access sa tinataya o tumpak na lokasyon, maaaring i-access ng app ang lokasyon habang tumatakbo sa background."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Puwedeng i-access ng app na ito ang lokasyon habang tumatakbo sa background, bilang karagdagan sa access sa lokasyon sa foreground."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"baguhin ang mga setting ng iyong audio"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Pinapayagan ang app na baguhin ang mga pandaigdigang setting ng audio gaya ng volume at kung aling speaker ang ginagamit para sa output."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"mag-record ng audio"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Pinapayagan ang app na tingnan ang configuration ng Bluetooth sa tablet, at na gumawa at tumanggap ng mga koneksyong may mga nakapares na device."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Nagbibigay-daan sa app na tingnan ang configuration ng Bluetooth sa iyong Android TV device, and at gumawa at tumanggap ng mga koneksyon sa mga nakapares na device."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Pinapayagan ang app na tingnan ang configuration ng Bluetooth sa telepono, at na gumawa at tumanggap ng mga koneksyong may mga nakapares na device."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolin ang Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Pinapayagan ang app na makipag-ugnay sa Near Field Communication (NFC) na mga tag, card, at reader."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"i-disable ang iyong screen lock"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Nakakonekta sa <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"I-tap upang makita ang mga file"</string>
<string name="pin_target" msgid="8036028973110156895">"I-pin"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"I-unpin"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Impormasyon ng app"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Sinisimulan ang demo…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"I-update ang mga item na ito sa "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, at <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"I-save"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Hindi, salamat na lang"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Hindi ngayon"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Hindi Kailanman"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"I-update"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Magpatuloy"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"password"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"I-toggle ang Split Screen"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> app sa Pop-up na window."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Caption bar ng <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 326ace9..55cdc8d 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"İş profili yönetici uygulaması eksik ya da bozuk. Bunun sonucunda iş profiliniz ve ilgili veriler silindi. Yardım almak için yöneticiniz ile iletişim kurun."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"İş profiliniz arık bu cihazda kullanılamıyor"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Çok fazla şifre denemesi yapıldı"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Yönetici, cihazı kişisel kullanım için serbest bıraktı"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Cihaz yönetiliyor"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Kuruluşunuz bu cihazı yönetmekte olup ağ trafiğini izleyebilir. Ayrıntılar için dokunun."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Cihazınız silinecek"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Uygulamaya, yayın bittikten sonra da kalan sabit yayınlar gönderme izni verir. Aşırı kullanılması çok fazla bellek harcanmasına neden olarak Android TV cihazınızı yavaşlatabilir veya dengesiz hale getirebilir."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Uygulamaya, yayın bittikten sonra da kalan sabit yayınlar gönderme izni verir. Aşırı kullanılması çok fazla bellek harcanmasına neden olarak telefonunu yavaşlatabilir veya dengesiz hale getirebilir."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"kişilerinizi okuma"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Uygulamaya tabletinizde depolanan kişilerinizle ilgili verileri okuma izni verir. Bu verilere belirli kişilerle ne sıklıkta çağrı, e-posta veya diğer yöntemlerle iletişim kurduğunuz bilgisi dahildir. Bu izin, uygulamanın kişi verilerinizi kaydetmesine olanak sağlar ve kötü amaçlı uygulamalar kişi verilerini haberiniz olmadan paylaşabilir."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Uygulamaya Android TV cihazınızda depolanan kişilerinizle ilgili verileri okuma izni verir. Bu verilere belirli kişilerle ne sıklıkta çağrı, e-posta veya diğer yöntemlerle iletişim kurduğunuz bilgisi dahildir. Bu izin, uygulamanın kişi verilerinizi kaydetmesine olanak sağlar ve kötü amaçlı uygulamalar kişi verilerini sizden habersiz paylaşabilir."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Uygulamaya telefonunuzda depolanan kişilerinizle ilgili verileri okuma izni verir. Bu verilere belirli kişilerle ne sıklıkta çağrı, e-posta veya diğer yöntemlerle iletişim kurduğunuz bilgisi dahildir. Bu izin, uygulamanın kişi verilerinizi kaydetmesine olanak sağlar ve kötü amaçlı uygulamalar kişi verilerini sizden habersiz paylaşabilir."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Uygulamaya tabletinizde kayıtlı kişileriniz ile ilgili verileri okuma izni verir. Uygulamalar ayrıca tabletinizde kişi oluşturan hesaplara da erişebilir. Bu, yüklediğiniz uygulamalar tarafından oluşturulan hesapları içerebilir. Bu izin, uygulamanın kişi verilerinizi kaydetmesine olanak sağlar ve kötü amaçlı uygulamalar kişi verilerini sizden habersiz paylaşabilir."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Uygulamaya Android TV cihazınızda depolanan kişilerinizle ilgili verileri okuma izni verir. Uygulamalar ayrıca Android TV cihazınızda kişi oluşturan hesaplara da erişebilir. Bu, yüklediğiniz uygulamalar tarafından oluşturulan hesapları içerebilir. Bu izin, uygulamanın kişi verilerinizi kaydetmesine olanak sağlar ve kötü amaçlı uygulamalar kişi verilerini sizden habersiz paylaşabilir."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Uygulamaya telefonunuzda depolanan kişilerinizle ilgili verileri okuma izni verir. Uygulamalar ayrıca telefonunuzda kişi oluşturan hesaplara da erişebilir. Bu, yüklediğiniz uygulamalar tarafından oluşturulan hesapları içerebilir. Bu izin, uygulamanın kişi verilerinizi kaydetmesine olanak sağlar ve kötü amaçlı uygulamalar kişi verilerini sizden habersiz paylaşabilir."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"kişilerinizi değiştirme"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Uygulamaya tabletinizde depolanan kişilerinizle ilgili verileri değiştirme izni verir. Bu verilere belirli kişilerle ne sıklıkta çağrı, e-posta veya diğer yöntemlerle iletişim kurduğunuz bilgisi dahildir. Bu izin, uygulamanın kişi verilerinizi silmesine olanak sağlar."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Uygulamaya Android TV cihazınızda depolanan kişilerinizle ilgili verileri değiştirme izni verir. Bu verilere belirli kişilerle ne sıklıkta çağrı, e-posta veya diğer yöntemlerle iletişim kurduğunuz bilgisi dahildir. Bu izin, uygulamanın kişi verilerinizi silmesine olanak sağlar."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Uygulamaya telefonunuzda depolanan kişilerinizle ilgili verileri değiştirme izni verir. Bu verilere belirli kişilerle ne sıklıkta çağrı, e-posta veya diğer yöntemlerle iletişim kurduğunuz bilgisi dahildir. Bu izin, uygulamanın kişi verilerinizi silmesine olanak sağlar."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Uygulamaya tabletinizde kayıtlı kişileriniz ile ilgili verileri değiştirme izni verir. Bu izin, uygulamanın kişi verilerinizi silmesine olanak sağlar."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Uygulamaya Android TV cihazınızda kayıtlı kişileriniz ile ilgili verileri değiştirme izni verir. Bu izin, uygulamanın kişi verilerinizi silmesine olanak sağlar."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Uygulamaya telefonunuzda kayıtlı kişileriniz ile ilgili verileri değiştirme izni verir. Bu izin, uygulamanın kişi verilerinizi silmesine olanak sağlar."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"çağrı günlüğünü oku"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Bu uygulama, çağrı geçmişinizi okuyabilir."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"çağrı günlüğüne yaz"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"ek konum sağlayıcı komutlarına eriş"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Uygulamanın, ekstra konum sağlayıcı komutlarına erişmesine izin verir. Bu izin, uygulamanın GPS veya diğer konum kaynaklarının çalışmasını kesmesine olanak sağlayabilir."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"yalnızca ön planda kesin konuma erişme"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Bu uygulama yalnızca ön plandayken kesin konumunuzu alabilir. Uygulamanın bu hizmetleri kullanabilmesi için telefonunuzda bu konum hizmetleri açık ve kullanılabilir olmalıdır. Bu, pil tüketimini artırabilir."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"yalnızca ön planda yaklaşık konuma (ağa dayalı) erişme"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Bu uygulama baz istasyonları ve kablosuz ağlar gibi ağ kaynaklarını dikkate alarak konumunuzu bulabilir, ancak bunu yalnızca ön plandayken yapabilir. Uygulamanın bu hizmetleri kullanabilmesi için tabletinizde bu konum hizmetleri açık ve kullanılabilir olmalıdır."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Bu uygulama baz istasyonları ve kablosuz ağlar gibi ağ kaynaklarını dikkate alarak konumunuzu bulabilir, ancak bunu yalnızca ön plandayken yapabilir. Uygulamanın bu hizmetleri kullanabilmesi için Android TV cihazınızda bu konum hizmetleri açık ve kullanılabilir olmalıdır."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Bu uygulama baz istasyonları ve kablosuz ağlar gibi ağ kaynaklarını dikkate alarak konumunuzu bulabilir, ancak bunu yalnızca ön plandayken yapabilir. Uygulamanın bu hizmetleri kullanabilmesi için telefonunuzda bu konum hizmetleri açık ve kullanılabilir olmalıdır."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Bu uygulama yalnızca ön plandayken kesin konumunuzu alabilir. Uygulamanın bu hizmetleri kullanabilmesi için telefonunuzda bu konum hizmetleri açık ve kullanılabilir olmalıdır. Bu, pil tüketimini artırabilir."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"yalnızca ön planda yaklaşık konuma erişme"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Bu uygulama, yalnızca ön planda çalışırken yaklaşık konum bilginizi alabilir. Uygulamanın kullanabilmesi için konum hizmetlerinin açılması ve cihazınızda kullanılabilir olması gerekir."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"konum bilgisine arka planda eriş"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Bu izin, yaklaşık veya tam konum erişimine ek olarak verilirse uygulama, konum bilgisine arka planda çalışırken erişebilir."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Bu uygulama ön plan konum erişimine ek olarak konum bilgisine arka planda çalışırken erişebilir."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"ses ayarlarınızı değiştirin"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Uygulamaya ses düzeyi ve ses çıkışı için kullanılan hoparlör gibi genel ses ayarlarını değiştirme izni verir."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ses kaydet"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Uygulamaya, tabletteki Bluetooth yapılandırmasını görüntüleme, eşlenmiş cihazlarla bağlantı yapma ve bu tür bağlantıları kabul etme izni verir."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Uygulamaya, Android TV cihazınızdaki Bluetooth yapılandırmasını görüntüleme, eşleştirilmiş cihazlarla bağlantı yapma ve bu tür bağlantıları kabul etme izni verir."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Uygulamaya, telefondaki Bluetooth yapılandırmasını görüntüleme, eşlenmiş cihazlarla bağlantı yapma ve bu tür bağlantıları kabul etme izni verir."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"Yakın Alan İletişimini denetle"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Uygulamaya, Near Field Communication (NFC) etiketleri, kartlar ve okuyucular ile iletişim kurma izni verir."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"ekran kilidimi devre dışı bırak"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> cihazına bağlandı"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Dosyaları görüntülemek için dokunun"</string>
<string name="pin_target" msgid="8036028973110156895">"Sabitle"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Sabitlemeyi kaldır"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Uygulama bilgileri"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Demo başlatılıyor…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Şu öğeler "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" hizmetinde güncellensin mi: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ve <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Kaydet"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Hayır, teşekkürler"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Şimdi değil"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Hiçbir zaman"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Güncelle"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Devam"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"şifre"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Bölünmüş Ekranı aç/kapat"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Kilit Ekranı"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekran görüntüsü"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Pop-up pencerede <xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasının başlık çubuğu."</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 8007f9e..00feb9e 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -192,8 +192,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Додаток адміністратора в робочому профілі відсутній або пошкоджений. У результаті ваш робочий профіль і пов’язані з ним дані видалено. Зверніться до свого адміністратора по допомогу."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Робочий профіль більше не доступний на цьому пристрої"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Забагато спроб ввести пароль"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Адміністратор не дозволив використовувати пристрій для особистих потреб"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Пристрій контролюється"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Адміністратор вашої організації контролює цей пристрій і відстежує мережевий трафік. Торкніться, щоб дізнатися більше."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"З вашого пристрою буде стерто всі дані"</string>
@@ -236,7 +235,7 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Звіт про помилки"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Завершити сеанс"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Знімок екрана"</string>
- <string name="bugreport_title" msgid="8549990811777373050">"Повідомлення про помилку"</string>
+ <string name="bugreport_title" msgid="8549990811777373050">"Звіт про помилку"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Інформація про поточний стан вашого пристрою буде зібрана й надіслана електронною поштою. Підготовка звіту триватиме певний час."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Інтерактивний звіт"</string>
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Підходить для більшості випадків. Можна відстежувати, як створюється звіт, вводити більше деталей про проблему та робити знімки екрана. Можуть опускатися деякі розділи, які рідко використовуються, але довго створюються."</string>
@@ -387,13 +386,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Дозволяє додатку надсилати закріплені широкомовні повідомлення, які залишаються після їх відтворення. Надмірне використання може сповільнювати роботу пристрою Android TV або порушувати її стабільність, спричиняючи завелике використання пам\'яті."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Дозволяє програмі надсилати закріплені широкомовні повідомлення, які залишаються після відтворення широкомовного повідомлення. Надмірне використання може сповільнювати роботу телефону або порушувати її стабільність, спричиняючи завелике використання пам’яті."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"читати контакти"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Дозволяє програмі читати дані про контакти, які зберігаються у вашому планшетному ПК, зокрема частоту здійснення викликів, надсилання електронних листів або інших способів спілкування з окремими особами. Такий дозвіл дає програмам змогу зберігати ваші контактні дані. Шкідливі програми можуть надсилати контактні дані без вашого відома."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Дозволяє додатку зчитувати дані про контакти, які зберігаються на вашому пристрої Android TV, зокрема частоту здійснення викликів, надсилання електронних листів або спілкування з певними особами іншими способами. Додатки з цим дозволом можуть зберігати контактні дані. Шкідливі додатки можуть надсилати контактні дані без вашого відома."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Дозволяє програмі читати дані про контакти, які зберігаються у вашому телефоні, зокрема частоту здійснення викликів, надсилання електронних листів або інших способів спілкування з окремими особами. Такий дозвіл дає програмам змогу змогу зберігати ваші контактні дані. Шкідливі програми можуть надсилати контактні дані без вашого відома."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Дозволяє додатку переглядати дані про контакти, які зберігаються на вашому планшеті. Додатки також отримають доступ до облікових записів на вашому планшеті (зокрема до створених іншими встановленими додатками), у яких було створено контакти. Додатки з цим дозволом можуть зберігати ваші контактні дані. Шкідливі додатки можуть надсилати контактні дані без вашого відома."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Дозволяє додатку переглядати дані про контакти, які зберігаються на вашому пристрої Android TV. Додатки також отримають доступ до облікових записів на вашому пристрої Android TV (зокрема до створених іншими встановленими додатками), у яких було створено контакти. Додатки з цим дозволом можуть зберігати ваші контактні дані. Шкідливі додатки можуть надсилати контактні дані без вашого відома."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Дозволяє додатку переглядати дані про контакти, які зберігаються на вашому телефоні. Додатки також отримають доступ до облікових записів на вашому телефоні (зокрема до створених іншими встановленими додатками), у яких було створено контакти. Додатки з цим дозволом можуть зберігати ваші контактні дані. Шкідливі додатки можуть надсилати контактні дані без вашого відома."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"змінювати контакти"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Дозволяє програмі змінювати дані про контакти, які зберігаються у вашому планшетному ПК, зокрема частоту здійснення дзвінків, надсилання електронних листів або інших способів спілкування з окремими особами. Такий дозвіл дає програмам змогу видаляти контактні дані."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Дозволяє додатку змінювати дані про контакти, які зберігаються на вашому пристрої Android TV, зокрема частоту здійснення викликів, надсилання електронних листів або спілкування з певними особами іншими способами. Додатки з цим дозволом можуть видаляти контактні дані."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Дозволяє програмі змінювати дані про контакти, які зберігаються у вашому телефоні, зокрема частоту здійснення дзвінків, надсилання електронних листів або інших способів спілкування з окремими особами. Такий дозвіл дає програмам змогу видаляти контактні дані."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Дозволяє додатку змінювати дані про контакти, які зберігаються на вашому планшеті, а також видаляти їх."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Дозволяє додатку змінювати дані про контакти, які зберігаються на вашому пристрої Android TV, а також видаляти їх."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Дозволяє додатку змінювати дані про контакти, які зберігаються на вашому телефоні, а також видаляти їх."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"читати журнал викликів"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Цей додаток може переглядати історію викликів."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"записувати в журнал викликів"</string>
@@ -413,13 +412,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"отр. дост. до додат. команд пров. місцезн."</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Додаток отримуватиме доступ до додаткових команд постачальника геоданих. Можливе втручання додатка в роботу GPS чи інших джерел геоданих."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"отримувати доступ до даних про точне місцезнаходження лише в активному режимі"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Цей додаток може отримувати дані про ваше точне місцезнаходження лише в активному режимі. Щоб додаток користувався службами локації, вони мають бути наявні й увімкнені на вашому телефоні. Через це може швидше розряджатись акумулятор."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"отримувати доступ до даних про приблизне місцезнаходження (на основі мережі) лише в активному режимі"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Цей додаток може отримувати дані про ваше місцезнаходження на основі джерел мережі, як-от антен мобільного зв’язку та мереж Wi-Fi, лише в активному режимі. Щоб додаток міг користуватися цими службами локації, вони мають бути доступними й увімкненими на вашому планшеті."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Додаток може отримувати дані про ваше місцезнаходження на основі джерел мережі, як-от антен мобільного зв’язку та мереж Wi-Fi, лише в активному режимі. Щоб додаток міг користуватися цими службами локації, вони мають бути доступними й увімкненими на вашому пристрої Android TV."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Цей додаток може отримувати дані про ваше місцезнаходження на основі джерел мережі, як-от антен мобільного зв’язку та мереж Wi-Fi, лише в активному режимі. Щоб додаток міг користуватися цими службами локації, вони мають бути доступними й увімкненими на вашому телефоні."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Цей додаток може отримувати дані про ваше точне місцезнаходження лише в активному режимі. Щоб додаток міг використовувати Служби локації, вони мають бути доступні й увімкнені на вашому пристрої. Це може пришвидшити розряджання акумулятора."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"отримувати доступ до даних про приблизне місцезнаходження лише в активному режимі"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Цей додаток може отримувати дані про ваше приблизне місцезнаходження лише в активному режимі. Щоб додаток міг використовувати Служби локації, вони мають бути доступні й увімкнені на вашому пристрої."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"доступ до геоданих у фоновому режимі"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Якщо ви надасте цей дозвіл і доступ до приблизного або точного місцезнаходження, додаток зможе отримувати геодані у фоновому режимі."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Цей додаток може отримувати дані про місцезнаходження, коли його запущено не лише в активному, а й у фоновому режимі."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"змінювати налаштув-ня звуку"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Дозволяє програмі змінювати загальні налаштування звуку, як-от гучність і динамік, який використовується для виводу сигналу."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"запис-ти аудіо"</string>
@@ -500,6 +497,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Дозволяє програмі переглядати конфігурацію Bluetooth на планшетному ПК, а також створювати та приймати з’єднання зі спареними пристроями."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Дозволяє додатку зчитувати конфігурацію Bluetooth на вашому пристрої Android TV, а також створювати та приймати з\'єднання зі спареними пристроями."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Дозволяє програмі переглядати конфігурацію Bluetooth на телефоні, а також створювати та приймати з’єднання зі спареними пристроями."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"контрол. Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Дозволяє програмі обмінюватися даними з тегами, картками та читачами екрана Near Field Communication (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"вимикати блокування екрана"</string>
@@ -906,7 +907,7 @@
<string name="factorytest_no_action" msgid="339252838115675515">"Не було знайдено жодного пакета, який надає дію FACTORY_TEST."</string>
<string name="factorytest_reboot" msgid="2050147445567257365">"Перезав."</string>
<string name="js_dialog_title" msgid="7464775045615023241">"На сторінці за адресою \"<xliff:g id="TITLE">%s</xliff:g>\" написано:"</string>
- <string name="js_dialog_title_default" msgid="3769524569903332476">"Javascript"</string>
+ <string name="js_dialog_title_default" msgid="3769524569903332476">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="7012587995876771246">"Підтвердити перехід"</string>
<string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"Полишити цю сторінку"</string>
<string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"Залишитися на цій сторінці"</string>
@@ -1356,7 +1357,7 @@
<string name="usb_contaminant_detected_message" msgid="7346100585390795743">"USB-порт автоматично вимкнено. Торкніться, щоб дізнатися більше."</string>
<string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"Можна використовувати USB-порт"</string>
<string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"Телефон уже не виявляє рідини або сміття."</string>
- <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Створюється повідомлення про помилку…"</string>
+ <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Створення звіту про помилку…"</string>
<string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Надіслати звіт про помилку?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"Надсилається звіт про помилку…"</string>
<string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Ваш адміністратор просить надіслати повідомлення про помилку, щоб вирішити проблему з пристроєм. Він може отримати доступ до ваших додатків і даних."</string>
@@ -1926,7 +1927,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Під’єднано до пристрою <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Торкніться, щоб переглянути файли"</string>
<string name="pin_target" msgid="8036028973110156895">"Закріпити"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Відкріпити"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Про додатки"</string>
<string name="negative_duration" msgid="1938335096972945232">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Запуск демонстрації…"</string>
@@ -1971,6 +1976,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Оновити в сервісі "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" такі дані: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> і <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Зберегти"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Ні, дякую"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Не зараз"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Ніколи"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Оновити"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Продовжити"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"пароль"</string>
@@ -2068,5 +2075,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Розділити екран"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Заблокувати екран"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Знімок екрана"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> у спливаючому вікні."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Смуга із субтитрами для додатка <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 312aed7d..04480d9 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"دفتری پروفائل کی منتظم ایپ یا تو غائب ہے یا خراب ہے۔ اس کی وجہ سے، آپ کا دفتری پروفائل اور متعلقہ ڈیٹا حذف کر دیے گئے ہیں۔ مدد کیلئے اپنے منتظم سے رابطہ کریں۔"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"آپ کا دفتری پروفائل اس آلہ پر مزید دستیاب نہیں ہے"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"پاس ورڈ کی بہت ساری کوششیں"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"منتظم نے ذاتی استعمال کے لیے آلہ کو دستبردار کیا ہے"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"آلہ زیر انتظام ہے"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"آپ کی تنظیم اس آلے کا نظم کرتی ہے اور وہ نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے۔ تفاصیل کیلئے تھپتھپائیں۔"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"آپ کا آلہ صاف کر دیا جائے گا"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"ایپ کو چپکنے والا براڈکاسٹس بھیجنے کی اجازت دیتا ہے، جو براڈکاسٹ ختم ہونے کے بعد بھی باقی رہتے ہیں۔ حد سے زیادہ استعمال میموری کے کافی زیادہ استعمال کی وجہ سے آپ کے Android TV کو سُست یا غیر مستحکم بنا سکتا ہے۔"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"ایپ کو اسٹیکی براڈکاسٹس بھیجنے کی اجازت دیتا ہے، جو براڈکاسٹ ختم ہونے کے بعد بھی باقی رہتے ہیں۔ حد سے زیادہ استعمال فون کو سست یا غیر مستحکم بنا سکتا ہے جس کی وجہ سے یہ میموری کا کافی زیادہ استعمال کر سکتا ہے۔"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"اپنے رابطوں کو پڑھیں"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"ایپ کو آپ کے ٹیبلٹ پر اسٹور کردہ آپ کے رابطوں، بشمول مخصوص افراد کو دوسرے طریقوں سے جس تعدد سے آپ نے کال، ای میل کیا ہے یا ان کے ساتھ مواصلت کی ہے اس کے بارے میں ڈیٹا کو پڑھنے کی اجازت دیتا ہے۔ یہ اجازت ایپس کو آپ کے رابطے کا ڈیٹا محفوظ کرنے کی اجازت دیتی ہے اور نقصان دہ ایپس آپ کے علم کے بغیر رابطے کے ڈیٹا کا اشتراک کرسکتی ہیں۔"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"ایپ کو آپ کے Android TV آلہ پر اسٹور کردہ آپ کے رابطے، بشمول مخصوص افراد کو دوسرے طریقوں سے جس تعدد سے آپ نے کال، ای میل کیا ہے یا ان کے ساتھ مواصلت کی ہے ان کے بارے میں ڈیٹا پڑھنے کی اجازت دیتا ہے۔ یہ اجازت ایپس کو آپ کے رابطے کا ڈیٹا محفوظ کرنے کی اجازت دیتی ہے اور نقصان دہ ایپس آپ کی جانکاری کے بغیر رابطے کے ڈیٹا کا اشتراک کر سکتی ہے۔"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"ایپ کو آپ کے فون پر اسٹور کردہ آپ کے رابطوں، بشمول مخصوص افراد کو دوسرے طریقوں سے جس تعدد سے آپ نے کال، ای میل کیا ہے یا ان کے ساتھ مواصلت کی ہے اس کے بارے میں ڈیٹا کو پڑھنے کی اجازت دیتا ہے۔ یہ اجازت ایپس کو آپ کے رابطے کا ڈیٹا محفوظ کرنے کی اجازت دیتی ہے اور نقصان دہ ایپس آپ کے علم کے بغیر رابطے کے ڈیٹا کا اشتراک کرسکتی ہیں۔"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"ایپ کو آپ کے ٹیبلیٹ پر اسٹور کردہ آپ کے رابطوں کے بارے میں ڈیٹا کو پڑھنے کی اجازت دیتی ہے۔ ایپس کو آپ کے ٹیبلیٹ پر ان اکاؤنٹس تک رسائی حاصل ہو گی جنہوں نے رابطے تخلیق کیے ہیں۔ اس میں آپ کی انسٹال کردہ ایپس کے ذریعے تخلیق کردہ اکاؤنٹس بھی شامل ہو سکتے ہیں۔ یہ اجازت ایپس کو آپ کے رابطے کا ڈیٹا محفوظ کرنے کی اجازت دیتی ہے اور نقصان دہ ایپس آپ کی جانکاری کے بغیر رابطے کے ڈیٹا کا اشتراک کر سکتی ہیں۔"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"ایپ کو آپ کے Android TV آلہ پر اسٹور کردہ آپ کے رابطوں کے بارے میں ڈیٹا کو پڑھنے کی اجازت دیتی ہے۔ ایپس کو آپ کے Android TV آلات پر ان اکاؤنٹس تک رسائی حاصل ہو گی جنہوں نے رابطے تخلیق کیے ہیں۔ اس میں آپ کی انسٹال کردہ ایپس کے ذریعے تخلیق کردہ اکاؤنٹس بھی شامل ہو سکتے ہیں۔ یہ اجازت ایپس کو آپ کے رابطے کا ڈیٹا محفوظ کرنے کی اجازت دیتی ہے اور نقصان دہ ایپس آپ کی جانکاری کے بغیر رابطے کے ڈیٹا کا اشتراک کر سکتی ہیں۔"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ایپ کو آپ کے فون پر اسٹور کردہ آپ کے رابطوں کے بارے میں ڈیٹا پڑھنے کی اجازت دیتی ہے۔ ایپس کو آپ کے فون پر ان اکاؤنٹس تک رسائی حاصل ہو گی جنہوں نے رابطے تخلیق کیے ہیں۔ اس میں آپ کی انسٹال کردہ ایپس کے ذریعے تخلیق کردہ اکاؤنٹس بھی شامل ہو سکتے ہیں۔ یہ اجازت ایپس کو آپ کے رابطے کا ڈیٹا محفوظ کرنے کی اجازت دیتی ہے اور نقصان دہ ایپس آپ کی جانکاری کے بغیر رابطے کے ڈیٹا کا اشتراک کر سکتی ہیں۔"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"اپنے رابطوں میں ترمیم کریں"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"ایپ کو آپ کے ٹیبلٹ پر اسٹور کردہ آپ کے رابطوں، بشمول مخصوص رابطوں کو جس تعدد سے آپ نے کال، ای میل کیا ہے یا دوسرے طریقوں سے ان کے ساتھ مواصلت کی ہے اس کے بارے میں ڈیٹا میں ترمیم کی اجازت دیتا ہے۔ یہ اجازت ایپس کو رابطے کا ڈیٹا حذف کرنے کی اجازت دیتی ہے۔"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"ایپ کو آپ کے Android TV آلات پر اسٹور کردہ آپ کے رابطوں، بشمول مخصوص رابطوں کو جس تعدد سے آپ نے کال، ای میل کیا ہے یا دوسرے طریقوں سے ان کے ساتھ مواصلت کی ہے ان کے بارے میں ڈیٹا میں ترمیم کی اجازت دیتا ہے۔ یہ اجازت ایپس کو رابطے کا ڈیٹا حذف کرنے کی اجازت دیتی ہے۔"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"ایپ کو آپ کے فون پر اسٹور کردہ آپ کے رابطوں، بشمول مخصوص رابطوں کو جس تعدد سے آپ نے کال، ای میل کیا ہے یا دوسرے طریقوں سے ان کے ساتھ مواصلت کی ہے اس کے بارے میں ڈیٹا میں ترمیم کی اجازت دیتا ہے۔ یہ اجازت ایپس کو رابطے کا ڈیٹا حذف کرنے کی اجازت دیتی ہے۔"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"ایپ کو آپ کے ٹیبلیٹ پر اسٹور کردہ آپ کے رابطوں کے بارے میں ڈیٹا کو ترمیم کرنے کی اجازت دیتی ہے۔ یہ اجازت ایپس کو رابطے کا ڈیٹا حذف کرنے کی اجازت دیتی ہے۔"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"ایپ کو آپ کے Android TV آلہ پر اسٹور کردہ آپ کے رابطوں کے بارے میں ڈیٹا کو ترمیم کرنے کی اجازت دیتی ہے۔ یہ اجازت ایپس کو رابطے کا ڈیٹا حذف کرنے کی اجازت دیتی ہے۔"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"ایپ کو آپ کے فون پر اسٹور کردہ آپ کے رابطوں کے بارے میں ڈیٹا کو ترمیم کرنے کی اجازت دیتی ہے۔ یہ اجازت ایپس کو رابطے کا ڈیٹا حذف کرنے کی اجازت دیتی ہے۔"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"کال لاگ پڑھیں"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"یہ ایپ آپ کی کال کی سرگزشت پڑھ سکتی ہے۔"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"کال لاگ لکھیں"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"اضافی مقام فراہم کنندہ کی کمانڈز تک رسائی حاصل کریں"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"ایپ کو اضافی مقام فراہم کنندہ کی کمانڈز تک رسائی حاصل کرنے کی اجازت دیتی ہے۔ یہ ایپ کو GPS یا دوسرے مقام کے مآخذ کے عمل کے ساتھ مداخلت کرنے کی اجازت دے سکتی ہے۔"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"صرف پیش منظر میں درست مقام تک رسائی حاصل کریں"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"یہ ایپ جب پس منظر میں ہوتی ہے تبھی یہ آپ کا صحیح مقام حاصل کر سکتی ہے۔ ایپ کو ان مقام کی سروسز کو استعمال کر سکنے کیلئے ان کا آن ہونا اور آپ کے فون پر دستیاب ہونا ضروری ہے۔"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"صرف پیش منظر میں (نیٹ ورک پر مبنی) تخمینی مقام تک رسائی حاصل کریں"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"نیٹ ورک ماخذات جیسے کہ سیل ٹاورز اور Wi-Fi نیٹ ورکس کی بنیاد پر یہ ایپ آپ کا مقام حاصل کر سکتی ہے لیکن صرف اس وقت جب ایپ پیش منظر میں ہو۔ ایپ کو ان مقام کی سروسز کو استعمال کرنے کے لیے ان کا آن ہونا اور آپ کے ٹیبلیٹ پر دستیاب ہونا ضروری ہے۔"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"نیٹ ورک ماخذات جیسے کہ سیل ٹاورز اور Wi-Fi نیٹ ورکس کی بنیاد پر یہ ایپ آپ کا مقام حاصل کر سکتی ہے لیکن صرف اس وقت جب ایپ پیش منظر میں ہو۔ ایپ کو ان مقام کی سروسز کو استعمال کرنے کے لیے ان کا آن ہونا اور آپ کے Android TV آلہ پر دستیاب ہونا ضروری ہے۔"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"نیٹ ورک ماخذات جیسے کہ سیل ٹاورز اور Wi-Fi نیٹ ورکس کی بنیاد پر یہ ایپ آپ کا مقام حاصل کر سکتی ہے لیکن صرف اس وقت جب ایپ پیش منظر میں ہو۔ ایپ کو ان مقام کی سروسز کو استعمال کرنے کے لیے ان کا آن ہونا اور آپ کے فون پر دستیاب ہونا ضروری ہے۔"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"یہ ایپ جب پس منظر میں ہوتی ہے تبھی یہ آپ کا صحیح مقام حاصل کر سکتی ہے۔ ایپ کو مقام کی سروسز کو استعمال کرنے کیلئے اِن کا آپ کے آلہ پر دستیاب ہونا اور آن ہونا ضروری ہے۔ اس سے بیٹری کی کھپت میں اضافہ ہو سکتا ہے۔"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"صرف پیش منظر میں تخمینی مقام تک رسائی"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"یہ ایپ جب پس منظر میں ہوتی ہے تبھی یہ آپ کا تخمینی مقام حاصل کر سکتی ہے۔ ایپ کو مقام کی سروسز کو استعمال کرنے کیلئے ان کا آپ کے آلہ پر دستیاب ہونا اور آن ہونا ضروری ہے۔"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"پس منظر میں مقام کی رسائی حاصل کریں"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"اگر اضافی طور پر اسے تخمینی یا درست مقام تک رسائی کی منظوری دی جاتی ہے تو پس منظر میں چلنے کے دوران ایپ اس مقام تک رسائی حاصل کر سکتی ہے۔"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"یہ ایپ پیش منظر کے مقام تک رسائی کے ساتھ ساتھ، پس منظر میں چلتے ہوئے مقام تک رسائی حاصل کر سکتی ہے۔"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"اپنے آڈیو کی ترتیبات کو تبدیل کریں"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"ایپ کو مجموعی آڈیو ترتیبات جیسے والیوم اور آؤٹ پٹ کیلئے جو اسپیکر استعمال ہوتا ہے اس میں ترمیم کرنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"آڈیو ریکارڈ کریں"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ایپ کو ٹیبلیٹ پر بلوٹوتھ کی ترتیب دیکھنے اور جوڑا بنائے ہوئے آلات کے ساتھ کنکشنز بنانے اور قبول کرنے کی اجازت دیتا ہے۔"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"ایپ کو آپ کے Android TV آلہ پر بلوٹوتھ کنفیگریشن دیکھنے، اور جوڑا بنائے ہوئے آلات کے ساتھ کنکشنز بنانے اور قبول کرنے کی اجازت دیتا ہے۔"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ایپ کو فون پر بلوٹوتھ کی ترتیب دیکھنے اور جوڑا بنائے ہوئے آلات کے ساتھ کنکشنز بنانے اور قبول کرنے کی اجازت دیتا ہے۔"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field کمیونیکیشن کنٹرول کریں"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"ایپ کو Near Field Communication (NFC) ٹیگز، کارڈز اور ریڈرز کے ساتھ مواصلت کرنے کی اجازت دیٹا ہے۔"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"اپنے اسکرین لاک کو غیر فعال کریں"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> سے منسلک"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"فائلوں کو دیکھنے کیلئے تھپتھپائیں"</string>
<string name="pin_target" msgid="8036028973110156895">"پن کریں"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"پن ہٹائیں"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"ایپ کی معلومات"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"ڈیمو شروع ہو رہا ہے…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"ان آئٹمز کو "<b>"<xliff:g id="LABEL">%4$s</xliff:g> "</b>" میں اپ ڈیٹ کریں: <xliff:g id="TYPE_0">%1$s</xliff:g>، <xliff:g id="TYPE_1">%2$s</xliff:g> اور <xliff:g id="TYPE_2">%3$s</xliff:g> ؟"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"محفوظ کریں"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"نہیں، شکریہ"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"ابھی نہیں"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"کبھی نہیں"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"اپ ڈیٹ کریں"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"جاری رکھیں"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"پاس ورڈ"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"اسپلٹ اسکرین ٹوگل کریں"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"مقفل اسکرین"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"اسکرین شاٹ"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"پوپ-اپ ونڈو میں <xliff:g id="APP_NAME">%1$s</xliff:g> ایپ۔"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> کی کیپشن بار۔"</string>
</resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index c7987d1..8872dac 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Ishchi profilning administrator ilovasi yo‘q yoki buzilgan. Shuning uchun, ishchi profilingiz va unga aloqador ma’lumotlar o‘chirib tashlandi. Yordam olish uchun administratoringizga murojaat qiling."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Bu qurilmada endi ishchi profilingiz mavjud emas"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Parol ko‘p marta xato kiritildi"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator shaxsiy foydalanishga qoldirilgan qurilmani rad etdi"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Bu – boshqariladigan qurilma"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Tashkilotingiz bu qurilmani boshqaradi va tarmoq trafigini nazorat qilishi mumkin. Tafsilotlar uchun bosing."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Qurilmangizdagi ma’lumotlar o‘chirib tashlanadi"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Ilova yuborilganidan keyin oʻchib ketmaydigan muddatsiz tarqatma xabarlarni yuborishi mumkin. Ulardan notoʻgʻri maqsadda foydalanish qurilmaning ishlashini sekinlatishi yoki xotiraga haddan ziyod yuklanish tushishi oqibatida qurilma ishdan chiqishi mumkin."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Ilova yuborilganidan keyin o‘chib ketmaydigan muddatsiz tarqatma xabarlarni yuborishi mumkin. Ulardan noto‘g‘ri maqsadda foydalanish qurilmaning ishlashini sekinlatishi yoki xotiraga haddan ziyod yuklanish tushishi oqibatida qurilma ishdan chiqishi mumkin."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"kontaktlaringizni ko‘rish"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Ilovaga planshetingizda saqlangan kontaktlar ma’lumotlarini, shuningdek, ba‘zi shaxslarga qilgan qo‘ng‘iroqlar muntazamligi, ularga yozgan e-pochta xabarlari yoki boshqa xabar almashish yo‘llari orqali xabarlashganingiz haqidagi ma’lumotlarni o‘qishga ruxsat beradi. Ushbu ruxsat ilovalarga aloqa ma’lumotlaringizni saqlash uchun ruxsat beradi va zararli ilovalar sizga bildirmasdan kontaktlar ma’lumotlaringizni boshqalarga ulashishi mumkin."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Ilovaga Android TV qurilmangizdagi kontaktlar haqidagi axborotni, jumladan, muayyan shaxslar bilan chaqiruv, email orqali xabarlashish yoki muloqot qilish takroriyligi haqidagi axborotni oʻqish huquqini beradi. Bu ruxsat ilovalarga kontaktlaringizga oid axborotni saqlash huquqini berib, zararli ilovalar uning yordamida kontakt maʼlumotlarini sizdan beruxsat boshqalarga ulashishi mumkin."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Ilovaga telefoningizda saqlangan kontaktlar ma’lumotlarini, shuningdek, ba‘zi shaxslarga qilgan qo‘ng‘iroqlar muntazamligi, ularga yozgan e-pochta xabarlari yoki boshqa xabar almashish yo‘llari orqali xabarlashganingiz haqidagi ma’lumotlarni o‘qishga ruxsat beradi. Ushbu ruxsat ilovalarga kontaktlar ma’lumotlaringizni saqlash uchun ruxsat beradi va zararli ilovalar sizga bildirmasdan aloqa ma’lumotlaringizni boshqalarga ulashishi mumkin."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Bu planshetga telefoningizdagi kontaktlarga oid axborotni oʻqish huquqini beradi. Ilovalar ham planshetdagi kontaktlarni yaratgan hisoblaringizga ruxsat oladi Jumladan, oʻrnatilgan ilovalar ochgan hisoblarga ham ruxsat beriladi. Bu ruxsat ilovalarga kontaktlaringizga oid axborotni saqlash huquqini berib, zararli ilovalar uning yordamida kontakt maʼlumotlarini sizdan beruxsat boshqalarga ulashishi mumkin."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Bu ilovaga Android TV qurilmangizdagi kontaktlarga oid axborotni oʻqish huquqini beradi. Ilovalar ham Android TV qurilmasidagi kontaktlarni yaratgan hisoblaringizga ruxsat oladi Jumladan, oʻrnatilgan ilovalar ochgan hisoblarga ham ruxsat beriladi. Bu ruxsat ilovalarga kontaktlaringizga oid axborotni saqlash huquqini berib, zararli ilovalar uning yordamida kontakt maʼlumotlarini sizdan beruxsat boshqalarga ulashishi mumkin."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Bu ilovaga telefoningizdagi kontaktlarga oid axborotni oʻqish huquqini beradi. Ilovalar ham telefondagi kontaktlarni yaratgan hisoblaringizga ruxsat oladi Jumladan, oʻrnatilgan ilovalar ochgan hisoblarga ham ruxsat beriladi. Bu ruxsat ilovalarga kontaktlaringizga oid axborotni saqlash huquqini berib, zararli ilovalar uning yordamida kontakt maʼlumotlarini sizdan beruxsat boshqalarga ulashishi mumkin."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"kontaktlaringizni tahrirlash"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Ilovaga planshetingizda saqlangan kontaktlar ma’lumotlarini, shuningdek, ba‘zi shaxslarga qilgan qo‘ng‘iroqlar muntazamligi, ularga yozgan e-pochta xabarlari yoki boshqa xabar almashish yo‘llari orqali xabarlashganingiz haqidagi ma’lumotlarni o‘zgartirishga ruxsat beradi. Ushbu ruxsat ilovalarga kontaktlar ma’lumotlarini o‘chirishga ruxsat beradi."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Ilovaga Android TV qurilmangizda saqlangan kontaktlar haqidagi axborotni, jumladan, muayyan kontakt bilan chaqiruv, email yoki boshqa usullar orqali muloqot qilish takroriyligini tahrirlash huquqini beradi. Bu ruxsat orqali ilovalar kontaktlar haqidagi axborotni oʻchirib tashlashi mumkin."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Ilovaga telefoningizda saqlangan kontaktlar ma’lumotlarini, shuningdek, ba‘zi shaxslarga qilgan qo‘ng‘iroqlar muntazamligi, ularga yozgan e-pochta xabarlari yoki boshqa xabar almashish yo‘llari orqali xabarlashganingiz haqidagi ma’lumotlarni o‘zgartirishga ruxsat beradi. Ushbu ruxsat ilovalarga kontaktlar ma’lumotlarini o‘chirishga ruxsat beradi."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Bu ilovaga planshetingizdagi kontaktlarga oid axborotni oʻzgartirish huquqini beradi. Bu ruxsat ilovalarga kontaktlarga oid axborotni oʻchirish imkonini ham beradi."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Bu ilovaga Android TV qurilmangizdagi kontaktlarga oid axborotni oʻzgartirish huquqini beradi. Bu ruxsat ilovalarga kontaktlarga oid axborotni oʻchirish imkonini ham beradi."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Bu ilovaga telefoningizdagi kontaktlarga oid axborotni oʻzgartirish huquqini beradi. Bu ruxsat ilovalarga kontaktlarga oid axborotni oʻchirish imkonini ham beradi."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"qo‘ng‘iroq jurnallarini o‘qish"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Bu ilova chaqiruvlar tarixini o‘qiy oladi."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"qo‘ng‘iroq jurnaliga yozish"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"qo‘shimcha manzillarga kirish buyruqlari"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Ilovaga qo‘shimcha joylashuv xizmati buyruqlaridan foydalanishga ruxsat beradi. Uning yordamida ilova GPS yoki boshqa joylashuv ma’lumoti manbalarining ishlashiga xalaqit qilishi mumkin."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"aniq joylashuv axborotini olishga faqat old fonda ruxsat"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Bu ilova faqat fon rejimida aniq joylashuv axborotingizdan foydalanishi mumkin. Ilova ushbu joylashuv xizmatlaridan foydalana olishi uchun ular telefoningizda yoniq turishi va ishlashi kerak. Bunda batareya sarfi oshishi mumkin."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"faqat faol rejimda taxminiy joylashuv axborotiga (tarmoq asosida) ruxsat"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Bu ilova faqat faol rejimda ekanida Wi-Fi va uyali tarmoq antennalari kabi tarmoq manbalari asosida joylashuvingiz axborotini olishi mumkin. Ilova ushbu joylashuv xizmatlaridan foydalana olishi uchun ular planshetingizda yoniq bo‘lishi va ishlashi kerak."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Bu ilova faqat faol rejimda ekanida Wi-Fi va uyali tarmoq antennalari kabi tarmoq manbalari asosida joylashuvingiz axborotini olishi mumkin. Ilova ushbu joylashuv xizmatlaridan foydalana olishi uchun ular Android TV qurilmangizda yoniq boʻlishi va ishlashi kerak."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Bu ilova faqat faol rejimda ekanida Wi-Fi va uyali tarmoq antennalari kabi tarmoq manbalari asosida joylashuvingiz axborotini olishi mumkin. Ilova ushbu joylashuv xizmatlaridan foydalana olishi uchun ular telefoningizda yoniq bo‘lishi va ishlashi kerak."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Bu ilova faqat fon rejimida aniq joylashuv axborotingizdan foydalanishi mumkin. Ilova joylashuv xizmatlaridan foydalana olishi uchun ular qurilmangizda yoniq turishi va ishlashi kerak. Bunda batareya sarfi oshishi mumkin."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"taxminiy joylashuv axborotini olishga faqat old fonda ruxsat"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Bu ilova faqat fon rejimida taxminiy joylashuv axborotingizdan foydalanishi mumkin. Ilova joylashuv xizmatlaridan foydalana olishi uchun ular avtomobilingizda yoniq boʻlishi va ishlashi kerak."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"fonda joylashuv axborotidan foydalanish"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Agar taxminiy yoki aniq joylashuv axborotiga qo‘shimcha tarzda ruxsat berilgan bo‘lsa, ilova ishlayotganda joylashuv axborotidan fonda foydalana oladi."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Bu ilova joylashuv axborotidan orqa fonda ham, old fonda ham foydalanishi mumkin."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"audio sozlamalaringizni o‘zgartirish"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Ilovalarga tovush va ovoz chiqarish uchun foydalaniladigan karnay kabi global audio sozlamalarini o‘zgartirish uchun ruxsat beradi."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ovoz yozib olish"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Ilovaga planshetdagi Bluetooth‘ning sozlamasini ko‘rishga va bog‘langan qurilmalarga ulanish va ulardan ulanish so‘rovlarini qabul qulishga imkon beradi."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Ilovaga Android TV qurilmangizdagi Bluetooth sozlamasini koʻrishga va bogʻlangan qurilmalarga ulanish va ulardan ulanish talablarni qabul qilishga imkon beradi."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Ilovaga telefondagi Bluetooth‘ning sozlamasini ko‘rishga va bog‘langan qurilmalarga ulanish va ulardan ulanish so‘rovlarini qabul qulishga imkon beradi."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"NFC modulini boshqarish"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Ilova qisqa masofali aloqa (NFC) texnologiyasi yordamida NFC yorliqlari, kartalar va o‘qish moslamalari bilan ma’lumot almashishi mumkin."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"ekran qulfini o‘chirib qo‘yish"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> qurilmasiga ulandi"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Fayllarni ko‘rish uchun bosing"</string>
<string name="pin_target" msgid="8036028973110156895">"Qadash"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Olib tashlash"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Ilova haqida"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Demo boshlanmoqda…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" xizmatidagi <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> va <xliff:g id="TYPE_2">%3$s</xliff:g> yangilansinmi?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Saqlash"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Kerak emas"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Keyinroq"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Hech qachon"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Yangilash"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Davom etish"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"parol"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Ekranni ikkiga ajratish tugmasi"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ekran qulfi"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skrinshot"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi qalqib chiquvchi oynada."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> taglavhalar paneli."</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 13c75f6..c21b81d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Ứng dụng quản trị hồ sơ công việc bị thiếu hoặc hỏng. Do vậy, hồ sơ công việc của bạn và dữ liệu liên quan đã bị xóa. Hãy liên hệ với quản trị viên của bạn để được trợ giúp."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Hồ sơ công việc của bạn không có sẵn trên thiết bị này nữa"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Quá nhiều lần nhập mật khẩu"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Quản trị viên đã từ bỏ quyền sở hữu thiết bị để cho phép dùng vào mục đích cá nhân"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Thiết bị được quản lý"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Tổ chức của bạn sẽ quản lý thiết bị này và có thể theo dõi lưu lượng truy cập mạng. Nhấn để biết chi tiết."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Thiết bị của bạn sẽ bị xóa"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Cho phép ứng dụng gửi nội dung truyền phát hấp dẫn người xem. Nội dung này sẽ vẫn còn sau khi quá trình truyền phát kết thúc. Việc sử dụng quá mức có thể làm cho thiết bị Android TV bị chậm hoặc không ổn định do việc sử dụng quá mức khiến thiết bị sử dụng quá nhiều bộ nhớ."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Cho phép ứng dụng gửi nội dung truyền phát hấp dẫn người xem. Nội dung này sẽ vẫn còn sau khi quá trình truyền phát kết thúc. Việc sử dụng quá mức có thể làm cho điện thoại bị chậm hoặc không ổn định do khiến điện thoại sử dụng quá nhiều bộ nhớ."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"đọc danh sách liên hệ của bạn"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Cho phép ứng dụng đọc dữ liệu về các liên hệ được lưu trữ trên máy tính bảng của bạn, bao gồm tần suất bạn đã gọi điện, gửi email hoặc liên lạc theo các cách khác với những người cụ thể. Quyền này cho phép ứng dụng lưu dữ liệu liên lạc của bạn và các ứng dụng độc hại có thể chia sẻ dữ liệu liên lạc mà bạn không biết."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Cho phép ứng dụng đọc dữ liệu về người liên hệ mà bạn lưu trên thiết bị Android TV, bao gồm cả tần suất bạn gọi điện, gửi email hoặc liên lạc theo cách khác với những cá nhân cụ thể. Quyền này cho phép ứng dụng lưu dữ liệu về người liên hệ của bạn, và các ứng dụng độc hại có thể chia sẻ dữ liệu về người liên hệ mà bạn không biết."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Cho phép ứng dụng đọc dữ liệu về các liên hệ được lưu trữ trên điện thoại của bạn, bao gồm tần suất bạn đã gọi điện, gửi email hoặc liên lạc theo các cách khác với những người cụ thể. Quyền này cho phép ứng dụng lưu dữ liệu liên lạc của bạn và các ứng dụng độc hại có thể chia sẻ dữ liệu liên lạc mà bạn không biết."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Cho phép ứng dụng đọc dữ liệu về người liên hệ mà bạn lưu trữ trên máy tính bảng của mình. Ứng dụng cũng sẽ có quyền truy cập vào các tài khoản đã tạo người liên hệ trên máy tính bảng của bạn. Đây có thể là các tài khoản do ứng dụng (bạn đã cài đặt) tạo. Quyền này cho phép ứng dụng lưu dữ liệu về người liên hệ của bạn và các ứng dụng độc hại có thể lén lút chia sẻ dữ liệu này."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Cho phép ứng dụng đọc dữ liệu về người liên hệ mà bạn lưu trữ trên thiết bị Android TV của mình. Ứng dụng cũng sẽ có quyền truy cập vào các tài khoản đã tạo người liên hệ trên thiết bị Android TV của bạn. Đây có thể là các tài khoản do ứng dụng (bạn đã cài đặt) tạo. Quyền này cho phép ứng dụng lưu dữ liệu về người liên hệ của bạn và các ứng dụng độc hại có thể lén lút chia sẻ dữ liệu này."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Cho phép ứng dụng đọc dữ liệu về người liên hệ mà bạn lưu trữ trên điện thoại. Ứng dụng cũng sẽ có quyền truy cập vào các tài khoản đã tạo người liên hệ trên điện thoại của bạn. Đây có thể là các tài khoản do ứng dụng (bạn đã cài đặt) tạo. Quyền này cho phép ứng dụng lưu dữ liệu về người liên hệ của bạn và các ứng dụng độc hại có thể lén lút chia sẻ dữ liệu này."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"sửa đổi danh sách liên hệ của bạn"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Cho phép ứng dụng sửa đổi dữ liệu về các địa chỉ liên hệ được lưu trữ trên máy tính bảng của bạn, bao gồm tần suất mà bạn đã gọi, gửi email hoặc liên lạc theo các cách khác với những địa chỉ liên hệ cụ thể. Quyền này cho phép ứng dụng xóa dữ liệu liên lạc."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Cho phép ứng dụng sửa đổi dữ liệu về người liên hệ mà bạn lưu trên thiết bị Android TV, bao gồm cả tần suất bạn gọi điện, gửi email hoặc liên lạc theo cách khác với những người liên hệ cụ thể. Quyền này cho phép ứng dụng xóa dữ liệu về người liên hệ."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Cho phép ứng dụng sửa đổi dữ liệu về các địa chỉ liên hệ được lưu trữ trên điện thoại của bạn, bao gồm tần suất mà bạn đã gọi, gửi email hoặc liên lạc theo các cách khác với những địa chỉ liên hệ cụ thể. Quyền này cho phép ứng dụng xóa dữ liệu liên lạc."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Cho phép ứng dụng sửa đổi dữ liệu về người liên hệ mà bạn lưu trữ trên máy tính bảng của mình. Quyền này cho phép ứng dụng xóa dữ liệu về người liên hệ."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Cho phép ứng dụng sửa đổi dữ liệu về người liên hệ mà bạn lưu trữ trên thiết bị Android TV. Quyền này cho phép ứng dụng xóa dữ liệu về người liên hệ."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Cho phép ứng dụng sửa đổi dữ liệu về người liên hệ mà bạn lưu trữ trên điện thoại của mình. Quyền này cho phép ứng dụng xóa dữ liệu về người liên hệ."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"đọc nhật ký cuộc gọi"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Ứng dụng này có thể đọc nhật ký cuộc gọi của bạn."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"ghi nhật ký cuộc gọi"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"truy cập vào các lệnh của nhà cung cấp vị trí bổ sung"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Cho phép ứng dụng truy cập vào các lệnh của nhà cung cấp vị trí bổ sung. Điều này có thể cho phép ứng dụng can thiệp vào hoạt động của Hệ thống định vị toàn cầu (GPS) hoặc các nguồn vị trí khác."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"chỉ truy cập vị trí chính xác trong nền trước"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Bất cứ khi nào chạy trong nền trước, ứng dụng này có thể nhận thông tin vị trí chính xác của bạn. Để ứng dụng có thể sử các dụng dịch vụ vị trí, điện thoại của bạn phải có các dịch vụ này và dịch vụ ở trạng thái bật. Hoạt động này có thể tăng mức tiêu thụ pin."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"chỉ truy cập vị trí gần đúng (dựa trên mạng) trong nền trước"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Bất cứ khi nào chạy trong nền trước, ứng dụng này có thể nhận thông tin vị trí dựa trên nguồn mạng, chẳng hạn như trạm phát sóng di động và mạng Wi-Fi. Để ứng dụng có thể dùng các dịch vụ vị trí, máy tính bảng của bạn phải có các dịch vụ này ở trạng thái bật."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Chỉ khi ở nền trước, ứng dụng này mới có thể nhận thông tin vị trí của bạn dựa trên các nguồn mạng, chẳng hạn như trạm phát sóng di động và mạng Wi-Fi. Bạn phải bật và sử dụng được các dịch vụ vị trí này trên thiết bị Android TV thì ứng dụng mới có thể dùng các dịch vụ đó."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Bất cứ khi nào chạy trong nền trước, ứng dụng này có thể nhận thông tin vị trí dựa trên nguồn mạng, chẳng hạn như trạm phát sóng di động và mạng Wi-Fi. Để ứng dụng có thể dùng các dịch vụ vị trí, điện thoại của bạn phải có các dịch vụ này ở trạng thái bật."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Ứng dụng này chỉ có thể nhận thông tin vị trí chính xác của bạn khi mở trên màn hình. Để ứng dụng có thể sử các dụng dịch vụ vị trí, thiết bị của bạn phải có các dịch vụ này và dịch vụ ở trạng thái bật. Hoạt động này có thể tăng mức tiêu thụ pin."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"chỉ truy cập thông tin vị trí gần đúng khi ứng dụng mở trên màn hình"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Ứng dụng này chỉ có thể nhận được thông tin vị trí gần đúng của bạn khi mở trên màn hình. Để ứng dụng có thể dùng các dịch vụ vị trí này, thiết bị của bạn phải có các dịch vụ này và dịch vụ ở trạng thái bật."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"truy cập vào vị trí trong nền"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Nếu bạn cấp cho ứng dụng quyền truy cập bổ sung vào vị trị gần đúng hoặc chính xác, thì ứng dụng có thể truy cập vào vị trí đó khi chạy trong nền."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Ngoài quyền truy cập vào thông tin vị trí khi mở trên màn hình, ứng dụng này còn có thể truy cập vào thông tin vị trí khi đang chạy trong nền."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"thay đổi cài đặt âm thanh của bạn"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Cho phép ứng dụng sửa đổi cài đặt âm thanh chung chẳng hạn như âm lượng và loa nào được sử dụng cho thiết bị ra."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ghi âm"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Cho phép ứng dụng xem cấu hình của Bluetooth trên máy tính bảng và tạo và chấp nhận các kết nối với các thiết bị được ghép nối."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Cho phép ứng dụng xem cấu hình của Bluetooth trên thiết bị Android TV, đồng thời tạo và chấp nhận các kết nối với thiết bị được ghép nối."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Cho phép ứng dụng xem cấu hình của Bluetooth trên điện thoại, tạo và chấp nhận các kết nối với các thiết bị được ghép nối."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"kiểm soát Liên lạc trường gần"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Cho phép ứng dụng giao tiếp với thẻ Giao tiếp trường gần (NFC), thẻ và trình đọc."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"vô hiệu hóa khóa màn hình của bạn"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Đã kết nối với <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Nhấn để xem tệp"</string>
<string name="pin_target" msgid="8036028973110156895">"Ghim"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Bỏ ghim"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Thông tin ứng dụng"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Đang bắt đầu bản trình diễn..."</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Cập nhật các mục này: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> và <xliff:g id="TYPE_2">%3$s</xliff:g> trong "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Lưu"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Không, cảm ơn"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Để sau"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Không bao giờ"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Cập nhật"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Tiếp tục"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"mật khẩu"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Bật/tắt chế độ chia đôi màn hình"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Khóa màn hình"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Chụp ảnh màn hình"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Ứng dụng <xliff:g id="APP_NAME">%1$s</xliff:g> trong Cửa sổ bật lên."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Thanh phụ đề của <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1df2a40..cc53668 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"工作资料管理应用缺失或损坏,因此系统已删除您的工作资料及相关数据。如需帮助,请与您的管理员联系。"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"您的工作资料已不在此设备上"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"密码尝试次数过多"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"管理员已将该设备开放给个人使用"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"设备为受管理设备"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"贵单位会管理该设备,且可能会监控网络流量。点按即可了解详情。"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"系统将清空您的设备"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"允许应用发送置顶广播,这类广播在广播结束后仍会继续存在。过度使用这项功能可能会导致 Android TV 设备使用过多内存,从而降低其运行速度或稳定性。"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"允许该应用发送持久广播消息,此类消息在广播结束后仍会保留。过度使用可能会导致手机使用过多内存,从而降低其速度或稳定性。"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"读取联系人"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"允许该应用读取您平板电脑上存储的联系人的相关数据,包括您通过打电话、发送电子邮件或以其他方式与特定个人通信的频率。此权限可让应用保存您的联系人数据,而恶意应用可能会在您不知情的情况下分享联系人数据。"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"允许应用读取您的 Android TV 设备上存储的联系人相关数据,包括您与特定用户通话、发送电子邮件或通过其他方式进行通信的频率。此权限可让应用保存您的联系人数据,而恶意应用可能会在您不知情的情况下分享联系人数据。"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"允许该应用读取您手机上存储的联系人的相关数据,包括您通过打电话、发送电子邮件或以其他方式与特定个人通信的频率。此权限可让应用保存您的联系人数据,而恶意应用可能会在您不知情的情况下分享联系人数据。"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"允许该应用读取您的平板电脑上存储的联系人相关数据。应用还将有权访问您的平板电脑上已创建联系人的帐号,其中可能包括您已安装的应用所创建的帐号。此权限允许应用保存您的联系人数据,而恶意应用可能会在您不知情的情况下分享联系人数据。"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"允许该应用读取您的 Android TV 设备上存储的联系人相关数据。应用还将有权访问您的 Android TV 设备上已创建联系人的帐号,其中可能包括您已安装的应用所创建的帐号。此权限允许应用保存您的联系人数据,而恶意应用可能会在您不知情的情况下分享联系人数据。"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"允许该应用读取您手机上存储的联系人相关数据。应用还将有权访问您的手机上已创建联系人的帐号,其中可能包括您已安装的应用所创建的帐号。此权限允许应用保存您的联系人数据,而恶意应用可能会在您不知情的情况下分享联系人数据。"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"修改您的通讯录"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"允许该应用修改您平板电脑上存储的联系人的相关数据,包括您通过打电话、发送电子邮件或以其他方式与特定联系人通信的频率。此权限可让应用删除联系人数据。"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"允许应用修改您 Android TV 设备上存储的联系人相关数据,包括您与特定联系人通话、发送电子邮件或通过其他方式进行通信的频率。此权限可让应用删除联系人数据。"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"允许该应用修改您手机上存储的联系人的相关数据,包括您通过打电话、发送电子邮件或以其他方式与特定联系人通信的频率。此权限可让应用删除联系人数据。"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"允许该应用修改您平板电脑上存储的联系人相关数据。此权限允许应用删除联系人数据。"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"允许该应用修改您的 Android TV 设备上存储的联系人相关数据。此权限允许应用删除联系人数据。"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"允许该应用修改您手机上存储的联系人相关数据。此权限允许应用删除联系人数据。"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"读取通话记录"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"此应用可读取您的通话记录。"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"新建/修改/删除通话记录"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"获取额外的位置信息提供程序命令"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"允许该应用使用其他的位置信息提供程序命令。此权限使该应用可以干扰GPS或其他位置信息源的运作。"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"只能在前台获取精确的位置信息"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"此应用只有在前台运行时才能获取您的精确位置信息。您的手机必须支持并开启这些位置信息服务,此应用才能使用这些服务。这可能会增加耗电量。"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"只能在前台获取大概位置(基于网络)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"此应用只能在前台根据网络来源(例如手机信号塔和 WLAN 网络)获取您的位置信息。您的平板电脑必须支持并开启这些位置信息服务,此应用才能使用这些服务。"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"只要这个应用在前台运行,就可以根据网络来源(例如手机信号塔和 WLAN 网络)获取您的位置信息。您的 Android TV 设备必须支持并开启这些位置信息服务,此应用才能使用这些服务。"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"此应用只能在前台根据网络来源(例如手机信号塔和 WLAN 网络)获取您的位置信息。您的手机必须支持并开启这些位置信息服务,此应用才能使用这些服务。"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"此应用只有在前台运行时才能获取您的精确位置信息。您的设备必须支持并开启位置信息服务,此应用才能使用这些服务。这可能会增加耗电量。"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"只有在前台运行时才能获取大致位置信息"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"此应用只有在前台运行时才能获取您的大致位置信息。您的设备必须支持并开启位置信息服务,此应用才能使用这些服务。"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"在后台使用位置信息"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"如果另外授予大致位置信息或精确位置信息访问权限,该应用便可在后台运行时使用位置信息。"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"此应用不仅在前台运行时可以获取位置信息,在后台运行时也能获取位置信息。"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"更改您的音频设置"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"允许该应用修改全局音频设置,例如音量和用于输出的扬声器。"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"录音"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"允许该应用查看平板电脑上的蓝牙配置,以及与配对设备建立连接或接受其连接请求。"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"允许应用查看 Android TV 设备上的蓝牙配置,以及与配对设备建立连接或接受其连接请求。"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"允许该应用查看手机上的蓝牙配置,以及与配对设备建立连接或接受其连接请求。"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距离通信"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"允许应用与近距离无线通信(NFC)标签、卡和读取器通信。"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"停用屏幕锁定"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"已连接到<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"点按即可查看文件"</string>
<string name="pin_target" msgid="8036028973110156895">"固定"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"取消固定"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"应用信息"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"正在启动演示模式…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"要在"<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"中更新<xliff:g id="TYPE_0">%1$s</xliff:g>、<xliff:g id="TYPE_1">%2$s</xliff:g>和<xliff:g id="TYPE_2">%3$s</xliff:g>这些内容吗?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"保存"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"不用了"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"以后再说"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"永不"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"更新"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"继续"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"密码"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"开启/关闭分屏"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"锁定屏幕"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"屏幕截图"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"以弹出式窗口形式打开的<xliff:g id="APP_NAME">%1$s</xliff:g>应用。"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g>的标题栏。"</string>
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index d4d1f7c..8bb32c3 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"工作設定檔管理員應用程式已遺失或損毀。因此,您的工作設定檔和相關資料已刪除。請聯絡您的管理員以取得協助。"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"您的工作設定檔無法再在此裝置上使用"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"密碼輸入錯誤的次數過多"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"管理員已開放裝置供個人使用"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"裝置已受管理"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"您的機構會管理此裝置,並可能會監控網絡流量。輕按即可瞭解詳情。"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"您的裝置將被清除"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"允許應用程式傳送置頂廣播,並在廣播結束後仍然繼續。過度使用會佔用大量記憶體,可能會令 Android TV 減慢運行速度或無法穩定運行。"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"允許應用程式傳送在廣播結束後仍繼續存在的記憶廣播。過度使用可能會促使手機過度使用記憶體,因而拖慢運行速度或造成不穩定。"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"讀取您的通訊錄"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"允許應用程式讀取平板電腦上儲存的聯絡人資料,包括您與個別聯絡人通話、電郵或以其他通訊方式聯絡的頻率。這項權限允許應用程式儲存您的聯絡人資料,而惡意應用程式也可能在您不知情下擅自共用聯絡人資料。"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"允許應用程式讀取儲存在 Android TV 裝置上的聯絡人資料,包括您與特定聯絡人通話、傳送電郵或以其他通訊方式聯絡的頻率。這項權限允許應用程式儲存您的聯絡人資料,而惡意應用程式也可能在您不知情時擅自共用聯絡資料。"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"允許應用程式讀取手機上儲存的聯絡人資料,包括您與個別聯絡人通話、電郵或以其他通訊方式聯絡的頻率。這項權限允許應用程式儲存您的聯絡人資料,而惡意應用程式也可能在您不知情下擅自共用聯絡人資料。"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"允許應用程式讀取儲存在平板電腦上的聯絡人資料。應用程式亦可存取平板電腦上已建立聯絡人的帳戶,其中可能包括已安裝應用程式所建立的帳戶。這項權限允許應用程式儲存您的聯絡人資料,而惡意應用程式也可能在您不知情時擅自共用聯絡資料。"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"允許應用程式讀取儲存在 Android TV 裝置上的聯絡人資料。應用程式亦可存取 Android TV 裝置上已建立聯絡人的帳戶,其中可能包括已安裝應用程式所建立的帳戶。這項權限允許應用程式儲存您的聯絡人資料,而惡意應用程式也可能在您不知情時擅自共用聯絡資料。"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"允許應用程式讀取儲存在手機上的聯絡人資料。應用程式亦可存取手機上已建立聯絡人的帳戶,其中可能包括已安裝應用程式所建立的帳戶。這項權限允許應用程式儲存您的聯絡人資料,而惡意應用程式也可能在您不知情時擅自共用聯絡資料。"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"修改您的通訊錄"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"允許應用程式修改平板電腦上儲存的聯絡人資料,包括您與個別聯絡人通話、電郵或以其他通訊方式聯絡的頻率。這項權限允許應用程式刪除聯絡人資料。"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"允許應用程式修改儲存在 Android TV 裝置上的聯絡人資料,包括您與特定聯絡人通話、傳送電郵或以其他通訊方式聯絡的頻率。這項權限允許應用程式刪除聯絡資料。"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"允許應用程式修改手機上儲存的聯絡人資料,包括您與個別聯絡人通話、電郵或以其他通訊方式聯絡的頻率。這項權限允許應用程式刪除聯絡人資料。"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"允許應用程式修改儲存在平板電腦上的聯絡人資料。這項權限允許應用程式刪除聯絡人資料。"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"允許應用程式修改儲存在 Android TV 裝置上的聯絡人資料。這項權限允許應用程式刪除聯絡人資料。"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"允許應用程式修改儲存在手機上的聯絡人資料。這項權限允許應用程式刪除聯絡人資料。"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"讀取通話記錄"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"此應用程式可以讀取您的通話記錄。"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"寫入通話記錄"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"接收額外的位置提供者指令"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"允許應用程式存取額外的位置提供者指令。這項設定可能會使應用程式干擾 GPS 或其他位置來源的運作。"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"只在前景存取精確位置"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"此應用程式只可在前台運行時獲取您的確實位置資訊。您的手機必須支援並啟用這些定位服務,應用程式方可使用這項功能,但這樣做可能會增加耗電量。"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"只可在前景存取大概位置 (根據網絡定位)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"此應用程式只能在前景中根據網絡來源 (例如手機訊號發射塔和 Wi-Fi 網絡) 獲取您的位置資訊。您必須在平板電腦上開啟這些定位服務,才能讓此應用程式使用位置資訊。"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"此應用程式只能在前景中根據網絡來源 (例如手機訊號發射塔和 Wi-Fi 網絡) 獲取您的位置資訊。您必須在適用的 Android TV 裝置上開啟這些定位服務,才能讓此應用程式使用位置資訊。"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"此應用程式只能在前景中根據網絡來源 (例如手機訊號發射塔和 Wi-Fi 網絡) 獲取您的位置資訊。您必須在手機上開啟這些定位服務,才能讓此應用程式使用位置資訊。"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"此應用程式只可在前景執行時獲取您的確實位置資訊。您的裝置必須支援並已啟用定位服務,應用程式才能使用此功能。不過,這樣做可能會增加耗電量。"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"只在前景存取大概位置"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"此應用程式只可在前景執行時獲取您的大概位置資訊。您的裝置必須支援並已啟用定位服務,應用程式才能使用此功能。"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"在背景存取位置資訊"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"如果您另外授予概略位置或精確位置的存取權,這個應用程式在背景運行時將可存取位置資訊。"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"此應用程式除了可在前景存取位置資訊外,亦可在背景中存取位置。"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"更改音效設定"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"允許應用程式修改全域音頻設定,例如音量和用於輸出的喇叭。"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"錄製音效"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"允許應用程式查看平板電腦的藍牙設定,以及建立和接受與其他配對裝置的連線。"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"允許應用程式查看 Android TV 裝置的藍牙設定,以及建立和接受與其他配對裝置的連線。"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"允許應用程式查看手機的藍牙設定,以及建立和接受與其他配對裝置的連線。"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"允許應用程式使用近距離無線通訊 (NFC) 標記、卡片及讀取程式進行通訊。"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"停用螢幕上鎖"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"已連線至 <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"輕按即可查看檔案"</string>
<string name="pin_target" msgid="8036028973110156895">"固定"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"取消固定"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"應用程式資料"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"正在開始示範…"</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"要在 "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" 中更新<xliff:g id="TYPE_0">%1$s</xliff:g>、<xliff:g id="TYPE_1">%2$s</xliff:g>和<xliff:g id="TYPE_2">%3$s</xliff:g>嗎?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"儲存"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"不用了,謝謝"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"暫時不要"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"永不"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"更新"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"繼續"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"密碼"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"切換分割螢幕"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"將畫面上鎖"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"螢幕截圖"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」應用程式在彈出式視窗中顯示。"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」的說明列。"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 9997b68..8d18a83 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"工作資料夾管理員應用程式遺失或已毀損,因此系統刪除了你的工作資料夾和相關資料。如需協助,請與你的管理員聯絡。"</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"你的工作資料夾已不在這個裝置上"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"密碼輸入錯誤的次數過多"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"管理員將這部裝置開放給個人使用"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"裝置受到管理"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"貴機構會管理這個裝置,且可能監控網路流量。輕觸即可瞭解詳情。"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"你的裝置資料將遭到清除"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"允許應用程式傳送記憶廣播,這類廣播在廣播動作結束後仍繼續存在。請注意,過度使用這項功能可能會使得 Android TV 裝置占用過多記憶體,導致系統的執行速度變慢或穩定性降低。"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"允許應用程式傳送記憶廣播,這類廣播在廣播動作結束後仍繼續存在。請注意,過度使用此功能可能導致手機使用過多的記憶體,導致手機的執行速度變慢或不穩定。"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"讀取你的聯絡人"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"允許應用程式讀取平板電腦上儲存的聯絡人資料,包括你與特定聯絡人通話、傳送電子郵件或使用其他通訊方式的互動頻率。這項權限可讓應用程式儲存你的聯絡人資料,惡意應用程式也可能私自共用聯絡人資料。"</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"允許應用程式讀取 Android TV 裝置上儲存的聯絡人資料,包括你與特定使用者通話、傳送電子郵件或使用其他通訊方式的頻率。這項權限可讓應用程式儲存你的聯絡人資料,惡意應用程式也可能在你不知情的情況下洩露你的聯絡人資料。"</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"允許應用程式讀取手機上儲存的聯絡人資料,包括你與特定聯絡人通話、傳送電子郵件或使用其他通訊方式的互動頻率。這項權限可讓應用程式儲存你的聯絡人資料,惡意應用程式也可能私自共用聯絡人資料。"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"允許應用程式讀取平板電腦上儲存的聯絡人資料。如果你已在平板電腦上的帳戶建立聯絡人,應用程式也將可以存取這些帳戶,當中可能包括你安裝的應用程式所建立的帳戶。這項權限可讓應用程式儲存你的聯絡人資料,惡意應用程式也可能在你不知情的情況下洩露你的聯絡人資料。"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"允許應用程式讀取 Android TV 裝置上儲存的聯絡人資料。如果你已在 Android TV 裝置上的帳戶建立聯絡人,應用程式也將可以存取這些帳戶,當中可能包括你安裝的應用程式所建立的帳戶。這項權限可讓應用程式儲存你的聯絡人資料,惡意應用程式也可能在你不知情的情況下洩露你的聯絡人資料。"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"允許應用程式讀取手機上儲存的聯絡人資料。如果你已在手機上的帳戶建立聯絡人,應用程式也將可以存取這些帳戶,當中可能包括你安裝的應用程式所建立的帳戶。這項權限可讓應用程式儲存你的聯絡人資料,惡意應用程式也可能在你不知情的情況下洩露你的聯絡人資料。"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"修改你的聯絡人"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"允許應用程式讀取平板電腦上儲存的聯絡人資料,包括你與特定聯絡人通話、傳送電子郵件或使用其他通訊方式的互動頻率。這項權限可讓應用程式刪除聯絡人資料。"</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"允許應用程式修改 Android TV 裝置上儲存的聯絡人資料,包括你與特定聯絡人通話、傳送電子郵件或使用其他通訊方式的頻率。這項權限可讓應用程式刪除聯絡人資料。"</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"允許應用程式讀取手機上儲存的聯絡人資料,包括你與特定聯絡人通話、傳送電子郵件或使用其他通訊方式的互動頻率。這項權限可讓應用程式刪除聯絡人資料。"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"允許應用程式修改平板電腦上儲存的聯絡人資料。這項權限可讓應用程式刪除聯絡人資料。"</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"允許應用程式修改 Android TV 裝置上儲存的聯絡人資料。這項權限可讓應用程式刪除聯絡人資料。"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"允許應用程式修改手機上儲存的聯絡人資料。這項權限可讓應用程式刪除聯絡人資料。"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"讀取通話記錄"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"這個應用程式可讀取通話記錄。"</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"寫入通話記錄"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"接收額外的位置提供者指令"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"允許應用程式存取額外位置資訊提供者指令。這項設定可能會造成應用程式干擾 GPS 或其他位置資訊來源的運作。"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"僅可在前景中取得精確位置"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"這個應用程式只能在前景中取得你的確切位置。你必須在手機上開啟這些定位服務,才能讓這個應用程式取得確切位置。請注意,這麼做可能會增加耗電量。"</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"只有在前景執行時才能根據網路取得概略位置"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"只要這個應用程式在前景執行,就可以根據網路來源 (例如基地台和 Wi-Fi 網路) 取得你的位置資訊。如要讓這個應用程式使用定位服務,你必須在平板電腦上開啟這些服務。"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"只要這個應用程式在前景執行,就可以根據網路來源 (例如基地台和 Wi-Fi 網路) 取得你的位置資訊。如要讓這個應用程式使用定位服務,你必須在 Android TV 裝置上開啟這些服務。"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"只要這個應用程式在前景執行,就可以根據網路來源 (例如基地台和 Wi-Fi 網路) 取得你的位置資訊。如要讓這個應用程式使用定位服務,你必須在手機上開啟這些服務。"</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"這個應用程式只能在前景執行時取得你的確切位置。你必須在裝置上開啟定位服務,這個應用程式才能取得定位資訊。請注意,這麼做可能會增加耗電量。"</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"僅可在前景中取得概略位置"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"這個應用程式只能在前景執行時取得你的概略位置。你必須在裝置上開啟定位服務,這個應用程式才能取得定位資訊。"</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"在背景存取位置資訊"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"除了概略位置或精確位置的存取權外,若您另外授予這項存取權,這個應用程式就能在背景執行時存取位置資訊。"</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"這個應用程式在前景和背景執行時,皆可取得位置資訊。"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"變更音訊設定"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"允許應用程式修改全域音訊設定,例如音量和用來輸出的喇叭。"</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"錄製音訊"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"允許應用程式查看平板電腦的藍牙設定,以及建立和接受與其他配對裝置的連線。"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"允許應用程式查看 Android TV 裝置的藍牙設定,以及建立及接受與其他配對裝置的連線。"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"允許應用程式查看手機的藍牙設定,以及建立和接受與其他配對裝置的連線。"</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"允許應用程式與近距離無線通訊 (NFC) 電子感應標籤、卡片及感應器進行通訊。"</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"停用螢幕鎖定"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"已連線至 <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"輕觸即可查看檔案"</string>
<string name="pin_target" msgid="8036028973110156895">"固定"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"取消固定"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"應用程式資訊"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"正在啟動示範模式..."</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"要更新 "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" 中的<xliff:g id="TYPE_0">%1$s</xliff:g>、<xliff:g id="TYPE_1">%2$s</xliff:g>和<xliff:g id="TYPE_2">%3$s</xliff:g>嗎?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"儲存"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"不用了,謝謝"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"暫時不要"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"永遠不要"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"更新"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"繼續"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"密碼"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"切換分割畫面模式"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"螢幕鎖定"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"擷取螢幕畫面"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」應用程式顯示在彈出式視窗中。"</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」的說明文字列。"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 5838a93..435211e 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -188,8 +188,7 @@
<string name="work_profile_deleted_details" msgid="3773706828364418016">"Uhlelo lokusebenza lokulawula lephrofayela yomsebenzi kungenzeka alukho noma lonakele. Njengomphumela, iphrofayela yakho yomsebenzi nedatha ehlobene isusiwe. Xhumana nomlawuli wakho ukuze uthole usizo."</string>
<string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Iphrofayela yakho yomsebenzi ayisatholakali kule divayisi"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Imizamo yamaphasiwedi eminingi kakhulu"</string>
- <!-- no translation found for device_ownership_relinquished (4080886992183195724) -->
- <skip />
+ <string name="device_ownership_relinquished" msgid="4080886992183195724">"Umphathi udedela idivayisi ngokusetshenziswa komuntu siqu"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Idivayisi iphethwe"</string>
<string name="network_logging_notification_text" msgid="1327373071132562512">"Inhlangano yakho iphethe le divayisi futhi kungenzeka ingaqaphi ithrafikhi yenethiwekhi. Thephela imininingwane."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Idivayisi yakho izosulwa"</string>
@@ -381,13 +380,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Ivumela uhlelo lokusebenza ukuthi lithumele ukusakaza okunamathelayo, okusalayo ngemuva kokuphela kokusakaza. Ukusetshenziswa ngokweqile kungenza idivayisi yakho ye-Android TV ihambe kancane noma ingazinzi ngokuyenza ukuthi isebenzise imemori eningi kakhulu."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Ivumela uhlelo lokusebenza ukuthumela ukusakaza okunamathelayo, okusalayo emva kokuba ukusakazwa sekuphelile. Ukusebenzisa kakhulu kuhle kwenze ifoni ukuthi ingasheshi noma ingahlali kahle ngokuyibangela ukusebenzisa imemori eningi."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"funda oxhumana nabo"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="3792628955305119168">"Ivumela uhlelo lokusebenza ukufunda idatha mayelana noxhumana nabo abalondolozwe kuthebhulethi yakho, kufaka phakathi nobuningi obushayele, wathumela i-imeyili, noma oxhumene nabo ngezinye izindlela nomuntu oyedwa. Le mvume ivumela izinhlelo zokusebenza ukulondoloza idatha yoxhumana nabo, izinhlelo zokusebenza ezingalungile zingaba idatha yokuxhumana ngaphandle kolwazi lakho."</string>
- <string name="permdesc_readContacts" product="tv" msgid="2387823103274997441">"Ivumela uhlelo lokusebenza ukuthi lifunde idatha mayelana noxhumana nabo abangqinwe kudivayisi ye-Android TV, okufaka imvamisa oshaye ngayo, wathumela ama-imeyili, noma waxhumana ngezinye izindlela nabantu abathile. Le mvume ivumela izinhlelo zokusebenza ukuthi zilondoloze idatha yoxhumana nabo, futhi izinhlelo zokusebenza ezinobungozi zingabelana ngedatha yokuxhumana ngaphandle kolwazi lakho."</string>
- <string name="permdesc_readContacts" product="default" msgid="6938416250821270191">"Ivumela uhlelo lokusebenza ukufunda idatha mayelana noxhumana nabo abalondolozwe efonini yakho, kufaka phakathi nobuningi obushayele, wathumela i-imeyili, noma oxhumene nabo ngezinye izindlela nomuntu oyedwa. Le mvume ivumela izinhlelo zokusebenza ukulondoloza idatha yoxhumana nabo, izinhlelo zokusebenza ezingalungile zingaba idatha yokuxhumana ngaphandle kolwazi lakho."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Ivumela uhlelo lokusebenza ukufunda idatha mayelana noxhumana nabo abalondolozwe kuthebhulethi yakho. Izinhlelo zokusebenza zizophinda zibe nokufinyelela kuma-akhawunti akuthebulethi yakho adale oxhumana nabo. Lokhu kungafaka ama-akhawunti adalwe izinhlelo zokusebenza ozifakile. Le mvume ivumela izinhlelo zokusebenza ukuthi zilondoloze idatha yoxhumana nabo, kanye nezinhlelo zokusebenza ezinobungozi zingabelana ngedatha yoxhumana nabo ngaphandle kolwazi lwakho."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Ivumela uhlelo lokusebenza ukufunda idatha mayelana noxhumana nabo abalondolozwe kudivayisi yakho ye-Android TV. Izinhlelo zokusebenza zizophinda zibe nokufinyelela kuma-akhawunti kudivayisi yakho ye-Android TV adale oxhumana nabo. Lokhu kungafaka ama-akhawunti adalwe izinhlelo zokusebenza ozifakile. Le mvume ivumela izinhlelo zokusebenza ukuthi zilondoloze idatha yoxhumana nabo, kanye nezinhlelo zokusebenza ezinobungozi zingabelana ngedatha yoxhumana nabo ngaphandle kolwazi lwakho."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Ivumela uhlelo lokusebenza ukufunda idatha mayelana noxhumana nabo abalondolozwe efonini yakho. Izinhlelo zokusebenza zizophinda zibe nokufinyelela kuma-akhawunti akufoni yakho adale oxhumana nabo. Lokhu kungafaka ama-akhawunti adalwe izinhlelo zokusebenza ozifakile. Le mvume ivumela izinhlelo zokusebenza ukuthi zilondoloze idatha yoxhumana nabo, kanye nezinhlelo zokusebenza ezinobungozi zingabelana ngedatha yoxhumana nabo ngaphandle kolwazi lwakho."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"shintsha oxhumana nabo"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="4460252002098005534">"Ivumela uhlelo lokusebenza ukushintsha idatha mayelana noxhumana nabo abalondolozwe kuthebhulethi yakho, kufaka phakathi ubuningi bokushayela, ukuthumela i-imeyili, noma oxhumene nabo ngezinye izindlela. Le mvume ivumela izinhlelo zokusebenza ukususa idatha yoxhumana nabo."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="3870937407268625273">"Ivumela uhlelo lokusebenza ukuguqula idatha emayelana noxhumana nabo abagcinwe kudivayisi yakho ye-Android TV yakho, okufaka imvamisa oshaye ngayo, wathumela ama-imeyili, noma waxhumana ngezinye izindlela noxhumana nabo abathile. Le mvume ivumela izinhlelo zokusebenza ukususa idatha yoxhumana nabo."</string>
- <string name="permdesc_writeContacts" product="default" msgid="4152877294201215490">"Ivumela uhlelo lokusebenza ukushintsha idatha mayelana noxhumana nabo abalondolozwe efonini yakho, kufaka phakathi ubuningi bokushayela, ukuthumela i-imeyili, noma oxhumene nabo ngezinye izindlela. Le mvume ivumela izinhlelo zokusebenza ukususa idatha yoxhumana nabo."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Ivumela uhlelo lokusebenza ukushintsha idatha mayelana noxhumana nabo abalondolozwe kuthebhulethi yakho. Le mvume ivumela izinhlelo zokusebenza ukususa idatha yoxhumana nabo."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Ivumela uhlelo lokusebenza ukushintsha idatha mayelana noxhumana nabo abalondolozwe kudivayisi yakho ye-Android. Le mvume ivumela izinhlelo zokusebenza ukususa idatha yoxhumana nabo."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Ivumela uhlelo lokusebenza ukushintsha idatha mayelana noxhumana nabo abalondolozwe efonini yakho. Le mvume ivumela izinhlelo zokusebenza ukususa idatha yoxhumana nabo."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"funda irekhodi lamakholi"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Lolu hlelo lokusebenza lungafunda umlando wakho wekholi."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"bhala irekhodi lamakholi"</string>
@@ -407,13 +406,11 @@
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"finyelela kweminye imiyalo yokunikeza indawo"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Ivumela uhlelo lokusebenza ukufinyelela imiyalo eyengeziwe yabahlinzeki bendawo. Lokhu kungase kuvumele uhlelo lokusebenza ukuthi liphazamisane nomsebenzi we-GPS noma eminye imithombo yendawo."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"finyelela indawo eqondile kuphela phambili"</string>
- <string name="permdesc_accessFineLocation" msgid="3056141052532120237">"Lolu hlelo lokusebenza lungakutholela indawo eqondile kuphela uma liphambili. Lawa masevisi endawo kufanele avulwe futhi atholakale efonini yakho ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa. Lokhu kungakhulisa ukusebenza kwebhethri."</string>
- <string name="permlab_accessCoarseLocation" msgid="8215351553392299056">"finyelela indawo eseduze (esuselwa kunethiwekhi) kuphela ngaphambili"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="7479449026750078899">"Lolu hlelo lokusebenza lungathola indawo yakho kusukela kumithombo yenethiwekhi efana nezinqaba zeselula namanethiwekhi e-Wi-Fi, kodwa kuphela uma uhlelo lokusebenza lungaphambili. Lawa masevisi endawo kumele avulwe futhi atholakale kuthebulethi yakho ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="6994518594789550469">"Lolu hlelo lokusebenza lungathola indawo yakho kusukela kumithombo yenethiwekhi efana nezinqaba zeselula namanethiwekhi e-Wi-Fi, kodwa kuphela uma uhlelo lokusebenza lungaphambili. Lawa masevisi endawo kumele avulwe futhi atholakale kudivayisi yakho ye-Android TV ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8962998102400124341">"Lolu hlelo lokusebenza lungathola indawo yakho kusukela kumithombo yenethiwekhi efana nezinqaba zeselula kanye namanethiwekhi e-Wi-Fi, kodwa kuphela uma uhlelo lokusebenza lungaphambili. Lawa masevisi endawo kumele avulwe futhi atholakale kufoni yakho ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa."</string>
+ <string name="permdesc_accessFineLocation" msgid="9221079523494157324">"Lolu hlelo lokusebenza lungakutholela indawo eqondile kuphela uma liphambili. Amasevisi endawo kufanele avulwe futhi atholakale kudivayisi yakho ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa. Lokhu kungakhulisa ukusebenza kwebhethri."</string>
+ <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"finyelela indawo enembile kuphela engaphambili"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="4826281078353537786">"Lolu hlelo lokusebenza lungakutholela indawo enembile kuphela uma ingaphambili. Amasevisi endawo kumele avulwe futhi atholakale kudivayisi yakho ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"finyelela kundawo ngemuva"</string>
- <string name="permdesc_accessBackgroundLocation" msgid="6904788108073882096">"Uma lokhu kunikezwa ngokungeziwe ekufinyeleleni okulinganiselwe noma okunembile kwendawo uhlelo lokusebenza lungafinyelela kundawo ngenkathi lusebenza ngemuva."</string>
+ <string name="permdesc_accessBackgroundLocation" msgid="623676842127558197">"Lolu hlelo lokusebenza lungafinyelela indawo ngenkathi isebenza ngasemuva, ngokungeziwe ekufinyeleleni kwendawo yangaphambili."</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"shintsha izilungiselelo zakho zomsindo"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Ivumela uhlelo lokusebenza ukushintsha izilungiselelo zomsindo we-global njengevolomu nokuthi isiphi isipika esisetshenziselwa okukhiphayo."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"qopha umsindo"</string>
@@ -494,6 +491,10 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Ivumela uhlelo lokusebenza ukubuka ukucushwa kwe-Bluetooth kuthebhulethi, nokwenza futhi nokwamukela uxhumo namadivayisi amatanisiwe."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Ivumela uhlelo lokusebenza ukubuka ukucushwa kwe-Bluetooth kudivayisi ye-Android TV, nokwenza futhi nokwamukela uxhumo namadivayisi abhangqiwe."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Ivumela uhlelo lokusebenza ukubuka ukucushwa kwe-Bluetooth efonini, ukwenza futhi nokwamukela uxhumo namadivayisi amatanisiwe."</string>
+ <!-- no translation found for permlab_preferredPaymentInfo (5274423844767445054) -->
+ <skip />
+ <!-- no translation found for permdesc_preferredPaymentInfo (8583552469807294967) -->
+ <skip />
<string name="permlab_nfc" msgid="1904455246837674977">"lawula Uxhumano Lwenkambu Eseduze"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Ivuela uhlelo lokusebenza ukuthi ixhumane ne-Near Field Communication (NFC) amathegi, amakhadi kanye nezinhlelo zokufunda."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"khubaza ukukhiya kwakho iskrini"</string>
@@ -1862,7 +1863,11 @@
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"Kuxhumekile ku-<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Thepha ukuze ubuke onke amafayela"</string>
<string name="pin_target" msgid="8036028973110156895">"Phina"</string>
+ <!-- no translation found for pin_specific_target (7824671240625957415) -->
+ <skip />
<string name="unpin_target" msgid="3963318576590204447">"Susa ukuphina"</string>
+ <!-- no translation found for unpin_specific_target (3859828252160908146) -->
+ <skip />
<string name="app_info" msgid="6113278084877079851">"Ulwazi lohlelo lokusebenza"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Iqalisa i-demo..."</string>
@@ -1905,6 +1910,8 @@
<string name="autofill_update_title_with_3types" msgid="1312232153076212291">"Buyekeza lezi zinto ku-"<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, ne-<xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string>
<string name="autofill_save_yes" msgid="8035743017382012850">"Londoloza"</string>
<string name="autofill_save_no" msgid="9212826374207023544">"Cha ngiyabonga"</string>
+ <string name="autofill_save_notnow" msgid="2853932672029024195">"Hhayi manje"</string>
+ <string name="autofill_save_never" msgid="6821841919831402526">"Akusoze"</string>
<string name="autofill_update_yes" msgid="4608662968996874445">"Buyekeza"</string>
<string name="autofill_continue_yes" msgid="7914985605534510385">"Qhubeka"</string>
<string name="autofill_save_type_password" msgid="5624528786144539944">"iphasiwedi"</string>
@@ -2000,5 +2007,5 @@
<string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Guqula ukuhlukanisa isikrini"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Khiya isikrini"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Isithombe-skrini"</string>
- <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> uhlelo lokusebenza kuwindi le-Pop-up."</string>
+ <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Ibha yamazwibela we-<xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 166cde0..b17d473 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -298,6 +298,9 @@
<!-- Additional flag from base permission type: this permission can be automatically
granted to the system telephony apps -->
<flag name="telephony" value="0x400000" />
+ <!-- Additional flag from base permission type: this permission can be automatically
+ granted to the system companion device manager service -->
+ <flag name="companion" value="0x800000" />
</attr>
<!-- Flags indicating more context for a permission group. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 85406c7..f28f08b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3572,6 +3572,13 @@
<item>android.ext.services</item>
</string-array>
+ <!-- The package name for the system companion device manager service.
+ This service must be trusted, as it can be activated without explicit consent of the user.
+ Example: "com.android.companiondevicemanager"
+ See android.companion.CompanionDeviceManager.
+ -->
+ <string name="config_companionDeviceManagerPackage" translatable="false"></string>
+
<!-- The package name for the default wellbeing app.
This package must be trusted, as it has the permissions to control other applications
on the device.
@@ -4253,6 +4260,10 @@
<!-- Add packages here -->
</string-array>
+ <!-- Whether or not wcg (wide color gamut) should be enabled on this device,
+ we only enabled it while the device has ability of mixed color spaces composition -->
+ <bool name="config_enableWcgMode">false</bool>
+
<!-- When true, enables the whitelisted app to handle bug reports from power menu short press. -->
<bool name="config_bugReportHandlerEnabled">false</bool>
@@ -4272,4 +4283,7 @@
value is left empty. When this is non-empty then config_rawContactsLocalAccountName
should also be non-empty.-->
<string name="config_rawContactsLocalAccountType" translatable="false"></string>
+
+ <!-- Whether or not to use assistant stream volume separately from music volume -->
+ <bool name="config_useAssistantVolume">false</bool>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index ab10738..31becf7 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1345,6 +1345,12 @@
connections with paired devices.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_preferredPaymentInfo">Preferred NFC Payment Service Information</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_preferredPaymentInfo">Allows the app to get preferred nfc payment service information like
+ registered aids and route destination.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_nfc">control Near Field Communication</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_nfc">Allows the app to communicate
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1e59c37..7cf2b78 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -468,6 +468,7 @@
<java-symbol type="string" name="config_deviceSpecificAudioService" />
<java-symbol type="integer" name="config_num_physical_slots" />
<java-symbol type="array" name="config_integrityRuleProviderPackages" />
+ <java-symbol type="bool" name="config_useAssistantVolume" />
<java-symbol type="color" name="tab_indicator_text_v4" />
@@ -3787,6 +3788,9 @@
<java-symbol type="string" name="accessibility_freeform_caption" />
+ <!-- For Wide Color Gamut -->
+ <java-symbol type="bool" name="config_enableWcgMode" />
+
<!-- For contacts provider. -->
<java-symbol type="string" name="config_rawContactsLocalAccountName" />
<java-symbol type="string" name="config_rawContactsLocalAccountType" />
diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java
index 576ac73..5cb7852 100644
--- a/core/tests/coretests/src/android/os/PowerManagerTest.java
+++ b/core/tests/coretests/src/android/os/PowerManagerTest.java
@@ -239,4 +239,17 @@
verify(mListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).onThermalStatusChanged(status);
}
+
+ @Test
+ public void testUserspaceRebootNotSupported_throwsUnsupportedOperationException() {
+ // Can't use assumption framework with AndroidTestCase :(
+ if (mPm.isRebootingUserspaceSupported()) {
+ return;
+ }
+ try {
+ mPm.reboot(PowerManager.REBOOT_USERSPACE);
+ fail("UnsupportedOperationException not thrown");
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
}
diff --git a/data/etc/car/Android.bp b/data/etc/car/Android.bp
index c445651..26a40d3 100644
--- a/data/etc/car/Android.bp
+++ b/data/etc/car/Android.bp
@@ -126,7 +126,7 @@
sub_dir: "permissions",
src: "com.android.car.developeroptions.xml",
filename_from_src: true,
- product_specific: true,
+ system_ext_specific: true,
}
prebuilt_etc {
diff --git a/packages/Tethering/CleanSpec.mk b/data/etc/car/CleanSpec.mk
similarity index 90%
rename from packages/Tethering/CleanSpec.mk
rename to data/etc/car/CleanSpec.mk
index 70db351..18f7d34 100644
--- a/packages/Tethering/CleanSpec.mk
+++ b/data/etc/car/CleanSpec.mk
@@ -43,10 +43,8 @@
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
-
-$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/Tethering)
-$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/InProcessTethering)
-
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product/etc/permissions/com.android.car.developeroptions.xml)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product/etc/permissions/com.android.car.developeroptions.xml)
# ******************************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
# ******************************************************************
diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml
index 07a5617..3997371 100644
--- a/data/etc/hiddenapi-package-whitelist.xml
+++ b/data/etc/hiddenapi-package-whitelist.xml
@@ -65,4 +65,7 @@
<hidden-api-whitelisted-app package="com.android.terminal" />
<hidden-api-whitelisted-app package="com.android.wallpaper" />
<hidden-api-whitelisted-app package="jp.co.omronsoft.openwnn" />
+ <!-- STOPSHIP: Remove this when fixing all @hide usage for tethering.-->
+ <hidden-api-whitelisted-app package="com.android.networkstack.tethering" />
+ <hidden-api-whitelisted-app package="com.android.networkstack" />
</config>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 238afd4..f1941fc 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -266,6 +266,8 @@
</privapp-permissions>
<privapp-permissions package="com.android.shell">
+ <!-- Needed for test only -->
+ <permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
<permission name="android.permission.ACCESS_LOWPAN_STATE"/>
<permission name="android.permission.BACKUP"/>
<permission name="android.permission.BATTERY_STATS"/>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 9917cee..1e98e3a 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1741,6 +1741,12 @@
"group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
"at": "com\/android\/server\/wm\/AppTransition.java"
},
+ "1460759282": {
+ "message": "getAnimationTarget in=%s, out=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
"1469292670": {
"message": "Changing focus from %s to %s displayId=%d Callers=%s",
"level": "VERBOSE",
diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp
index 773353d..ce3bfff 100644
--- a/libs/androidfw/Idmap.cpp
+++ b/libs/androidfw/Idmap.cpp
@@ -43,6 +43,10 @@
return dtohl(e1.overlay_id) < overlay_id;
}
+size_t Idmap_header::Size() const {
+ return sizeof(Idmap_header) + sizeof(uint8_t) * dtohl(debug_info_size);
+}
+
OverlayStringPool::OverlayStringPool(const LoadedIdmap* loaded_idmap)
: data_header_(loaded_idmap->data_header_),
idmap_string_pool_(loaded_idmap->string_pool_.get()) { };
@@ -211,8 +215,8 @@
}
auto header = reinterpret_cast<const Idmap_header*>(idmap_data.data());
- const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(idmap_data.data()) + sizeof(*header);
- size_t data_size = idmap_data.size() - sizeof(*header);
+ const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(idmap_data.data()) + header->Size();
+ size_t data_size = idmap_data.size() - header->Size();
// Currently idmap2 can only generate one data block.
auto data_header = reinterpret_cast<const Idmap_data_header*>(data_ptr);
diff --git a/libs/androidfw/LocaleDataTables.cpp b/libs/androidfw/LocaleDataTables.cpp
index c462eb7..e748bd8 100644
--- a/libs/androidfw/LocaleDataTables.cpp
+++ b/libs/androidfw/LocaleDataTables.cpp
@@ -118,6 +118,7 @@
{0x80600000u, 44u}, // ada -> Latn
{0x90600000u, 44u}, // ade -> Latn
{0xA4600000u, 44u}, // adj -> Latn
+ {0xBC600000u, 88u}, // adp -> Tibt
{0xE0600000u, 16u}, // ady -> Cyrl
{0xE4600000u, 44u}, // adz -> Latn
{0x61650000u, 4u}, // ae -> Avst
@@ -145,6 +146,7 @@
{0xB5800000u, 44u}, // amn -> Latn
{0xB9800000u, 44u}, // amo -> Latn
{0xBD800000u, 44u}, // amp -> Latn
+ {0x616E0000u, 44u}, // an -> Latn
{0x89A00000u, 44u}, // anc -> Latn
{0xA9A00000u, 44u}, // ank -> Latn
{0xB5A00000u, 44u}, // ann -> Latn
@@ -165,6 +167,7 @@
{0xB6200000u, 44u}, // arn -> Latn
{0xBA200000u, 44u}, // aro -> Latn
{0xC2200000u, 1u}, // arq -> Arab
+ {0xCA200000u, 1u}, // ars -> Arab
{0xE2200000u, 1u}, // ary -> Arab
{0xE6200000u, 1u}, // arz -> Arab
{0x61730000u, 7u}, // as -> Beng
@@ -236,7 +239,6 @@
{0x84E10000u, 17u}, // bhb -> Deva
{0x98E10000u, 44u}, // bhg -> Latn
{0xA0E10000u, 17u}, // bhi -> Deva
- {0xA8E10000u, 44u}, // bhk -> Latn
{0xACE10000u, 44u}, // bhl -> Latn
{0xB8E10000u, 17u}, // bho -> Deva
{0xE0E10000u, 44u}, // bhy -> Latn
@@ -332,6 +334,7 @@
{0xB8E20000u, 44u}, // cho -> Latn
{0xBCE20000u, 44u}, // chp -> Latn
{0xC4E20000u, 13u}, // chr -> Cher
+ {0x89020000u, 44u}, // cic -> Latn
{0x81220000u, 1u}, // cja -> Arab
{0xB1220000u, 12u}, // cjm -> Cham
{0xD5220000u, 44u}, // cjv -> Latn
@@ -387,6 +390,7 @@
{0xA1C30000u, 1u}, // doi -> Arab
{0xBDC30000u, 44u}, // dop -> Latn
{0xD9C30000u, 44u}, // dow -> Latn
+ {0x9E230000u, 54u}, // drh -> Mong
{0xA2230000u, 44u}, // dri -> Latn
{0xCA230000u, 19u}, // drs -> Ethi
{0x86430000u, 44u}, // dsb -> Latn
@@ -737,6 +741,7 @@
{0x866A0000u, 19u}, // ktb -> Ethi
{0xB26A0000u, 44u}, // ktm -> Latn
{0xBA6A0000u, 44u}, // kto -> Latn
+ {0xC66A0000u, 44u}, // ktr -> Latn
{0x6B750000u, 44u}, // ku -> Latn
{0x6B754952u, 1u}, // ku-IR -> Arab
{0x6B754C42u, 1u}, // ku-LB -> Arab
@@ -755,8 +760,10 @@
{0x6B770000u, 44u}, // kw -> Latn
{0xA6CA0000u, 44u}, // kwj -> Latn
{0xBACA0000u, 44u}, // kwo -> Latn
+ {0xC2CA0000u, 44u}, // kwq -> Latn
{0x82EA0000u, 44u}, // kxa -> Latn
{0x8AEA0000u, 19u}, // kxc -> Ethi
+ {0x92EA0000u, 44u}, // kxe -> Latn
{0xB2EA0000u, 87u}, // kxm -> Thai
{0xBEEA0000u, 1u}, // kxp -> Arab
{0xDAEA0000u, 44u}, // kxw -> Latn
@@ -766,7 +773,9 @@
{0x6B795452u, 44u}, // ky-TR -> Latn
{0x930A0000u, 44u}, // kye -> Latn
{0xDF0A0000u, 44u}, // kyx -> Latn
+ {0xA72A0000u, 44u}, // kzj -> Latn
{0xC72A0000u, 44u}, // kzr -> Latn
+ {0xCF2A0000u, 44u}, // kzt -> Latn
{0x6C610000u, 44u}, // la -> Latn
{0x840B0000u, 46u}, // lab -> Lina
{0x8C0B0000u, 30u}, // lad -> Hebr
@@ -899,6 +908,7 @@
{0x95AC0000u, 44u}, // mnf -> Latn
{0xA1AC0000u, 7u}, // mni -> Beng
{0xD9AC0000u, 56u}, // mnw -> Mymr
+ {0x6D6F0000u, 44u}, // mo -> Latn
{0x81CC0000u, 44u}, // moa -> Latn
{0x91CC0000u, 44u}, // moe -> Latn
{0x9DCC0000u, 44u}, // moh -> Latn
@@ -1069,6 +1079,7 @@
{0xB5AF0000u, 44u}, // pnn -> Latn
{0xCDAF0000u, 24u}, // pnt -> Grek
{0xB5CF0000u, 44u}, // pon -> Latn
+ {0x81EF0000u, 17u}, // ppa -> Deva
{0xB9EF0000u, 44u}, // ppo -> Latn
{0x822F0000u, 38u}, // pra -> Khar
{0x8E2F0000u, 1u}, // prd -> Arab
@@ -1241,6 +1252,7 @@
{0x8C730000u, 79u}, // tdd -> Tale
{0x98730000u, 17u}, // tdg -> Deva
{0x9C730000u, 17u}, // tdh -> Deva
+ {0xD0730000u, 44u}, // tdu -> Latn
{0x74650000u, 84u}, // te -> Telu
{0x8C930000u, 44u}, // ted -> Latn
{0xB0930000u, 44u}, // tem -> Latn
@@ -1326,6 +1338,7 @@
{0xC5B40000u, 7u}, // unr -> Beng
{0xC5B44E50u, 17u}, // unr-NP -> Deva
{0xDDB40000u, 7u}, // unx -> Beng
+ {0xA9D40000u, 44u}, // uok -> Latn
{0x75720000u, 1u}, // ur -> Arab
{0xA2340000u, 44u}, // uri -> Latn
{0xCE340000u, 44u}, // urt -> Latn
@@ -1479,6 +1492,7 @@
0x904049444C61746ELLU, // ace_Latn_ID
0x9C4055474C61746ELLU, // ach_Latn_UG
0x806047484C61746ELLU, // ada_Latn_GH
+ 0xBC60425454696274LLU, // adp_Tibt_BT
0xE06052554379726CLLU, // ady_Cyrl_RU
0x6165495241767374LLU, // ae_Avst_IR
0x8480544E41726162LLU, // aeb_Arab_TN
@@ -1491,6 +1505,7 @@
0xCD6052554379726CLLU, // alt_Cyrl_RU
0x616D455445746869LLU, // am_Ethi_ET
0xB9804E474C61746ELLU, // amo_Latn_NG
+ 0x616E45534C61746ELLU, // an_Latn_ES
0xE5C049444C61746ELLU, // aoz_Latn_ID
0x8DE0544741726162LLU, // apd_Arab_TG
0x6172454741726162LLU, // ar_Arab_EG
@@ -1500,6 +1515,7 @@
0xB620434C4C61746ELLU, // arn_Latn_CL
0xBA20424F4C61746ELLU, // aro_Latn_BO
0xC220445A41726162LLU, // arq_Arab_DZ
+ 0xCA20534141726162LLU, // ars_Arab_SA
0xE2204D4141726162LLU, // ary_Arab_MA
0xE620454741726162LLU, // arz_Arab_EG
0x6173494E42656E67LLU, // as_Beng_IN
@@ -1537,7 +1553,6 @@
0xDCC154524772656BLLU, // bgx_Grek_TR
0x84E1494E44657661LLU, // bhb_Deva_IN
0xA0E1494E44657661LLU, // bhi_Deva_IN
- 0xA8E150484C61746ELLU, // bhk_Latn_PH
0xB8E1494E44657661LLU, // bho_Deva_IN
0x626956554C61746ELLU, // bi_Latn_VU
0xA90150484C61746ELLU, // bik_Latn_PH
@@ -1584,6 +1599,7 @@
0xB8E255534C61746ELLU, // cho_Latn_US
0xBCE243414C61746ELLU, // chp_Latn_CA
0xC4E2555343686572LLU, // chr_Cher_US
+ 0x890255534C61746ELLU, // cic_Latn_US
0x81224B4841726162LLU, // cja_Arab_KH
0xB122564E4368616DLLU, // cjm_Cham_VN
0x8542495141726162LLU, // ckb_Arab_IQ
@@ -1617,6 +1633,7 @@
0x91234E454C61746ELLU, // dje_Latn_NE
0xA5A343494C61746ELLU, // dnj_Latn_CI
0xA1C3494E41726162LLU, // doi_Arab_IN
+ 0x9E23434E4D6F6E67LLU, // drh_Mong_CN
0x864344454C61746ELLU, // dsb_Latn_DE
0xB2634D4C4C61746ELLU, // dtm_Latn_ML
0xBE634D594C61746ELLU, // dtp_Latn_MY
@@ -1809,6 +1826,7 @@
0x864A545A4C61746ELLU, // ksb_Latn_TZ
0x964A434D4C61746ELLU, // ksf_Latn_CM
0x9E4A44454C61746ELLU, // ksh_Latn_DE
+ 0xC66A4D594C61746ELLU, // ktr_Latn_MY
0x6B75495141726162LLU, // ku_Arab_IQ
0x6B7554524C61746ELLU, // ku_Latn_TR
0xB28A52554379726CLLU, // kum_Cyrl_RU
@@ -1821,6 +1839,8 @@
0x6B79434E41726162LLU, // ky_Arab_CN
0x6B794B474379726CLLU, // ky_Cyrl_KG
0x6B7954524C61746ELLU, // ky_Latn_TR
+ 0xA72A4D594C61746ELLU, // kzj_Latn_MY
+ 0xCF2A4D594C61746ELLU, // kzt_Latn_MY
0x6C6156414C61746ELLU, // la_Latn_VA
0x840B47524C696E61LLU, // lab_Lina_GR
0x8C0B494C48656272LLU, // lad_Hebr_IL
@@ -1893,6 +1913,7 @@
0x6D6E434E4D6F6E67LLU, // mn_Mong_CN
0xA1AC494E42656E67LLU, // mni_Beng_IN
0xD9AC4D4D4D796D72LLU, // mnw_Mymr_MM
+ 0x6D6F524F4C61746ELLU, // mo_Latn_RO
0x91CC43414C61746ELLU, // moe_Latn_CA
0x9DCC43414C61746ELLU, // moh_Latn_CA
0xC9CC42464C61746ELLU, // mos_Latn_BF
@@ -1981,6 +2002,7 @@
0xC98F49544C61746ELLU, // pms_Latn_IT
0xCDAF47524772656BLLU, // pnt_Grek_GR
0xB5CF464D4C61746ELLU, // pon_Latn_FM
+ 0x81EF494E44657661LLU, // ppa_Deva_IN
0x822F504B4B686172LLU, // pra_Khar_PK
0x8E2F495241726162LLU, // prd_Arab_IR
0x7073414641726162LLU, // ps_Arab_AF
@@ -2094,6 +2116,7 @@
0x8C73434E54616C65LLU, // tdd_Tale_CN
0x98734E5044657661LLU, // tdg_Deva_NP
0x9C734E5044657661LLU, // tdh_Deva_NP
+ 0xD0734D594C61746ELLU, // tdu_Latn_MY
0x7465494E54656C75LLU, // te_Telu_IN
0xB093534C4C61746ELLU, // tem_Latn_SL
0xB89355474C61746ELLU, // teo_Latn_UG
diff --git a/libs/androidfw/OWNERS b/libs/androidfw/OWNERS
index 87b1467..8cffd6a 100644
--- a/libs/androidfw/OWNERS
+++ b/libs/androidfw/OWNERS
@@ -3,3 +3,4 @@
rtmitchell@google.com
per-file CursorWindow.cpp=omakoto@google.com
+per-file LocaleDataTables.cpp=vichang@google.com,tobiast@google.com,nikitai@google.com
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index b20e657..b603326 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -39,7 +39,7 @@
namespace android {
constexpr const static uint32_t kIdmapMagic = 0x504D4449u;
-constexpr const static uint32_t kIdmapCurrentVersion = 0x00000002u;
+constexpr const static uint32_t kIdmapCurrentVersion = 0x00000003u;
/**
* In C++11, char16_t is defined as *at least* 16 bits. We do a lot of
@@ -1724,6 +1724,11 @@
uint8_t target_path[256];
uint8_t overlay_path[256];
+
+ uint32_t debug_info_size;
+ uint8_t debug_info[0];
+
+ size_t Size() const;
};
struct Idmap_data_header {
diff --git a/libs/androidfw/tests/data/overlay/overlay.apk b/libs/androidfw/tests/data/overlay/overlay.apk
index c594b8e..62e9866 100644
--- a/libs/androidfw/tests/data/overlay/overlay.apk
+++ b/libs/androidfw/tests/data/overlay/overlay.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/overlay/overlay.idmap b/libs/androidfw/tests/data/overlay/overlay.idmap
index 27cf792f..3759ed6 100644
--- a/libs/androidfw/tests/data/overlay/overlay.idmap
+++ b/libs/androidfw/tests/data/overlay/overlay.idmap
Binary files differ
diff --git a/location/java/android/location/LocationListener.java b/location/java/android/location/LocationListener.java
index aa9dddc..8df0834 100644
--- a/location/java/android/location/LocationListener.java
+++ b/location/java/android/location/LocationListener.java
@@ -16,6 +16,7 @@
package android.location;
+import android.annotation.NonNull;
import android.os.Bundle;
/**
@@ -37,36 +38,32 @@
/**
* Called when the location has changed.
*
- * <p> There are no restrictions on the use of the supplied Location object.
- *
- * @param location The new location, as a Location object.
+ * @param location the updated location
*/
- void onLocationChanged(Location location);
+ void onLocationChanged(@NonNull Location location);
/**
- * This callback will never be invoked and providers can be considers as always in the
- * {@link LocationProvider#AVAILABLE} state.
+ * This callback will never be invoked on Android Q and above, and providers can be considered
+ * as always in the {@link LocationProvider#AVAILABLE} state.
*
- * @deprecated This callback will never be invoked.
+ * @deprecated This callback will never be invoked on Android Q and above.
*/
@Deprecated
- void onStatusChanged(String provider, int status, Bundle extras);
+ default void onStatusChanged(String provider, int status, Bundle extras) {}
/**
* Called when the provider is enabled by the user.
*
- * @param provider the name of the location provider associated with this
- * update.
+ * @param provider the name of the location provider that has become enabled
*/
- void onProviderEnabled(String provider);
+ default void onProviderEnabled(@NonNull String provider) {}
/**
* Called when the provider is disabled by the user. If requestLocationUpdates
* is called on an already disabled provider, this method is called
* immediately.
*
- * @param provider the name of the location provider associated with this
- * update.
+ * @param provider the name of the location provider that has become disabled
*/
- void onProviderDisabled(String provider);
+ default void onProviderDisabled(@NonNull String provider) {}
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index c8a7ef5..34ed5b3 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -374,6 +374,10 @@
public static final int STREAM_TTS = AudioSystem.STREAM_TTS;
/** Used to identify the volume of audio streams for accessibility prompts */
public static final int STREAM_ACCESSIBILITY = AudioSystem.STREAM_ACCESSIBILITY;
+ /** @hide Used to identify the volume of audio streams for virtual assistant */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public static final int STREAM_ASSISTANT = AudioSystem.STREAM_ASSISTANT;
/** Number of audio streams */
/**
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 8e76fcf..e584add 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -80,6 +80,8 @@
public static final int STREAM_TTS = 9;
/** Used to identify the volume of audio streams for accessibility prompts */
public static final int STREAM_ACCESSIBILITY = 10;
+ /** Used to identify the volume of audio streams for virtual assistant */
+ public static final int STREAM_ASSISTANT = 11;
/**
* @deprecated Use {@link #numStreamTypes() instead}
*/
@@ -92,7 +94,7 @@
private static native int native_get_FCC_8();
// Expose only the getter method publicly so we can change it in the future
- private static final int NUM_STREAM_TYPES = 11;
+ private static final int NUM_STREAM_TYPES = 12;
@UnsupportedAppUsage
public static final int getNumStreamTypes() { return NUM_STREAM_TYPES; }
@@ -107,7 +109,8 @@
"STREAM_SYSTEM_ENFORCED",
"STREAM_DTMF",
"STREAM_TTS",
- "STREAM_ACCESSIBILITY"
+ "STREAM_ACCESSIBILITY",
+ "STREAM_ASSISTANT"
};
/*
@@ -1277,6 +1280,7 @@
5, // STREAM_DTMF
5, // STREAM_TTS
5, // STREAM_ACCESSIBILITY
+ 5, // STREAM_ASSISTANT
};
public static String streamToString(int stream) {
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index 14a48d7..58c73b5 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -676,10 +676,9 @@
throw new IllegalArgumentException("bufferInfo must not be null");
}
if (bufferInfo.size < 0 || bufferInfo.offset < 0
- || (bufferInfo.offset + bufferInfo.size) > byteBuf.capacity()
- || bufferInfo.presentationTimeUs < 0) {
+ || (bufferInfo.offset + bufferInfo.size) > byteBuf.capacity()) {
throw new IllegalArgumentException("bufferInfo must specify a" +
- " valid buffer offset, size and presentation time");
+ " valid buffer offset and size");
}
if (mNativeObject == 0) {
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 445420f..7008d32 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -249,20 +249,34 @@
return mExtras;
}
+ /**
+ * Returns if the route supports the specified control category
+ *
+ * @param controlCategory control category to consider
+ * @return true if the route supports at the category
+ */
+ public boolean supportsControlCategory(@NonNull String controlCategory) {
+ Objects.requireNonNull(controlCategory, "control category must not be null");
+ for (String supportedCategory : getSupportedCategories()) {
+ if (TextUtils.equals(controlCategory, supportedCategory)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
//TODO: Move this if we re-define control category / selector things.
/**
- * Returns true if the route supports at least one of the specified control categories
+ * Returns if the route supports at least one of the specified control categories
*
* @param controlCategories the list of control categories to consider
* @return true if the route supports at least one category
*/
- public boolean supportsControlCategory(@NonNull Collection<String> controlCategories) {
+ public boolean supportsControlCategories(@NonNull Collection<String> controlCategories) {
Objects.requireNonNull(controlCategories, "control categories must not be null");
for (String controlCategory : controlCategories) {
- for (String supportedCategory : getSupportedCategories()) {
- if (TextUtils.equals(controlCategory, supportedCategory)) {
- return true;
- }
+ if (supportsControlCategory(controlCategory)) {
+ return true;
}
}
return false;
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index bad0ef4..f9dabcf 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -271,7 +271,7 @@
List<MediaRoute2Info> filteredRoutes = new ArrayList<>();
for (MediaRoute2Info route : mRoutes.values()) {
- if (route.supportsControlCategory(mControlCategories)) {
+ if (route.supportsControlCategories(mControlCategories)) {
filteredRoutes.add(route);
}
}
@@ -399,8 +399,8 @@
mControlCategories = newControlCategories;
for (MediaRoute2Info route : mRoutes.values()) {
- boolean preSupported = route.supportsControlCategory(prevControlCategories);
- boolean postSupported = route.supportsControlCategory(newControlCategories);
+ boolean preSupported = route.supportsControlCategories(prevControlCategories);
+ boolean postSupported = route.supportsControlCategories(newControlCategories);
if (preSupported == postSupported) {
continue;
}
@@ -430,7 +430,7 @@
synchronized (sLock) {
for (MediaRoute2Info route : routes) {
mRoutes.put(route.getUniqueId(), route);
- if (route.supportsControlCategory(mControlCategories)) {
+ if (route.supportsControlCategories(mControlCategories)) {
addedRoutes.add(route);
}
}
@@ -446,7 +446,7 @@
synchronized (sLock) {
for (MediaRoute2Info route : routes) {
mRoutes.remove(route.getUniqueId());
- if (route.supportsControlCategory(mControlCategories)) {
+ if (route.supportsControlCategories(mControlCategories)) {
removedRoutes.add(route);
}
}
@@ -462,7 +462,7 @@
synchronized (sLock) {
for (MediaRoute2Info route : routes) {
mRoutes.put(route.getUniqueId(), route);
- if (route.supportsControlCategory(mControlCategories)) {
+ if (route.supportsControlCategories(mControlCategories)) {
changedRoutes.add(route);
}
}
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 502538d..5de3370 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -25,6 +25,7 @@
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
@@ -163,7 +164,7 @@
List<MediaRoute2Info> routes = new ArrayList<>();
synchronized (mRoutesLock) {
for (MediaRoute2Info route : mRoutes.values()) {
- if (route.supportsControlCategory(controlCategories)) {
+ if (route.supportsControlCategories(controlCategories)) {
routes.add(route);
}
}
@@ -172,6 +173,34 @@
}
/**
+ * Gets the list of routes that are actively used by {@link MediaRouter2}.
+ */
+ @NonNull
+ public List<MediaRoute2Info> getActiveRoutes() {
+ List<MediaRoute2Info> routes = new ArrayList<>();
+ synchronized (mRoutesLock) {
+ for (MediaRoute2Info route : mRoutes.values()) {
+ if (!TextUtils.isEmpty(route.getClientPackageName())) {
+ routes.add(route);
+ }
+ }
+ }
+ return routes;
+ }
+
+ /**
+ * Gets the list of discovered routes
+ */
+ @NonNull
+ public List<MediaRoute2Info> getAllRoutes() {
+ List<MediaRoute2Info> routes = new ArrayList<>();
+ synchronized (mRoutesLock) {
+ routes.addAll(mRoutes.values());
+ }
+ return routes;
+ }
+
+ /**
* Selects media route for the specified package name.
*
* @param packageName the package name of the application that should change it's media route
diff --git a/media/java/android/media/tv/tuner/FrontendSettings.java b/media/java/android/media/tv/tuner/FrontendSettings.java
index 3782cc6..531e210 100644
--- a/media/java/android/media/tv/tuner/FrontendSettings.java
+++ b/media/java/android/media/tv/tuner/FrontendSettings.java
@@ -16,15 +16,22 @@
package android.media.tv.tuner;
+import android.annotation.SystemApi;
import android.media.tv.tuner.TunerConstants.FrontendSettingsType;
import java.util.List;
/**
+ * Frontend settings for tune and scan operations.
* @hide
*/
+@SystemApi
public abstract class FrontendSettings {
- protected int mFrequency;
+ private final int mFrequency;
+
+ FrontendSettings(int frequency) {
+ mFrequency = frequency;
+ }
/**
* Returns the frontend type.
@@ -32,7 +39,12 @@
@FrontendSettingsType
public abstract int getType();
- public int getFrequency() {
+ /**
+ * Gets the frequency setting.
+ *
+ * @return the frequency in Hz.
+ */
+ public final int getFrequency() {
return mFrequency;
}
@@ -42,6 +54,7 @@
/**
* Frontend settings for analog.
+ * @hide
*/
public static class FrontendAnalogSettings extends FrontendSettings {
private int mAnalogType;
@@ -68,7 +81,7 @@
}
private FrontendAnalogSettings(int frequency, int analogType, int sifStandard) {
- mFrequency = frequency;
+ super(frequency);
mAnalogType = analogType;
mSifStandard = sifStandard;
}
@@ -118,10 +131,15 @@
/**
* Frontend settings for ATSC.
+ * @hide
*/
public static class FrontendAtscSettings extends FrontendSettings {
public int modulation;
+ FrontendAtscSettings(int frequency) {
+ super(frequency);
+ }
+
@Override
public int getType() {
return TunerConstants.FRONTEND_TYPE_ATSC;
@@ -130,12 +148,17 @@
/**
* Frontend settings for ATSC-3.
+ * @hide
*/
public static class FrontendAtsc3Settings extends FrontendSettings {
public int bandwidth;
public byte demodOutputFormat;
public List<FrontendAtsc3PlpSettings> plpSettings;
+ FrontendAtsc3Settings(int frequency) {
+ super(frequency);
+ }
+
@Override
public int getType() {
return TunerConstants.FRONTEND_TYPE_ATSC3;
@@ -144,6 +167,7 @@
/**
* Frontend settings for DVBS.
+ * @hide
*/
public static class FrontendDvbsSettings extends FrontendSettings {
public int modulation;
@@ -154,6 +178,10 @@
public int inputStreamId;
public byte standard;
+ FrontendDvbsSettings(int frequency) {
+ super(frequency);
+ }
+
@Override
public int getType() {
return TunerConstants.FRONTEND_TYPE_DVBS;
@@ -162,6 +190,7 @@
/**
* Frontend settings for DVBC.
+ * @hide
*/
public static class FrontendDvbcSettings extends FrontendSettings {
public int modulation;
@@ -171,6 +200,10 @@
public byte annex;
public int spectralInversion;
+ FrontendDvbcSettings(int frequency) {
+ super(frequency);
+ }
+
@Override
public int getType() {
return TunerConstants.FRONTEND_TYPE_DVBC;
@@ -179,6 +212,7 @@
/**
* Frontend settings for DVBT.
+ * @hide
*/
public static class FrontendDvbtSettings extends FrontendSettings {
public int transmissionMode;
@@ -195,6 +229,10 @@
public byte plpId;
public byte plpGroupId;
+ FrontendDvbtSettings(int frequency) {
+ super(frequency);
+ }
+
@Override
public int getType() {
return TunerConstants.FRONTEND_TYPE_DVBT;
@@ -203,6 +241,7 @@
/**
* Frontend settings for ISDBS.
+ * @hide
*/
public static class FrontendIsdbsSettings extends FrontendSettings {
public int streamId;
@@ -212,6 +251,10 @@
public int symbolRate;
public int rolloff;
+ FrontendIsdbsSettings(int frequency) {
+ super(frequency);
+ }
+
@Override
public int getType() {
return TunerConstants.FRONTEND_TYPE_ISDBS;
@@ -220,6 +263,7 @@
/**
* Frontend settings for ISDBS-3.
+ * @hide
*/
public static class FrontendIsdbs3Settings extends FrontendSettings {
public int streamId;
@@ -229,6 +273,10 @@
public int symbolRate;
public int rolloff;
+ FrontendIsdbs3Settings(int frequency) {
+ super(frequency);
+ }
+
@Override
public int getType() {
return TunerConstants.FRONTEND_TYPE_ISDBS3;
@@ -237,6 +285,7 @@
/**
* Frontend settings for ISDBT.
+ * @hide
*/
public static class FrontendIsdbtSettings extends FrontendSettings {
public int modulation;
@@ -245,6 +294,10 @@
public int guardInterval;
public int serviceAreaId;
+ FrontendIsdbtSettings(int frequency) {
+ super(frequency);
+ }
+
@Override
public int getType() {
return TunerConstants.FRONTEND_TYPE_ISDBT;
@@ -253,6 +306,7 @@
/**
* PLP settings for ATSC-3.
+ * @hide
*/
public static class FrontendAtsc3PlpSettings {
public byte plpId;
@@ -264,6 +318,7 @@
/**
* Code rate for DVBS.
+ * @hide
*/
public static class FrontendDvbsCodeRate {
public long fec;
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 4c93101..4947700 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -18,6 +18,10 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.content.pm.PackageManager;
import android.media.tv.tuner.TunerConstants.DemuxPidType;
import android.os.Handler;
import android.os.Looper;
@@ -26,14 +30,20 @@
import java.util.List;
/**
- * Tuner is used to interact with tuner devices.
+ * This class is used to interact with hardware tuners devices.
+ *
+ * <p> Each TvInputService Session should create one instance of this class.
+ *
+ * <p> This class controls the TIS interaction with Tuner HAL.
*
* @hide
*/
+@SystemApi
public final class Tuner implements AutoCloseable {
private static final String TAG = "MediaTvTuner";
private static final boolean DEBUG = false;
+ private static final String PERMISSION = android.Manifest.permission.ACCESS_TV_TUNER;
private static final int MSG_ON_FRONTEND_EVENT = 1;
private static final int MSG_ON_FILTER_EVENT = 2;
private static final int MSG_ON_FILTER_STATUS = 3;
@@ -44,6 +54,8 @@
nativeInit();
}
+ private final Context mContext;
+
private List<Integer> mFrontendIds;
private Frontend mFrontend;
private EventHandler mHandler;
@@ -51,12 +63,26 @@
private List<Integer> mLnbIds;
private Lnb mLnb;
- public Tuner() {
+ /**
+ * Constructs a Tuner instance.
+ *
+ * @param context context of the caller.
+ */
+ public Tuner(@NonNull Context context) {
+ mContext = context;
nativeSetup();
}
+ private void checkPermission() {
+ if (mContext.checkCallingOrSelfPermission(PERMISSION)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Caller must have " + PERMISSION + " permission.");
+ }
+ }
+
private long mNativeContext; // used by native jMediaTuner
+ /** @hide */
@Override
public void close() {}
@@ -92,6 +118,8 @@
/**
* Frontend Callback.
+ *
+ * @hide
*/
public interface FrontendCallback {
@@ -103,6 +131,8 @@
/**
* LNB Callback.
+ *
+ * @hide
*/
public interface LnbCallback {
/**
@@ -113,6 +143,8 @@
/**
* Frontend Callback.
+ *
+ * @hide
*/
public interface FilterCallback {
/**
@@ -123,6 +155,8 @@
/**
* DVR Callback.
+ *
+ * @hide
*/
public interface DvrCallback {
/**
@@ -177,7 +211,7 @@
}
}
- protected class Frontend {
+ private class Frontend {
private int mId;
private FrontendCallback mCallback;
@@ -210,9 +244,15 @@
}
/**
- * Tunes the frontend to using the settings given.
+ * Tunes the frontend to the settings given.
+ *
+ * @return result status of tune operation.
+ * @throws SecurityException if the caller does not have appropriate permissions.
+ * TODO: add result constants or throw exceptions.
*/
+ @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
public int tune(@NonNull FrontendSettings settings) {
+ checkPermission();
return nativeTune(settings.getType(), settings);
}
@@ -238,7 +278,8 @@
}
}
- protected class Filter {
+ /** @hide */
+ public class Filter {
private long mNativeContext;
private FilterCallback mCallback;
int mId;
@@ -297,7 +338,8 @@
return filter;
}
- protected class Lnb {
+ /** @hide */
+ public class Lnb {
private int mId;
private LnbCallback mCallback;
@@ -338,7 +380,15 @@
}
}
- protected class Descrambler {
+ /**
+ * This class is used to interact with descramblers.
+ *
+ * <p> Descrambler is a hardware component used to descramble data.
+ *
+ * <p> This class controls the TIS interaction with Tuner HAL.
+ *
+ */
+ public class Descrambler {
private long mNativeContext;
private native boolean nativeAddPid(int pidType, int pid, Filter filter);
@@ -346,23 +396,33 @@
private Descrambler() {}
- private boolean addPid(@DemuxPidType int pidType, int pid, Filter filter) {
+ /** @hide */
+ public boolean addPid(@DemuxPidType int pidType, int pid, Filter filter) {
return nativeAddPid(pidType, pid, filter);
}
- private boolean removePid(@DemuxPidType int pidType, int pid, Filter filter) {
+ /** @hide */
+ public boolean removePid(@DemuxPidType int pidType, int pid, Filter filter) {
return nativeRemovePid(pidType, pid, filter);
}
}
- private Descrambler openDescrambler() {
- Descrambler descrambler = nativeOpenDescrambler();
- return descrambler;
+ /**
+ * Opens a Descrambler in tuner.
+ *
+ * @return a {@link Descrambler} object.
+ */
+ @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
+ @Nullable
+ public Descrambler openDescrambler() {
+ checkPermission();
+ return nativeOpenDescrambler();
}
// TODO: consider splitting Dvr to Playback and Recording
- protected class Dvr {
+ /** @hide */
+ public class Dvr {
private long mNativeContext;
private DvrCallback mCallback;
diff --git a/media/jni/android_media_MediaExtractor.h b/media/jni/android_media_MediaExtractor.h
index baa779c..f5ba92e 100644
--- a/media/jni/android_media_MediaExtractor.h
+++ b/media/jni/android_media_MediaExtractor.h
@@ -19,7 +19,7 @@
#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AudioPresentationInfo.h>
-#include <media/MediaSource.h>
+#include <media/stagefright/MediaSource.h>
#include <media/DataSource.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
index b380aff..2772aa4 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -256,6 +256,37 @@
}
}
+ @Test
+ public void testGetActiveRoutes() throws Exception {
+ CountDownLatch latch = new CountDownLatch(1);
+ CountDownLatch latch2 = new CountDownLatch(1);
+
+ Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(CATEGORIES_ALL);
+ addRouterCallback(new MediaRouter2.Callback());
+ addManagerCallback(new MediaRouter2Manager.Callback() {
+ @Override
+ public void onRouteSelected(String packageName, MediaRoute2Info route) {
+ if (TextUtils.equals(mPackageName, packageName)
+ && route != null && TextUtils.equals(route.getId(), ROUTE_ID1)) {
+ latch.countDown();
+ }
+ }
+ });
+
+ assertEquals(0, mManager.getActiveRoutes().size());
+
+ mManager.selectRoute(mPackageName, routes.get(ROUTE_ID1));
+ latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+
+ assertEquals(1, mManager.getActiveRoutes().size());
+
+ awaitOnRouteChangedManager(
+ () -> mManager.unselectRoute(mPackageName),
+ ROUTE_ID1,
+ route -> TextUtils.equals(route.getClientPackageName(), null));
+ assertEquals(0, mManager.getActiveRoutes().size());
+ }
+
/**
* Tests selecting and unselecting routes of a single provider.
*/
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 177f2b8..203adfc 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -40,6 +40,7 @@
AConfiguration_getOrientation;
AConfiguration_getScreenHeightDp; # introduced-arm=13 introduced-arm64=21 introduced-mips=13 introduced-mips64=21 introduced-x86=13 introduced-x86_64=21
AConfiguration_getScreenLong;
+ AConfiguration_getScreenRound; # introduced=30
AConfiguration_getScreenSize;
AConfiguration_getScreenWidthDp; # introduced-arm=13 introduced-arm64=21 introduced-mips=13 introduced-mips64=21 introduced-x86=13 introduced-x86_64=21
AConfiguration_getSdkVersion;
diff --git a/packages/CompanionDeviceManager/Android.bp b/packages/CompanionDeviceManager/Android.bp
index a379bfc..1453ec3 100644
--- a/packages/CompanionDeviceManager/Android.bp
+++ b/packages/CompanionDeviceManager/Android.bp
@@ -15,5 +15,6 @@
android_app {
name: "CompanionDeviceManager",
srcs: ["src/**/*.java"],
+
platform_apis: true,
}
diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml
index 42885e8..a9c6685 100644
--- a/packages/CompanionDeviceManager/AndroidManifest.xml
+++ b/packages/CompanionDeviceManager/AndroidManifest.xml
@@ -29,6 +29,7 @@
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+ <uses-permission android:name="android.permission.RADIO_SCAN_WITHOUT_LOCATION"/>
<application
android:allowClearUserData="true"
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 7b2922ba..1e19786 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -102,6 +102,9 @@
DocumentsContract.EXTERNAL_STORAGE_PRIMARY_EMULATED_ROOT_ID;
private static final String ROOT_ID_HOME = "home";
+ private static final String GET_DOCUMENT_URI_CALL = "get_document_uri";
+ private static final String GET_MEDIA_URI_CALL = "get_media_uri";
+
private StorageManager mStorageManager;
private UserManager mUserManager;
@@ -665,7 +668,7 @@
}
break;
}
- case MediaStore.GET_DOCUMENT_URI_CALL: {
+ case GET_DOCUMENT_URI_CALL: {
// All callers must go through MediaProvider
getContext().enforceCallingPermission(
android.Manifest.permission.WRITE_MEDIA_STORAGE, TAG);
@@ -684,7 +687,7 @@
throw new IllegalStateException("File in " + path + " is not found.", e);
}
}
- case MediaStore.GET_MEDIA_URI_CALL: {
+ case GET_MEDIA_URI_CALL: {
// All callers must go through MediaProvider
getContext().enforceCallingPermission(
android.Manifest.permission.WRITE_MEDIA_STORAGE, TAG);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java
index e936c35..68a3729 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java
@@ -17,8 +17,7 @@
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
-import android.util.LongSparseLongArray;
-import android.util.Pair;
+import android.util.LongSparseArray;
import org.junit.Before;
import org.junit.Ignore;
@@ -159,14 +158,11 @@
private OpEntry createOpEntryWithTime(int op, long time) {
// Slot for background access timestamp.
- final LongSparseLongArray accessTimes = new LongSparseLongArray();
- accessTimes.put(AppOpsManager.makeKey(AppOpsManager.UID_STATE_BACKGROUND,
- AppOpsManager.OP_FLAG_SELF), time);
+ final LongSparseArray<AppOpsManager.NoteOpEvent> accessEvents = new LongSparseArray<>();
+ accessEvents.put(AppOpsManager.makeKey(AppOpsManager.UID_STATE_BACKGROUND,
+ AppOpsManager.OP_FLAG_SELF), new AppOpsManager.NoteOpEvent(time, -1, null));
- OpFeatureEntry.Builder featureEntry = new OpFeatureEntry.Builder(false, accessTimes,
- null /*rejectTimes*/, null /*durations*/, null /* proxyUids */,
- null /* proxyPackages */, null /* proxyFeatureIds */);
- return new OpEntry(op, AppOpsManager.MODE_ALLOWED,
- new Pair[]{new Pair(null, featureEntry)});
+ return new OpEntry(op, AppOpsManager.MODE_ALLOWED, Collections.singletonMap(null,
+ new OpFeatureEntry(op, false, accessEvents, null)));
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
index 3fde48b..3f8d758 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
@@ -17,6 +17,7 @@
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.LongSparseArray;
import android.util.LongSparseLongArray;
import android.util.Pair;
@@ -158,17 +159,11 @@
}
private OpEntry createOpEntryWithTime(int op, long time, int duration) {
- final LongSparseLongArray accessTimes = new LongSparseLongArray();
- accessTimes.put(AppOpsManager.makeKey(AppOpsManager.UID_STATE_TOP,
- AppOpsManager.OP_FLAG_SELF), time);
- final LongSparseLongArray durations = new LongSparseLongArray();
- durations.put(AppOpsManager.makeKey(AppOpsManager.UID_STATE_TOP,
- AppOpsManager.OP_FLAG_SELF), duration);
+ final LongSparseArray<AppOpsManager.NoteOpEvent> accessEvents = new LongSparseArray<>();
+ accessEvents.put(AppOpsManager.makeKey(AppOpsManager.UID_STATE_TOP,
+ AppOpsManager.OP_FLAG_SELF), new AppOpsManager.NoteOpEvent(time, duration, null));
- OpFeatureEntry.Builder featureEntry = new OpFeatureEntry.Builder(false, accessTimes,
- null /*rejectTimes*/, durations, null /* proxyUids */,
- null /* proxyPackages */, null /* proxyFeatureIds */);
- return new OpEntry(op, AppOpsManager.MODE_ALLOWED,
- new Pair[]{new Pair(null, featureEntry)});
+ return new OpEntry(op, AppOpsManager.MODE_ALLOWED, Collections.singletonMap(null,
+ new OpFeatureEntry(op, false, accessEvents, null)));
}
}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 19ff244..443811f 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -87,6 +87,7 @@
Settings.System.VOLUME_ACCESSIBILITY, // used internally, changing value will
// not change volume
Settings.System.VOLUME_ALARM, // deprecated since API 2?
+ Settings.System.VOLUME_ASSISTANT, // candidate for backup?
Settings.System.VOLUME_BLUETOOTH_SCO, // deprecated since API 2?
Settings.System.VOLUME_MASTER, // candidate for backup?
Settings.System.VOLUME_MUSIC, // deprecated since API 2?
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 9bba2aa..fb7a269 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -92,7 +92,6 @@
import android.util.SparseBooleanArray;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.widget.LockPatternUtils;
@@ -1060,7 +1059,7 @@
if (DEBUG_SIM_STATES) {
Log.v(TAG, "action " + action
+ " state: " + intent.getStringExtra(
- IccCardConstants.INTENT_KEY_ICC_STATE)
+ Intent.EXTRA_SIM_STATE)
+ " slotId: " + args.slotId + " subid: " + args.subId);
}
mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
@@ -1236,38 +1235,38 @@
if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
}
- String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+ String stateExtra = intent.getStringExtra(Intent.EXTRA_SIM_STATE);
int slotId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0);
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
- if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+ if (Intent.SIM_STATE_ABSENT.equals(stateExtra)) {
final String absentReason = intent
- .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+ .getStringExtra(Intent.EXTRA_SIM_LOCKED_REASON);
- if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
+ if (Intent.SIM_ABSENT_ON_PERM_DISABLED.equals(
absentReason)) {
state = TelephonyManager.SIM_STATE_PERM_DISABLED;
} else {
state = TelephonyManager.SIM_STATE_ABSENT;
}
- } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+ } else if (Intent.SIM_STATE_READY.equals(stateExtra)) {
state = TelephonyManager.SIM_STATE_READY;
- } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+ } else if (Intent.SIM_STATE_LOCKED.equals(stateExtra)) {
final String lockedReason = intent
- .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
- if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+ .getStringExtra(Intent.EXTRA_SIM_LOCKED_REASON);
+ if (Intent.SIM_LOCKED_ON_PIN.equals(lockedReason)) {
state = TelephonyManager.SIM_STATE_PIN_REQUIRED;
- } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+ } else if (Intent.SIM_LOCKED_ON_PUK.equals(lockedReason)) {
state = TelephonyManager.SIM_STATE_PUK_REQUIRED;
} else {
state = TelephonyManager.SIM_STATE_UNKNOWN;
}
- } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
+ } else if (Intent.SIM_LOCKED_NETWORK.equals(stateExtra)) {
state = TelephonyManager.SIM_STATE_NETWORK_LOCKED;
- } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
+ } else if (Intent.SIM_STATE_CARD_IO_ERROR.equals(stateExtra)) {
state = TelephonyManager.SIM_STATE_CARD_IO_ERROR;
- } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
- || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
+ } else if (Intent.SIM_STATE_LOADED.equals(stateExtra)
+ || Intent.SIM_STATE_IMSI.equals(stateExtra)) {
// This is required because telephony doesn't return to "READY" after
// these state transitions. See bug 7197471.
state = TelephonyManager.SIM_STATE_READY;
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 29a7167..e50d08c 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -108,12 +108,13 @@
if (mController != null) {
mController.addCallback(this /* StateListener */);
}
- mEglHelper = new EglHelper();
- mRenderer = new ImageWallpaperRenderer(context, this /* SurfaceProxy */);
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
+ mEglHelper = new EglHelper();
+ // Deferred init renderer because we need to get wallpaper by display context.
+ mRenderer = new ImageWallpaperRenderer(getDisplayContext(), this /* SurfaceProxy */);
setFixedSizeAllowed(true);
setOffsetNotificationsEnabled(true);
updateSurfaceSize();
@@ -177,14 +178,13 @@
mRenderer = null;
mEglHelper.finish();
mEglHelper = null;
- getSurfaceHolder().getSurface().hwuiDestroy();
});
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
mWorker.getThreadHandler().post(() -> {
- mEglHelper.init(holder);
+ mEglHelper.init(holder, needSupportWideColorGamut());
mRenderer.onSurfaceCreated();
});
}
@@ -257,7 +257,7 @@
// Check if we need to recreate egl surface.
if (mEglHelper.hasEglContext() && !mEglHelper.hasEglSurface()) {
- if (!mEglHelper.createEglSurface(getSurfaceHolder())) {
+ if (!mEglHelper.createEglSurface(getSurfaceHolder(), needSupportWideColorGamut())) {
Log.w(TAG, "recreate egl surface failed!");
}
}
@@ -340,6 +340,10 @@
&& mController.getState() == StatusBarState.KEYGUARD;
}
+ private boolean needSupportWideColorGamut() {
+ return mRenderer.isWcgContent();
+ }
+
@Override
protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
super.dump(prefix, fd, out, args);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index e3694ac..bfac4fc 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -16,6 +16,8 @@
package com.android.systemui.accessibility;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+
import android.content.Context;
import android.content.res.Resources;
import android.graphics.PixelFormat;
@@ -196,6 +198,7 @@
params.token = mOverlayView.getWindowToken();
params.x = mMagnificationFrame.left;
params.y = mMagnificationFrame.top;
+ params.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
params.setTitle(mContext.getString(R.string.magnification_window_title));
mMirrorView = LayoutInflater.from(mContext).inflate(R.layout.window_magnifier_view, null);
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
index c6812a7..4b28540 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
@@ -51,40 +51,65 @@
import android.opengl.EGLDisplay;
import android.opengl.EGLSurface;
import android.opengl.GLUtils;
+import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceHolder;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
/**
* A helper class to handle EGL management.
*/
public class EglHelper {
private static final String TAG = EglHelper.class.getSimpleName();
+ private static final int OPENGLES_VERSION = 2;
// Below two constants make drawing at low priority, so other things can preempt our drawing.
private static final int EGL_CONTEXT_PRIORITY_LEVEL_IMG = 0x3100;
private static final int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103;
private static final boolean DEBUG = true;
+
+ private static final int EGL_GL_COLORSPACE_KHR = 0x309D;
+ private static final int EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT = 0x3490;
+
private static final String EGL_IMG_CONTEXT_PRIORITY = "EGL_IMG_context_priority";
+ /**
+ * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_gl_colorspace.txt
+ */
+ private static final String KHR_GL_COLOR_SPACE = "EGL_KHR_gl_colorspace";
+
+ /**
+ * https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_gl_colorspace_display_p3_passthrough.txt
+ */
+ private static final String EXT_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH =
+ "EGL_EXT_gl_colorspace_display_p3_passthrough";
+
private EGLDisplay mEglDisplay;
private EGLConfig mEglConfig;
private EGLContext mEglContext;
private EGLSurface mEglSurface;
private final int[] mEglVersion = new int[2];
private boolean mEglReady;
- private boolean mContextPrioritySupported;
+ private final Set<String> mExts;
+
+ public EglHelper() {
+ mExts = new HashSet<>();
+ connectDisplay();
+ }
/**
- * Initialize EGL and prepare EglSurface.
+ * Initialize render context.
* @param surfaceHolder surface holder.
- * @return true if EglSurface is ready.
+ * @param wideColorGamut claim if a wcg surface is necessary.
+ * @return true if the render context is ready.
*/
- public boolean init(SurfaceHolder surfaceHolder) {
- mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (mEglDisplay == EGL_NO_DISPLAY) {
- Log.w(TAG, "eglGetDisplay failed: " + GLUtils.getEGLErrorString(eglGetError()));
+ public boolean init(SurfaceHolder surfaceHolder, boolean wideColorGamut) {
+ if (!hasEglDisplay() && !connectDisplay()) {
+ Log.w(TAG, "Can not connect display, abort!");
return false;
}
@@ -105,25 +130,38 @@
return false;
}
- if (!createEglSurface(surfaceHolder)) {
+ if (!createEglSurface(surfaceHolder, wideColorGamut)) {
Log.w(TAG, "Can't create EGLSurface!");
return false;
}
- mContextPrioritySupported = isContextPrioritySuppported();
-
mEglReady = true;
return true;
}
- private boolean isContextPrioritySuppported() {
- String[] extensions = eglQueryString(mEglDisplay, EGL_EXTENSIONS).split(" ");
- for (String extension : extensions) {
- if (extension.equals(EGL_IMG_CONTEXT_PRIORITY)) {
- return true;
- }
+ private boolean connectDisplay() {
+ mExts.clear();
+ mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (!hasEglDisplay()) {
+ Log.w(TAG, "eglGetDisplay failed: " + GLUtils.getEGLErrorString(eglGetError()));
+ return false;
}
- return false;
+ String queryString = eglQueryString(mEglDisplay, EGL_EXTENSIONS);
+ if (!TextUtils.isEmpty(queryString)) {
+ Collections.addAll(mExts, queryString.split(" "));
+ }
+ return true;
+ }
+
+ private boolean checkExtensionCapability(String extName) {
+ return mExts.contains(extName);
+ }
+
+ private int getWcgCapability() {
+ if (checkExtensionCapability(EXT_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH)) {
+ return EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT;
+ }
+ return 0;
}
private EGLConfig chooseEglConfig() {
@@ -148,7 +186,7 @@
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 8,
+ EGL_ALPHA_SIZE, 0,
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
@@ -160,21 +198,27 @@
/**
* Prepare an EglSurface.
* @param surfaceHolder surface holder.
+ * @param wcg if need to support wcg.
* @return true if EglSurface is ready.
*/
- public boolean createEglSurface(SurfaceHolder surfaceHolder) {
+ public boolean createEglSurface(SurfaceHolder surfaceHolder, boolean wcg) {
if (DEBUG) {
Log.d(TAG, "createEglSurface start");
}
if (hasEglDisplay()) {
- mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, null, 0);
+ int[] attrs = null;
+ int wcgCapability = getWcgCapability();
+ if (wcg && checkExtensionCapability(KHR_GL_COLOR_SPACE) && wcgCapability > 0) {
+ attrs = new int[] {EGL_GL_COLORSPACE_KHR, wcgCapability, EGL_NONE};
+ }
+ mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, attrs, 0);
} else {
Log.w(TAG, "mEglDisplay is null");
return false;
}
- if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
+ if (!hasEglSurface()) {
Log.w(TAG, "createWindowSurface failed: " + GLUtils.getEGLErrorString(eglGetError()));
return false;
}
@@ -221,12 +265,12 @@
int[] attrib_list = new int[5];
int idx = 0;
attrib_list[idx++] = EGL_CONTEXT_CLIENT_VERSION;
- attrib_list[idx++] = 2;
- if (mContextPrioritySupported) {
+ attrib_list[idx++] = OPENGLES_VERSION;
+ if (checkExtensionCapability(EGL_IMG_CONTEXT_PRIORITY)) {
attrib_list[idx++] = EGL_CONTEXT_PRIORITY_LEVEL_IMG;
attrib_list[idx++] = EGL_CONTEXT_PRIORITY_LOW_IMG;
}
- attrib_list[idx++] = EGL_NONE;
+ attrib_list[idx] = EGL_NONE;
if (hasEglDisplay()) {
mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attrib_list, 0);
} else {
@@ -234,7 +278,7 @@
return false;
}
- if (mEglContext == EGL_NO_CONTEXT) {
+ if (!hasEglContext()) {
Log.w(TAG, "eglCreateContext failed: " + GLUtils.getEGLErrorString(eglGetError()));
return false;
}
@@ -260,7 +304,7 @@
* @return true if EglContext is ready.
*/
public boolean hasEglContext() {
- return mEglContext != null;
+ return mEglContext != null && mEglContext != EGL_NO_CONTEXT;
}
/**
@@ -268,7 +312,7 @@
* @return true if EglDisplay is ready.
*/
public boolean hasEglDisplay() {
- return mEglDisplay != null;
+ return mEglDisplay != null && mEglDisplay != EGL_NO_DISPLAY;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
index 60ea1cdf..88ab9ef4 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
@@ -27,6 +27,11 @@
public interface GLWallpaperRenderer {
/**
+ * Check if the content to render is a WCG content.
+ */
+ boolean isWcgContent();
+
+ /**
* Called when the surface is created or recreated.
*/
void onSurfaceCreated();
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
index 24a4b9e..54eca0e 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
@@ -116,7 +116,8 @@
int width = bitmap.getWidth();
int height = bitmap.getHeight();
- Bitmap grayscale = Bitmap.createBitmap(width, height, bitmap.getConfig());
+ Bitmap grayscale = Bitmap.createBitmap(width, height, bitmap.getConfig(),
+ false /* hasAlpha */, bitmap.getColorSpace());
Canvas canvas = new Canvas(grayscale);
ColorMatrix cm = new ColorMatrix(LUMINOSITY_MATRIX);
Paint paint = new Paint();
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
index a8371e3..fa8269d 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
@@ -62,6 +62,7 @@
private boolean mScissorMode;
private float mXOffset;
private float mYOffset;
+ private boolean mWcgContent;
public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
mWallpaperManager = context.getSystemService(WallpaperManager.class);
@@ -94,6 +95,11 @@
}
@Override
+ public boolean isWcgContent() {
+ return mWcgContent;
+ }
+
+ @Override
public void onSurfaceCreated() {
glClearColor(0f, 0f, 0f, 1.0f);
mProgram.useGLProgram(
@@ -112,7 +118,8 @@
Log.d(TAG, "loadBitmap: mBitmap=" + mBitmap);
}
if (mWallpaperManager != null && mBitmap == null) {
- mBitmap = mWallpaperManager.getBitmap();
+ mBitmap = mWallpaperManager.getBitmap(false /* hardware */);
+ mWcgContent = mWallpaperManager.wallpaperSupportsWcg(WallpaperManager.FLAG_SYSTEM);
mWallpaperManager.forgetLoadedWallpaper();
if (mBitmap != null) {
float scale = (float) mScissor.height() / mBitmap.getHeight();
@@ -231,6 +238,7 @@
out.print(prefix); out.print("mYOffset="); out.print(mYOffset);
out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold());
out.print(prefix); out.print("mReveal="); out.print(mImageRevealHelper.getReveal());
+ out.print(prefix); out.print("mWcgContent="); out.print(mWcgContent);
mWallpaper.dump(prefix, fd, out, args);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java b/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java
index 75e260e..d1d9b3d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java
@@ -20,11 +20,13 @@
import android.content.res.Configuration;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.wm.DisplayWindowController;
import java.io.PrintWriter;
public interface BasePipManager {
- void initialize(Context context, BroadcastDispatcher broadcastDispatcher);
+ void initialize(Context context, BroadcastDispatcher broadcastDispatcher,
+ DisplayWindowController displayWindowController);
void showPictureInPictureMenu();
default void expandPip() {}
default void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
index f10274a..8e34a90 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
@@ -16,8 +16,14 @@
package com.android.systemui.pip;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
@@ -32,10 +38,9 @@
import android.view.Gravity;
import android.view.IPinnedStackController;
import android.view.IWindowManager;
+import android.view.WindowContainerTransaction;
import android.view.WindowManagerGlobal;
-import com.android.internal.policy.PipSnapAlgorithm;
-
import java.io.PrintWriter;
/**
@@ -154,6 +159,7 @@
*/
public void onMinimizedStateChanged(boolean minimized) {
mIsMinimized = minimized;
+ mSnapAlgorithm.setMinimized(minimized);
}
/**
@@ -199,6 +205,7 @@
mReentrySnapFraction = INVALID_SNAP_FRACTION;
mReentrySize = null;
mLastPipComponentName = null;
+ mLastDestinationBounds.setEmpty();
}
public Rect getLastDestinationBounds() {
@@ -235,8 +242,9 @@
*/
public void onPrepareAnimation(Rect sourceRectHint, float aspectRatio, Rect bounds) {
final Rect destinationBounds;
+ final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
if (bounds == null) {
- destinationBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
+ destinationBounds = new Rect(defaultBounds);
} else {
destinationBounds = new Rect(bounds);
}
@@ -253,12 +261,85 @@
mPinnedStackController.startAnimation(destinationBounds, sourceRectHint,
-1 /* animationDuration */);
mLastDestinationBounds.set(destinationBounds);
+ mPinnedStackController.reportBounds(defaultBounds,
+ getMovementBounds(defaultBounds));
} catch (RemoteException e) {
Log.e(TAG, "Failed to start PiP animation from SysUI", e);
}
}
/**
+ * Updates the display info, calculating and returning the new stack and movement bounds in the
+ * new orientation of the device if necessary.
+ *
+ * @return {@code true} if internal {@link DisplayInfo} is rotated, {@code false} otherwise.
+ */
+ public boolean onDisplayRotationChanged(Rect outBounds, int displayId, int fromRotation,
+ int toRotation, WindowContainerTransaction t) {
+ // Bail early if the event is not sent to current {@link #mDisplayInfo}
+ if ((displayId != mDisplayInfo.displayId) || (fromRotation == toRotation)) {
+ return false;
+ }
+
+ // Bail early if the pinned stack is staled.
+ final ActivityManager.StackInfo pinnedStackInfo;
+ try {
+ pinnedStackInfo = ActivityTaskManager.getService()
+ .getStackInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
+ if (pinnedStackInfo == null) return false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to get StackInfo for pinned stack", e);
+ return false;
+ }
+
+ // Calculate the snap fraction of the current stack along the old movement bounds
+ final Rect postChangeStackBounds = new Rect(mLastDestinationBounds);
+ final float snapFraction = getSnapFraction(postChangeStackBounds);
+
+ // Populate the new {@link #mDisplayInfo}.
+ // The {@link DisplayInfo} queried from DisplayManager would be the one before rotation,
+ // therefore, the width/height may require a swap first.
+ // Moving forward, we should get the new dimensions after rotation from DisplayLayout.
+ mDisplayInfo.rotation = toRotation;
+ updateDisplayInfoIfNeeded();
+
+ // Calculate the stack bounds in the new orientation based on same fraction along the
+ // rotated movement bounds.
+ final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
+ false /* adjustForIme */);
+ mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
+ snapFraction);
+ if (mIsMinimized) {
+ applyMinimizedOffset(postChangeStackBounds, postChangeMovementBounds);
+ }
+
+ try {
+ outBounds.set(postChangeStackBounds);
+ mLastDestinationBounds.set(outBounds);
+ mPinnedStackController.resetBoundsAnimation(outBounds);
+ mPinnedStackController.reportBounds(outBounds, getMovementBounds(outBounds));
+ t.setBounds(pinnedStackInfo.stackToken, outBounds);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to resize PiP on display rotation", e);
+ }
+ return true;
+ }
+
+ private void updateDisplayInfoIfNeeded() {
+ final boolean updateNeeded;
+ if ((mDisplayInfo.rotation == ROTATION_0) || (mDisplayInfo.rotation == ROTATION_180)) {
+ updateNeeded = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight);
+ } else {
+ updateNeeded = (mDisplayInfo.logicalWidth < mDisplayInfo.logicalHeight);
+ }
+ if (updateNeeded) {
+ final int newLogicalHeight = mDisplayInfo.logicalWidth;
+ mDisplayInfo.logicalWidth = mDisplayInfo.logicalHeight;
+ mDisplayInfo.logicalHeight = newLogicalHeight;
+ }
+ }
+
+ /**
* @return whether the given {@param aspectRatio} is valid.
*/
private boolean isValidPictureInPictureAspectRatio(float aspectRatio) {
diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java
similarity index 99%
rename from core/java/com/android/internal/policy/PipSnapAlgorithm.java
rename to packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java
index e3623c5..f3e707c 100644
--- a/core/java/com/android/internal/policy/PipSnapAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.policy;
+package com.android.systemui.pip;
import android.content.Context;
import android.content.res.Configuration;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
index 583ce67..29de90b 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
@@ -28,6 +28,7 @@
import com.android.systemui.SystemUI;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.wm.DisplayWindowController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -44,15 +45,17 @@
private final CommandQueue mCommandQueue;
private BasePipManager mPipManager;
private final BroadcastDispatcher mBroadcastDispatcher;
-
+ private final DisplayWindowController mDisplayWindowController;
private boolean mSupportsPip;
@Inject
public PipUI(Context context, CommandQueue commandQueue,
- BroadcastDispatcher broadcastDispatcher) {
+ BroadcastDispatcher broadcastDispatcher,
+ DisplayWindowController displayWindowController) {
super(context);
mBroadcastDispatcher = broadcastDispatcher;
mCommandQueue = commandQueue;
+ mDisplayWindowController = displayWindowController;
}
@Override
@@ -72,7 +75,7 @@
mPipManager = pm.hasSystemFeature(FEATURE_LEANBACK_ONLY)
? com.android.systemui.pip.tv.PipManager.getInstance()
: com.android.systemui.pip.phone.PipManager.getInstance();
- mPipManager.initialize(mContext, mBroadcastDispatcher);
+ mPipManager.initialize(mContext, mBroadcastDispatcher, mDisplayWindowController);
mCommandQueue.addCallback(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index a4707cf..0a89017 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -34,6 +34,7 @@
import android.util.Pair;
import android.view.DisplayInfo;
import android.view.IPinnedStackController;
+import android.view.WindowContainerTransaction;
import com.android.systemui.Dependency;
import com.android.systemui.UiOffloadThread;
@@ -45,6 +46,7 @@
import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.WindowManagerWrapper;
+import com.android.systemui.wm.DisplayWindowController;
import java.io.PrintWriter;
@@ -75,9 +77,22 @@
private PipAppOpsListener mAppOpsListener;
/**
+ * Handler for display rotation changes.
+ */
+ private final DisplayWindowController.OnDisplayWindowRotationController mRotationController = (
+ int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> {
+ final boolean changed = mPipBoundsHandler.onDisplayRotationChanged(mTmpNormalBounds,
+ displayId, fromRotation, toRotation, t);
+ if (changed) {
+ updateMovementBounds(mTmpNormalBounds, false /* fromImeAdjustment */,
+ false /* fromShelfAdjustment */);
+ }
+ };
+
+ /**
* Handler for system task stack changes.
*/
- TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
+ private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
@Override
public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
mTouchHandler.onActivityPinned();
@@ -214,7 +229,8 @@
/**
* Initializes {@link PipManager}.
*/
- public void initialize(Context context, BroadcastDispatcher broadcastDispatcher) {
+ public void initialize(Context context, BroadcastDispatcher broadcastDispatcher,
+ DisplayWindowController displayWindowController) {
mContext = context;
mActivityManager = ActivityManager.getService();
mActivityTaskManager = ActivityTaskManager.getService();
@@ -235,6 +251,7 @@
mMenuController, mInputConsumerController, mPipBoundsHandler);
mAppOpsListener = new PipAppOpsListener(context, mActivityManager,
mTouchHandler.getMotionHelper());
+ displayWindowController.addRotationController(mRotationController);
// If SystemUI restart, and it already existed a pinned stack,
// register the pip input consumer to ensure touch can send to it.
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index fa60477..6afa0bf 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -46,7 +46,7 @@
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.internal.os.SomeArgs;
-import com.android.internal.policy.PipSnapAlgorithm;
+import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.systemui.statusbar.FlingAnimationUtils;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 2347a47..95e3444 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -46,9 +46,9 @@
import android.view.accessibility.AccessibilityWindowInfo;
import com.android.internal.os.logging.MetricsLoggerWrapper;
-import com.android.internal.policy.PipSnapAlgorithm;
import com.android.systemui.R;
import com.android.systemui.pip.PipBoundsHandler;
+import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.statusbar.FlingAnimationUtils;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 195fca8..696db68 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -55,6 +55,7 @@
import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.WindowManagerWrapper;
+import com.android.systemui.wm.DisplayWindowController;
import java.util.ArrayList;
import java.util.List;
@@ -228,7 +229,8 @@
/**
* Initializes {@link PipManager}.
*/
- public void initialize(Context context, BroadcastDispatcher broadcastDispatcher) {
+ public void initialize(Context context, BroadcastDispatcher broadcastDispatcher,
+ DisplayWindowController displayWindowController) {
if (mInitialized) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 00220ce..c9813db 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -16,8 +16,6 @@
package com.android.systemui.screenshot;
-import static android.content.Context.NOTIFICATION_SERVICE;
-import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
import static android.view.View.VISIBLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
@@ -31,14 +29,10 @@
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.Nullable;
-import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.Notification;
-import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
@@ -55,7 +49,6 @@
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
-import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.DisplayMetrics;
@@ -74,20 +67,13 @@
import android.widget.TextView;
import android.widget.Toast;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.systemui.R;
-import com.android.systemui.SystemUI;
-import com.android.systemui.SystemUIFactory;
import com.android.systemui.dagger.qualifiers.MainResources;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.util.NotificationChannels;
-import java.util.Collections;
import java.util.List;
import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -108,29 +94,20 @@
* POD used in the AsyncTask which saves an image in the background.
*/
static class SaveImageInBackgroundData {
- public Context context;
public Bitmap image;
public Uri imageUri;
public Consumer<Uri> finisher;
public GlobalScreenshot.ActionsReadyListener mActionsReadyListener;
- public int iconSize;
- public int previewWidth;
- public int previewheight;
public int errorMsgResId;
void clearImage() {
image = null;
imageUri = null;
- iconSize = 0;
- }
-
- void clearContext() {
- context = null;
}
}
abstract static class ActionsReadyListener {
- abstract void onActionsReady(PendingIntent shareAction, PendingIntent editAction);
+ abstract void onActionsReady(Uri imageUri, List<Notification.Action> actions);
}
// These strings are used for communicating the action invoked to
@@ -165,13 +142,12 @@
private static final float SCREENSHOT_CORNER_MIN_SCALE_OFFSET = .1f;
private static final long SCREENSHOT_CORNER_TIMEOUT_MILLIS = 8000;
private static final int MESSAGE_CORNER_TIMEOUT = 2;
- private final int mPreviewWidth;
- private final int mPreviewHeight;
+
+ private final ScreenshotNotificationsController mNotificationsController;
private Context mContext;
private WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowLayoutParams;
- private NotificationManager mNotificationManager;
private Display mDisplay;
private DisplayMetrics mDisplayMetrics;
@@ -182,13 +158,9 @@
private ImageView mScreenshotView;
private ImageView mScreenshotFlash;
private LinearLayout mActionsView;
- private TextView mShareAction;
- private TextView mEditAction;
- private TextView mScrollAction;
private AnimatorSet mScreenshotAnimation;
- private int mNotificationIconSize;
private float mBgPadding;
private float mBgPaddingScale;
@@ -213,9 +185,11 @@
* @param context everything needs a context :(
*/
@Inject
- public GlobalScreenshot(Context context, @MainResources Resources resources,
- LayoutInflater layoutInflater) {
+ public GlobalScreenshot(
+ Context context, @MainResources Resources resources, LayoutInflater layoutInflater,
+ ScreenshotNotificationsController screenshotNotificationsController) {
mContext = context;
+ mNotificationsController = screenshotNotificationsController;
// Inflate the screenshot layout
mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null);
@@ -223,21 +197,6 @@
mScreenshotView = mScreenshotLayout.findViewById(R.id.global_screenshot);
mActionsView = mScreenshotLayout.findViewById(R.id.global_screenshot_actions);
- mShareAction = (TextView) layoutInflater.inflate(
- R.layout.global_screenshot_action_chip, mActionsView, false);
- mEditAction = (TextView) layoutInflater.inflate(
- R.layout.global_screenshot_action_chip, mActionsView, false);
- mScrollAction = (TextView) layoutInflater.inflate(
- R.layout.global_screenshot_action_chip, mActionsView, false);
-
- mShareAction.setText(com.android.internal.R.string.share);
- mEditAction.setText(com.android.internal.R.string.screenshot_edit);
- mScrollAction.setText("Scroll"); // TODO (mkephart): Add to resources and translate
-
- mActionsView.addView(mShareAction);
- mActionsView.addView(mEditAction);
- mActionsView.addView(mScrollAction);
-
mScreenshotFlash = mScreenshotLayout.findViewById(R.id.global_screenshot_flash);
mScreenshotSelectorView = mScreenshotLayout.findViewById(R.id.global_screenshot_selector);
mScreenshotLayout.setFocusable(true);
@@ -260,32 +219,14 @@
mWindowLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
mWindowLayoutParams.setFitWindowInsetsTypes(0 /* types */);
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- mNotificationManager =
- (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
mDisplay = mWindowManager.getDefaultDisplay();
mDisplayMetrics = new DisplayMetrics();
mDisplay.getRealMetrics(mDisplayMetrics);
- // Get the various target sizes
- mNotificationIconSize =
- resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
-
// Scale has to account for both sides of the bg
mBgPadding = (float) resources.getDimensionPixelSize(R.dimen.global_screenshot_bg_padding);
mBgPaddingScale = mBgPadding / mDisplayMetrics.widthPixels;
- // determine the optimal preview size
- int panelWidth = 0;
- try {
- panelWidth = resources.getDimensionPixelSize(R.dimen.notification_panel_width);
- } catch (Resources.NotFoundException e) {
- }
- if (panelWidth <= 0) {
- // includes notification_panel_width==match_parent (-1)
- panelWidth = mDisplayMetrics.widthPixels;
- }
- mPreviewWidth = panelWidth;
- mPreviewHeight = resources.getDimensionPixelSize(R.dimen.notification_max_height);
// Setup the Camera shutter sound
mCameraSound = new MediaActionSound();
@@ -298,22 +239,20 @@
private void saveScreenshotInWorkerThread(
Consumer<Uri> finisher, @Nullable ActionsReadyListener actionsReadyListener) {
SaveImageInBackgroundData data = new SaveImageInBackgroundData();
- data.context = mContext;
data.image = mScreenBitmap;
- data.iconSize = mNotificationIconSize;
data.finisher = finisher;
data.mActionsReadyListener = actionsReadyListener;
- data.previewWidth = mPreviewWidth;
- data.previewheight = mPreviewHeight;
if (mSaveInBgTask != null) {
mSaveInBgTask.cancel(false);
}
- mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data, mNotificationManager)
- .execute();
- }
- private void saveScreenshotInWorkerThread(Consumer<Uri> finisher) {
- saveScreenshotInWorkerThread(finisher, null);
+ if (!DeviceConfig.getBoolean(
+ NAMESPACE_SYSTEMUI, SCREENSHOT_CORNER_FLOW, false)) {
+ mNotificationsController.reset();
+ mNotificationsController.setImage(mScreenBitmap);
+ mNotificationsController.showSavingScreenshotNotification();
+ }
+ mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data).execute();
}
/**
@@ -328,7 +267,7 @@
// Take the screenshot
mScreenBitmap = SurfaceControl.screenshot(crop, width, height, rot);
if (mScreenBitmap == null) {
- notifyScreenshotError(mContext, mNotificationManager,
+ mNotificationsController.notifyScreenshotError(
R.string.screenshot_failed_to_capture_text);
finisher.accept(null);
return;
@@ -373,12 +312,8 @@
if (rect != null) {
if (rect.width() != 0 && rect.height() != 0) {
// Need mScreenshotLayout to handle it after the view disappears
- mScreenshotLayout.post(new Runnable() {
- public void run() {
- takeScreenshot(finisher, statusBarVisible, navBarVisible,
- rect);
- }
- });
+ mScreenshotLayout.post(() -> takeScreenshot(
+ finisher, statusBarVisible, navBarVisible, rect));
}
}
@@ -464,15 +399,30 @@
public void onAnimationEnd(Animator animation) {
// Save the screenshot once we have a bit of time now
if (!useCornerFlow) {
- saveScreenshotInWorkerThread(finisher);
+ saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
+ @Override
+ void onActionsReady(Uri uri, List<Notification.Action> actions) {
+ if (uri == null) {
+ mNotificationsController.notifyScreenshotError(
+ R.string.screenshot_failed_to_capture_text);
+ } else {
+ mNotificationsController
+ .showScreenshotActionsNotification(uri, actions);
+ }
+ }
+ });
clearScreenshot();
} else {
saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
@Override
- void onActionsReady(PendingIntent shareAction, PendingIntent editAction) {
- mScreenshotHandler.post(() ->
- createScreenshotActionsShadeAnimation(shareAction, editAction)
- .start());
+ void onActionsReady(Uri uri, List<Notification.Action> actions) {
+ if (uri == null) {
+ mNotificationsController.notifyScreenshotError(
+ R.string.screenshot_failed_to_capture_text);
+ } else {
+ mScreenshotHandler.post(() ->
+ createScreenshotActionsShadeAnimation(actions).start());
+ }
}
});
mScreenshotHandler.sendMessageDelayed(
@@ -679,8 +629,33 @@
return anim;
}
- private ValueAnimator createScreenshotActionsShadeAnimation(
- PendingIntent shareAction, PendingIntent editAction) {
+ private ValueAnimator createScreenshotActionsShadeAnimation(List<Notification.Action> actions) {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ mActionsView.removeAllViews();
+
+ for (Notification.Action action : actions) {
+ TextView actionChip = (TextView) inflater.inflate(
+ R.layout.global_screenshot_action_chip, mActionsView, false);
+ actionChip.setText(action.title);
+ actionChip.setOnClickListener(v -> {
+ try {
+ action.actionIntent.send();
+ clearScreenshot();
+ } catch (PendingIntent.CanceledException e) {
+ Log.e(TAG,
+ String.format("Intent cancelled (title: %s)", action.title), e);
+ }
+ });
+ mActionsView.addView(actionChip);
+ }
+ TextView scrollChip = (TextView) inflater.inflate(
+ R.layout.global_screenshot_action_chip, mActionsView, false);
+ Toast scrollNotImplemented = Toast.makeText(
+ mContext, "Not implemented", Toast.LENGTH_SHORT);
+ scrollChip.setText("Scroll"); // TODO (mkephart): add resource and translate
+ scrollChip.setOnClickListener(v -> scrollNotImplemented.show());
+ mActionsView.addView(scrollChip);
+
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
mActionsView.setY(mDisplayMetrics.heightPixels);
mActionsView.setVisibility(VISIBLE);
@@ -698,158 +673,11 @@
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mScreenshotView.requestFocus();
- mShareAction.setOnClickListener(v -> {
- try {
- shareAction.send();
- clearScreenshot();
- } catch (PendingIntent.CanceledException e) {
- Log.e(TAG, "Share intent cancelled", e);
- }
- });
- mEditAction.setOnClickListener(v -> {
- try {
- editAction.send();
- clearScreenshot();
- } catch (PendingIntent.CanceledException e) {
- Log.e(TAG, "Edit intent cancelled", e);
- }
- });
- Toast scrollNotImplemented = Toast.makeText(
- mContext, "Not implemented", Toast.LENGTH_SHORT);
- mScrollAction.setOnClickListener(v -> scrollNotImplemented.show());
}
});
return animator;
}
- static void notifyScreenshotError(Context context, NotificationManager nManager, int msgResId) {
- Resources r = context.getResources();
- String errorMsg = r.getString(msgResId);
-
- // Repurpose the existing notification to notify the user of the error
- Notification.Builder b = new Notification.Builder(context, NotificationChannels.ALERTS)
- .setTicker(r.getString(R.string.screenshot_failed_title))
- .setContentTitle(r.getString(R.string.screenshot_failed_title))
- .setContentText(errorMsg)
- .setSmallIcon(R.drawable.stat_notify_image_error)
- .setWhen(System.currentTimeMillis())
- .setVisibility(Notification.VISIBILITY_PUBLIC) // ok to show outside lockscreen
- .setCategory(Notification.CATEGORY_ERROR)
- .setAutoCancel(true)
- .setColor(context.getColor(
- com.android.internal.R.color.system_notification_accent_color));
- final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
- Context.DEVICE_POLICY_SERVICE);
- final Intent intent = dpm.createAdminSupportIntent(
- DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
- if (intent != null) {
- final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
- context, 0, intent, 0, null, UserHandle.CURRENT);
- b.setContentIntent(pendingIntent);
- }
-
- SystemUI.overrideNotificationAppName(context, b, true);
-
- Notification n = new Notification.BigTextStyle(b)
- .bigText(errorMsg)
- .build();
- nManager.notify(SystemMessage.NOTE_GLOBAL_SCREENSHOT, n);
- }
-
- @VisibleForTesting
- static CompletableFuture<List<Notification.Action>> getSmartActionsFuture(String screenshotId,
- Bitmap image, ScreenshotNotificationSmartActionsProvider smartActionsProvider,
- boolean smartActionsEnabled, boolean isManagedProfile) {
- if (!smartActionsEnabled) {
- Slog.i(TAG, "Screenshot Intelligence not enabled, returning empty list.");
- return CompletableFuture.completedFuture(Collections.emptyList());
- }
- if (image.getConfig() != Bitmap.Config.HARDWARE) {
- Slog.w(TAG, String.format(
- "Bitmap expected: Hardware, Bitmap found: %s. Returning empty list.",
- image.getConfig()));
- return CompletableFuture.completedFuture(Collections.emptyList());
- }
-
- Slog.d(TAG, "Screenshot from a managed profile: " + isManagedProfile);
- CompletableFuture<List<Notification.Action>> smartActionsFuture;
- long startTimeMs = SystemClock.uptimeMillis();
- try {
- ActivityManager.RunningTaskInfo runningTask =
- ActivityManagerWrapper.getInstance().getRunningTask();
- ComponentName componentName =
- (runningTask != null && runningTask.topActivity != null)
- ? runningTask.topActivity
- : new ComponentName("", "");
- smartActionsFuture = smartActionsProvider.getActions(screenshotId, image,
- componentName,
- isManagedProfile);
- } catch (Throwable e) {
- long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
- smartActionsFuture = CompletableFuture.completedFuture(Collections.emptyList());
- Slog.e(TAG, "Failed to get future for screenshot notification smart actions.", e);
- notifyScreenshotOp(screenshotId, smartActionsProvider,
- ScreenshotNotificationSmartActionsProvider.ScreenshotOp.REQUEST_SMART_ACTIONS,
- ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.ERROR,
- waitTimeMs);
- }
- return smartActionsFuture;
- }
-
- @VisibleForTesting
- static List<Notification.Action> getSmartActions(String screenshotId,
- CompletableFuture<List<Notification.Action>> smartActionsFuture, int timeoutMs,
- ScreenshotNotificationSmartActionsProvider smartActionsProvider) {
- long startTimeMs = SystemClock.uptimeMillis();
- try {
- List<Notification.Action> actions = smartActionsFuture.get(timeoutMs,
- TimeUnit.MILLISECONDS);
- long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
- Slog.d(TAG, String.format("Got %d smart actions. Wait time: %d ms",
- actions.size(), waitTimeMs));
- notifyScreenshotOp(screenshotId, smartActionsProvider,
- ScreenshotNotificationSmartActionsProvider.ScreenshotOp.WAIT_FOR_SMART_ACTIONS,
- ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.SUCCESS,
- waitTimeMs);
- return actions;
- } catch (Throwable e) {
- long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
- Slog.e(TAG, String.format("Error getting smart actions. Wait time: %d ms", waitTimeMs),
- e);
- ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus status =
- (e instanceof TimeoutException)
- ? ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.TIMEOUT
- : ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.ERROR;
- notifyScreenshotOp(screenshotId, smartActionsProvider,
- ScreenshotNotificationSmartActionsProvider.ScreenshotOp.WAIT_FOR_SMART_ACTIONS,
- status, waitTimeMs);
- return Collections.emptyList();
- }
- }
-
- static void notifyScreenshotOp(String screenshotId,
- ScreenshotNotificationSmartActionsProvider smartActionsProvider,
- ScreenshotNotificationSmartActionsProvider.ScreenshotOp op,
- ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus status, long durationMs) {
- try {
- smartActionsProvider.notifyOp(screenshotId, op, status, durationMs);
- } catch (Throwable e) {
- Slog.e(TAG, "Error in notifyScreenshotOp: ", e);
- }
- }
-
- static void notifyScreenshotAction(Context context, String screenshotId, String action,
- boolean isSmartAction) {
- try {
- ScreenshotNotificationSmartActionsProvider provider =
- SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider(
- context, THREAD_POOL_EXECUTOR, new Handler());
- provider.notifyAction(screenshotId, action, isSmartAction);
- } catch (Throwable e) {
- Slog.e(TAG, "Error in notifyScreenshotAction: ", e);
- }
- }
-
/**
* Receiver to proxy the share or edit intent, used to clean up the notification and send
* appropriate signals to the system (ie. to dismiss the keyguard if necessary).
@@ -878,7 +706,7 @@
Intent actionIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT);
if (intent.getBooleanExtra(EXTRA_CANCEL_NOTIFICATION, false)) {
- cancelScreenshotNotification(context);
+ ScreenshotNotificationsController.cancelScreenshotNotification(context);
}
ActivityOptions opts = ActivityOptions.makeBasic();
opts.setDisallowEnterPictureInPictureWhileLaunching(
@@ -897,8 +725,8 @@
if (intent.getBooleanExtra(EXTRA_SMART_ACTIONS_ENABLED, false)) {
String actionType = Intent.ACTION_EDIT.equals(intent.getAction()) ? ACTION_TYPE_EDIT
: ACTION_TYPE_SHARE;
- notifyScreenshotAction(context, intent.getStringExtra(EXTRA_ID),
- actionType, false);
+ ScreenshotSmartActions.notifyScreenshotAction(
+ context, intent.getStringExtra(EXTRA_ID), actionType, false);
}
}
}
@@ -910,7 +738,7 @@
@Override
public void onReceive(Context context, Intent intent) {
// Clear the notification only after the user has chosen a share action
- cancelScreenshotNotification(context);
+ ScreenshotNotificationsController.cancelScreenshotNotification(context);
}
}
@@ -925,15 +753,14 @@
}
// Clear the notification when the image is deleted
- cancelScreenshotNotification(context);
+ ScreenshotNotificationsController.cancelScreenshotNotification(context);
// And delete the image from the media store
final Uri uri = Uri.parse(intent.getStringExtra(SCREENSHOT_URI_ID));
new DeleteImageInBackgroundTask(context).execute(uri);
if (intent.getBooleanExtra(EXTRA_SMART_ACTIONS_ENABLED, false)) {
- notifyScreenshotAction(context, intent.getStringExtra(EXTRA_ID),
- ACTION_TYPE_DELETE,
- false);
+ ScreenshotSmartActions.notifyScreenshotAction(
+ context, intent.getStringExtra(EXTRA_ID), ACTION_TYPE_DELETE, false);
}
}
}
@@ -952,15 +779,8 @@
context.startActivityAsUser(actionIntent, opts.toBundle(),
UserHandle.CURRENT);
- notifyScreenshotAction(context, intent.getStringExtra(EXTRA_ID),
- actionType,
- true);
+ ScreenshotSmartActions.notifyScreenshotAction(
+ context, intent.getStringExtra(EXTRA_ID), actionType, true);
}
}
-
- private static void cancelScreenshotNotification(Context context) {
- final NotificationManager nm =
- (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
- nm.cancel(SystemMessage.NOTE_GLOBAL_SCREENSHOT);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index 2f401e5..6bad15c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -18,7 +18,6 @@
import android.app.ActivityTaskManager;
import android.app.Notification;
-import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ClipData;
import android.content.ClipDescription;
@@ -30,12 +29,7 @@
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Picture;
+import android.graphics.drawable.Icon;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
@@ -57,13 +51,8 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-import com.android.internal.messages.nano.SystemMessageProto;
import com.android.systemui.R;
-import com.android.systemui.SystemUI;
import com.android.systemui.SystemUIFactory;
-import com.android.systemui.util.NotificationChannels;
-
-import libcore.io.IoUtils;
import java.io.File;
import java.io.IOException;
@@ -76,6 +65,7 @@
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@@ -93,22 +83,17 @@
private static final String SCREENSHOT_ID_TEMPLATE = "Screenshot_%s";
private static final String SCREENSHOT_SHARE_SUBJECT_TEMPLATE = "Screenshot (%s)";
+ private final Context mContext;
private final GlobalScreenshot.SaveImageInBackgroundData mParams;
- private final NotificationManager mNotificationManager;
- private final Notification.Builder mNotificationBuilder, mPublicNotificationBuilder;
private final String mImageFileName;
private final long mImageTime;
- private final Notification.BigPictureStyle mNotificationStyle;
- private final int mImageWidth;
- private final int mImageHeight;
private final ScreenshotNotificationSmartActionsProvider mSmartActionsProvider;
private final String mScreenshotId;
private final boolean mSmartActionsEnabled;
private final Random mRandom = new Random();
- SaveImageInBackgroundTask(Context context, GlobalScreenshot.SaveImageInBackgroundData data,
- NotificationManager nManager) {
- Resources r = context.getResources();
+ SaveImageInBackgroundTask(Context context, GlobalScreenshot.SaveImageInBackgroundData data) {
+ mContext = context;
// Prepare all the output metadata
mParams = data;
@@ -129,143 +114,6 @@
// If smart actions is not enabled use empty implementation.
mSmartActionsProvider = new ScreenshotNotificationSmartActionsProvider();
}
-
- // Create the large notification icon
- mImageWidth = data.image.getWidth();
- mImageHeight = data.image.getHeight();
- int iconSize = data.iconSize;
- int previewWidth = data.previewWidth;
- int previewHeight = data.previewheight;
-
- Paint paint = new Paint();
- ColorMatrix desat = new ColorMatrix();
- desat.setSaturation(0.25f);
- paint.setColorFilter(new ColorMatrixColorFilter(desat));
- Matrix matrix = new Matrix();
- int overlayColor = 0x40FFFFFF;
-
- matrix.setTranslate((previewWidth - mImageWidth) / 2,
- (previewHeight - mImageHeight) / 2);
- Bitmap picture = generateAdjustedHwBitmap(data.image, previewWidth, previewHeight,
- matrix, paint, overlayColor);
-
- // Note, we can't use the preview for the small icon, since it is non-square
- float scale = (float) iconSize / Math.min(mImageWidth, mImageHeight);
- matrix.setScale(scale, scale);
- matrix.postTranslate((iconSize - (scale * mImageWidth)) / 2,
- (iconSize - (scale * mImageHeight)) / 2);
- Bitmap icon = generateAdjustedHwBitmap(data.image, iconSize, iconSize, matrix, paint,
- overlayColor);
-
- mNotificationManager = nManager;
- final long now = System.currentTimeMillis();
-
- // Setup the notification
- mNotificationStyle = new Notification.BigPictureStyle()
- .bigPicture(picture.createAshmemBitmap());
-
- // The public notification will show similar info but with the actual screenshot omitted
- mPublicNotificationBuilder =
- new Notification.Builder(context, NotificationChannels.SCREENSHOTS_HEADSUP)
- .setContentTitle(r.getString(R.string.screenshot_saving_title))
- .setSmallIcon(R.drawable.stat_notify_image)
- .setCategory(Notification.CATEGORY_PROGRESS)
- .setWhen(now)
- .setShowWhen(true)
- .setColor(r.getColor(
- com.android.internal.R.color.system_notification_accent_color));
- SystemUI.overrideNotificationAppName(context, mPublicNotificationBuilder, true);
-
- mNotificationBuilder = new Notification.Builder(context,
- NotificationChannels.SCREENSHOTS_HEADSUP)
- .setContentTitle(r.getString(R.string.screenshot_saving_title))
- .setSmallIcon(R.drawable.stat_notify_image)
- .setWhen(now)
- .setShowWhen(true)
- .setColor(r.getColor(
- com.android.internal.R.color.system_notification_accent_color))
- .setStyle(mNotificationStyle)
- .setPublicVersion(mPublicNotificationBuilder.build());
- mNotificationBuilder.setFlag(Notification.FLAG_NO_CLEAR, true);
- SystemUI.overrideNotificationAppName(context, mNotificationBuilder, true);
-
- mNotificationManager.notify(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT,
- mNotificationBuilder.build());
-
- /**
- * NOTE: The following code prepares the notification builder for updating the
- * notification after the screenshot has been written to disk.
- */
-
- // On the tablet, the large icon makes the notification appear as if it is clickable
- // (and on small devices, the large icon is not shown) so defer showing the large icon
- // until we compose the final post-save notification below.
- mNotificationBuilder.setLargeIcon(icon.createAshmemBitmap());
- // But we still don't set it for the expanded view, allowing the smallIcon to show here.
- mNotificationStyle.bigLargeIcon((Bitmap) null);
- }
-
- private int getUserHandleOfForegroundApplication(Context context) {
- // This logic matches
- // com.android.systemui.statusbar.phone.PhoneStatusBarPolicy#updateManagedProfile
- try {
- return ActivityTaskManager.getService().getLastResumedActivityUserId();
- } catch (RemoteException e) {
- Slog.w(TAG, "getUserHandleOfForegroundApplication: ", e);
- return context.getUserId();
- }
- }
-
- private boolean isManagedProfile(Context context) {
- UserManager manager = UserManager.get(context);
- UserInfo info = manager.getUserInfo(getUserHandleOfForegroundApplication(context));
- return info.isManagedProfile();
- }
-
- private List<Notification.Action> buildSmartActions(
- List<Notification.Action> actions, Context context) {
- List<Notification.Action> broadcastActions = new ArrayList<>();
- for (Notification.Action action : actions) {
- // Proxy smart actions through {@link GlobalScreenshot.SmartActionsReceiver}
- // for logging smart actions.
- Bundle extras = action.getExtras();
- String actionType = extras.getString(
- ScreenshotNotificationSmartActionsProvider.ACTION_TYPE,
- ScreenshotNotificationSmartActionsProvider.DEFAULT_ACTION_TYPE);
- Intent intent = new Intent(context,
- GlobalScreenshot.SmartActionsReceiver.class).putExtra(
- GlobalScreenshot.EXTRA_ACTION_INTENT, action.actionIntent);
- addIntentExtras(mScreenshotId, intent, actionType, mSmartActionsEnabled);
- PendingIntent broadcastIntent = PendingIntent.getBroadcast(context,
- mRandom.nextInt(),
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
- broadcastActions.add(new Notification.Action.Builder(action.getIcon(), action.title,
- broadcastIntent).setContextual(true).addExtras(extras).build());
- }
- return broadcastActions;
- }
-
- private static void addIntentExtras(String screenshotId, Intent intent, String actionType,
- boolean smartActionsEnabled) {
- intent
- .putExtra(GlobalScreenshot.EXTRA_ACTION_TYPE, actionType)
- .putExtra(GlobalScreenshot.EXTRA_ID, screenshotId)
- .putExtra(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED, smartActionsEnabled);
- }
-
- /**
- * Generates a new hardware bitmap with specified values, copying the content from the
- * passed in bitmap.
- */
- private Bitmap generateAdjustedHwBitmap(Bitmap bitmap, int width, int height, Matrix matrix,
- Paint paint, int color) {
- Picture picture = new Picture();
- Canvas canvas = picture.beginRecording(width, height);
- canvas.drawColor(color);
- canvas.drawBitmap(bitmap, matrix, paint);
- picture.endRecording();
- return Bitmap.createBitmap(picture);
}
@Override
@@ -278,15 +126,15 @@
// so bump it back up so that we save a little quicker.
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
- Context context = mParams.context;
- ContentResolver resolver = context.getContentResolver();
+ ContentResolver resolver = mContext.getContentResolver();
Bitmap image = mParams.image;
- Resources r = context.getResources();
+ Resources r = mContext.getResources();
try {
CompletableFuture<List<Notification.Action>> smartActionsFuture =
- GlobalScreenshot.getSmartActionsFuture(mScreenshotId, image,
- mSmartActionsProvider, mSmartActionsEnabled, isManagedProfile(context));
+ ScreenshotSmartActions.getSmartActionsFuture(
+ mScreenshotId, image, mSmartActionsProvider,
+ mSmartActionsEnabled, isManagedProfile(mContext));
// Save the screenshot to the MediaStore
final ContentValues values = new ContentValues();
@@ -347,8 +195,9 @@
throw e;
}
- populateNotificationActions(context, r, uri, smartActionsFuture, mNotificationBuilder);
-
+ List<Notification.Action> actions =
+ populateNotificationActions(mContext, r, uri, smartActionsFuture);
+ mParams.mActionsReadyListener.onActionsReady(uri, actions);
mParams.imageUri = uri;
mParams.image = null;
mParams.errorMsgResId = 0;
@@ -358,6 +207,7 @@
Slog.e(TAG, "unable to save screenshot", e);
mParams.clearImage();
mParams.errorMsgResId = R.string.screenshot_failed_to_save_text;
+ mParams.mActionsReadyListener.onActionsReady(null, null);
}
// Recycle the bitmap data
@@ -368,10 +218,24 @@
return null;
}
+ @Override
+ protected void onPostExecute(Void params) {
+ mParams.finisher.accept(mParams.imageUri);
+ }
+
+ @Override
+ protected void onCancelled(Void params) {
+ // If we are cancelled while the task is running in the background, we may get null
+ // params. The finisher is expected to always be called back, so just use the baked-in
+ // params from the ctor in any case.
+ mParams.mActionsReadyListener.onActionsReady(null, null);
+ mParams.finisher.accept(null);
+ mParams.clearImage();
+ }
+
@VisibleForTesting
- void populateNotificationActions(Context context, Resources r, Uri uri,
- CompletableFuture<List<Notification.Action>> smartActionsFuture,
- Notification.Builder notificationBuilder) {
+ List<Notification.Action> populateNotificationActions(Context context, Resources r, Uri uri,
+ CompletableFuture<List<Notification.Action>> smartActionsFuture) {
// Note: Both the share and edit actions are proxied through ActionProxyReceiver in
// order to do some common work like dismissing the keyguard and sending
// closeSystemWindows
@@ -399,10 +263,10 @@
PendingIntent chooserAction = PendingIntent.getBroadcast(context, requestCode,
new Intent(context, GlobalScreenshot.TargetChosenReceiver.class),
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
- Intent sharingChooserIntent = Intent.createChooser(sharingIntent, null,
- chooserAction.getIntentSender())
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ Intent sharingChooserIntent =
+ Intent.createChooser(sharingIntent, null, chooserAction.getIntentSender())
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// Create a share action for the notification
PendingIntent shareAction = PendingIntent.getBroadcastAsUser(context, requestCode,
@@ -414,10 +278,10 @@
mSmartActionsEnabled)
.setAction(Intent.ACTION_SEND),
PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM);
+
Notification.Action.Builder shareActionBuilder = new Notification.Action.Builder(
- R.drawable.ic_screenshot_share,
+ Icon.createWithResource(r, R.drawable.ic_screenshot_share),
r.getString(com.android.internal.R.string.share), shareAction);
- notificationBuilder.addAction(shareActionBuilder.build());
// Create an edit intent, if a specific package is provided as the editor, then
// launch that directly
@@ -443,12 +307,8 @@
.setAction(Intent.ACTION_EDIT),
PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM);
Notification.Action.Builder editActionBuilder = new Notification.Action.Builder(
- R.drawable.ic_screenshot_edit,
+ Icon.createWithResource(r, R.drawable.ic_screenshot_edit),
r.getString(com.android.internal.R.string.screenshot_edit), editAction);
- notificationBuilder.addAction(editActionBuilder.build());
- if (mParams.mActionsReadyListener != null) {
- mParams.mActionsReadyListener.onActionsReady(shareAction, editAction);
- }
// Create a delete action for the notification
PendingIntent deleteAction = PendingIntent.getBroadcast(context, requestCode,
@@ -459,88 +319,73 @@
mSmartActionsEnabled),
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
Notification.Action.Builder deleteActionBuilder = new Notification.Action.Builder(
- R.drawable.ic_screenshot_delete,
+ Icon.createWithResource(r, R.drawable.ic_screenshot_delete),
r.getString(com.android.internal.R.string.delete), deleteAction);
- notificationBuilder.addAction(deleteActionBuilder.build());
+ ArrayList<Notification.Action> actions = new ArrayList<>(
+ Arrays.asList(shareActionBuilder.build(), editActionBuilder.build(),
+ deleteActionBuilder.build()));
if (mSmartActionsEnabled) {
- int timeoutMs = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags
- .SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS,
+ int timeoutMs = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_SYSTEMUI,
+ SystemUiDeviceConfigFlags.SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS,
1000);
- List<Notification.Action> smartActions = GlobalScreenshot.getSmartActions(mScreenshotId,
- smartActionsFuture, timeoutMs, mSmartActionsProvider);
- smartActions = buildSmartActions(smartActions, context);
- for (Notification.Action action : smartActions) {
- notificationBuilder.addAction(action);
- }
+ actions.addAll(buildSmartActions(
+ ScreenshotSmartActions.getSmartActions(
+ mScreenshotId, smartActionsFuture, timeoutMs, mSmartActionsProvider),
+ context));
+ }
+ return actions;
+ }
+
+ private int getUserHandleOfForegroundApplication(Context context) {
+ // This logic matches
+ // com.android.systemui.statusbar.phone.PhoneStatusBarPolicy#updateManagedProfile
+ try {
+ return ActivityTaskManager.getService().getLastResumedActivityUserId();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "getUserHandleOfForegroundApplication: ", e);
+ return context.getUserId();
}
}
- @Override
- protected void onPostExecute(Void params) {
- if (mParams.errorMsgResId != 0) {
- // Show a message that we've failed to save the image to disk
- GlobalScreenshot.notifyScreenshotError(mParams.context, mNotificationManager,
- mParams.errorMsgResId);
- } else {
- if (mParams.mActionsReadyListener != null) {
- // Cancel the "saving screenshot" notification
- mNotificationManager.cancel(
- SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT);
- } else {
- // Show the final notification to indicate screenshot saved
- Context context = mParams.context;
- Resources r = context.getResources();
+ private boolean isManagedProfile(Context context) {
+ UserManager manager = UserManager.get(context);
+ UserInfo info = manager.getUserInfo(getUserHandleOfForegroundApplication(context));
+ return info.isManagedProfile();
+ }
- // Create the intent to show the screenshot in gallery
- Intent launchIntent = new Intent(Intent.ACTION_VIEW);
- launchIntent.setDataAndType(mParams.imageUri, "image/png");
- launchIntent.setFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
-
- final long now = System.currentTimeMillis();
-
- // Update the text and the icon for the existing notification
- mPublicNotificationBuilder
- .setContentTitle(r.getString(R.string.screenshot_saved_title))
- .setContentText(r.getString(R.string.screenshot_saved_text))
- .setContentIntent(
- PendingIntent.getActivity(mParams.context, 0, launchIntent, 0))
- .setWhen(now)
- .setAutoCancel(true)
- .setColor(context.getColor(
- com.android.internal.R.color.system_notification_accent_color));
- mNotificationBuilder
- .setContentTitle(r.getString(R.string.screenshot_saved_title))
- .setContentText(r.getString(R.string.screenshot_saved_text))
- .setContentIntent(PendingIntent.getActivity(mParams.context, 0,
- launchIntent, 0))
- .setWhen(now)
- .setAutoCancel(true)
- .setColor(context.getColor(
- com.android.internal.R.color.system_notification_accent_color))
- .setPublicVersion(mPublicNotificationBuilder.build())
- .setFlag(Notification.FLAG_NO_CLEAR, false);
-
- mNotificationManager.notify(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT,
- mNotificationBuilder.build());
- }
+ private List<Notification.Action> buildSmartActions(
+ List<Notification.Action> actions, Context context) {
+ List<Notification.Action> broadcastActions = new ArrayList<>();
+ for (Notification.Action action : actions) {
+ // Proxy smart actions through {@link GlobalScreenshot.SmartActionsReceiver}
+ // for logging smart actions.
+ Bundle extras = action.getExtras();
+ String actionType = extras.getString(
+ ScreenshotNotificationSmartActionsProvider.ACTION_TYPE,
+ ScreenshotNotificationSmartActionsProvider.DEFAULT_ACTION_TYPE);
+ Intent intent = new Intent(context,
+ GlobalScreenshot.SmartActionsReceiver.class).putExtra(
+ GlobalScreenshot.EXTRA_ACTION_INTENT, action.actionIntent);
+ addIntentExtras(mScreenshotId, intent, actionType, mSmartActionsEnabled);
+ PendingIntent broadcastIntent = PendingIntent.getBroadcast(context,
+ mRandom.nextInt(),
+ intent,
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ broadcastActions.add(new Notification.Action.Builder(action.getIcon(), action.title,
+ broadcastIntent).setContextual(true).addExtras(extras).build());
}
- mParams.finisher.accept(mParams.imageUri);
- mParams.clearContext();
+ return broadcastActions;
}
- @Override
- protected void onCancelled(Void params) {
- // If we are cancelled while the task is running in the background, we may get null
- // params. The finisher is expected to always be called back, so just use the baked-in
- // params from the ctor in any case.
- mParams.finisher.accept(null);
- mParams.clearImage();
- mParams.clearContext();
-
- // Cancel the posted notification
- mNotificationManager.cancel(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT);
+ private static void addIntentExtras(String screenshotId, Intent intent, String actionType,
+ boolean smartActionsEnabled) {
+ intent
+ .putExtra(GlobalScreenshot.EXTRA_ACTION_TYPE, actionType)
+ .putExtra(GlobalScreenshot.EXTRA_ID, screenshotId)
+ .putExtra(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED, smartActionsEnabled);
}
+
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
new file mode 100644
index 0000000..42fca94
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2019 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.screenshot;
+
+import static android.content.Context.NOTIFICATION_SERVICE;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Picture;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.util.DisplayMetrics;
+import android.view.WindowManager;
+
+import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+import com.android.systemui.util.NotificationChannels;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+/**
+ * Convenience class to handle showing and hiding notifications while taking a screenshot.
+ */
+public class ScreenshotNotificationsController {
+ private static final String TAG = "ScreenshotNotificationManager";
+
+ private final Context mContext;
+ private final Resources mResources;
+ private final NotificationManager mNotificationManager;
+ private final Notification.BigPictureStyle mNotificationStyle;
+
+ private int mIconSize;
+ private int mPreviewWidth, mPreviewHeight;
+ private Notification.Builder mNotificationBuilder, mPublicNotificationBuilder;
+
+ @Inject
+ ScreenshotNotificationsController(Context context, WindowManager windowManager) {
+ mContext = context;
+ mResources = context.getResources();
+
+ mNotificationManager =
+ (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
+
+ mIconSize = mResources.getDimensionPixelSize(
+ android.R.dimen.notification_large_icon_height);
+
+ DisplayMetrics displayMetrics = new DisplayMetrics();
+ windowManager.getDefaultDisplay().getRealMetrics(displayMetrics);
+
+
+ // determine the optimal preview size
+ int panelWidth = 0;
+ try {
+ panelWidth = mResources.getDimensionPixelSize(R.dimen.notification_panel_width);
+ } catch (Resources.NotFoundException e) {
+ }
+ if (panelWidth <= 0) {
+ // includes notification_panel_width==match_parent (-1)
+ panelWidth = displayMetrics.widthPixels;
+ }
+ mPreviewWidth = panelWidth;
+ mPreviewHeight = mResources.getDimensionPixelSize(R.dimen.notification_max_height);
+
+ // Setup the notification
+ mNotificationStyle = new Notification.BigPictureStyle();
+ }
+
+ /**
+ * Resets the notification builders.
+ */
+ public void reset() {
+ // The public notification will show similar info but with the actual screenshot omitted
+ mPublicNotificationBuilder =
+ new Notification.Builder(mContext, NotificationChannels.SCREENSHOTS_HEADSUP);
+ mNotificationBuilder =
+ new Notification.Builder(mContext, NotificationChannels.SCREENSHOTS_HEADSUP);
+ }
+
+ /**
+ * Sets the current screenshot bitmap.
+ *
+ * @param image the bitmap of the current screenshot (used for preview)
+ */
+ public void setImage(Bitmap image) {
+ // Create the large notification icon
+ int imageWidth = image.getWidth();
+ int imageHeight = image.getHeight();
+
+ Paint paint = new Paint();
+ ColorMatrix desat = new ColorMatrix();
+ desat.setSaturation(0.25f);
+ paint.setColorFilter(new ColorMatrixColorFilter(desat));
+ Matrix matrix = new Matrix();
+ int overlayColor = 0x40FFFFFF;
+
+ matrix.setTranslate((mPreviewWidth - imageWidth) / 2f, (mPreviewHeight - imageHeight) / 2f);
+
+ Bitmap picture = generateAdjustedHwBitmap(
+ image, mPreviewWidth, mPreviewHeight, matrix, paint, overlayColor);
+
+ mNotificationStyle.bigPicture(picture.createAshmemBitmap());
+
+ // Note, we can't use the preview for the small icon, since it is non-square
+ float scale = (float) mIconSize / Math.min(imageWidth, imageHeight);
+ matrix.setScale(scale, scale);
+ matrix.postTranslate(
+ (mIconSize - (scale * imageWidth)) / 2,
+ (mIconSize - (scale * imageHeight)) / 2);
+ Bitmap icon =
+ generateAdjustedHwBitmap(image, mIconSize, mIconSize, matrix, paint, overlayColor);
+
+ /**
+ * NOTE: The following code prepares the notification builder for updating the
+ * notification after the screenshot has been written to disk.
+ */
+
+ // On the tablet, the large icon makes the notification appear as if it is clickable
+ // (and on small devices, the large icon is not shown) so defer showing the large icon
+ // until we compose the final post-save notification below.
+ mNotificationBuilder.setLargeIcon(icon.createAshmemBitmap());
+ // But we still don't set it for the expanded view, allowing the smallIcon to show here.
+ mNotificationStyle.bigLargeIcon((Bitmap) null);
+ }
+
+ /**
+ * Shows a notification to inform the user that a screenshot is currently being saved.
+ */
+ public void showSavingScreenshotNotification() {
+ final long now = System.currentTimeMillis();
+
+ mPublicNotificationBuilder
+ .setContentTitle(mResources.getString(R.string.screenshot_saving_title))
+ .setSmallIcon(R.drawable.stat_notify_image)
+ .setCategory(Notification.CATEGORY_PROGRESS)
+ .setWhen(now)
+ .setShowWhen(true)
+ .setColor(mResources.getColor(
+ com.android.internal.R.color.system_notification_accent_color));
+ SystemUI.overrideNotificationAppName(mContext, mPublicNotificationBuilder, true);
+
+ mNotificationBuilder
+ .setContentTitle(mResources.getString(R.string.screenshot_saving_title))
+ .setSmallIcon(R.drawable.stat_notify_image)
+ .setWhen(now)
+ .setShowWhen(true)
+ .setColor(mResources.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setStyle(mNotificationStyle)
+ .setPublicVersion(mPublicNotificationBuilder.build());
+ mNotificationBuilder.setFlag(Notification.FLAG_NO_CLEAR, true);
+ SystemUI.overrideNotificationAppName(mContext, mNotificationBuilder, true);
+
+ mNotificationManager.notify(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT,
+ mNotificationBuilder.build());
+ }
+
+ /**
+ * Shows a notification with the saved screenshot and actions that can be taken with it.
+ *
+ * @param imageUri URI for the saved image
+ * @param actions a list of notification actions which can be taken
+ */
+ public void showScreenshotActionsNotification(
+ Uri imageUri,
+ List<Notification.Action> actions) {
+ for (Notification.Action action : actions) {
+ mNotificationBuilder.addAction(action);
+ }
+
+ // Create the intent to show the screenshot in gallery
+ Intent launchIntent = new Intent(Intent.ACTION_VIEW);
+ launchIntent.setDataAndType(imageUri, "image/png");
+ launchIntent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+ final long now = System.currentTimeMillis();
+
+ // Update the text and the icon for the existing notification
+ mPublicNotificationBuilder
+ .setContentTitle(mResources.getString(R.string.screenshot_saved_title))
+ .setContentText(mResources.getString(R.string.screenshot_saved_text))
+ .setContentIntent(PendingIntent.getActivity(mContext, 0, launchIntent, 0))
+ .setWhen(now)
+ .setAutoCancel(true)
+ .setColor(mContext.getColor(
+ com.android.internal.R.color.system_notification_accent_color));
+ mNotificationBuilder
+ .setContentTitle(mResources.getString(R.string.screenshot_saved_title))
+ .setContentText(mResources.getString(R.string.screenshot_saved_text))
+ .setContentIntent(PendingIntent.getActivity(mContext, 0, launchIntent, 0))
+ .setWhen(now)
+ .setAutoCancel(true)
+ .setColor(mContext.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setPublicVersion(mPublicNotificationBuilder.build())
+ .setFlag(Notification.FLAG_NO_CLEAR, false);
+
+ mNotificationManager.notify(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT,
+ mNotificationBuilder.build());
+ }
+
+ /**
+ * Sends a notification that the screenshot capture has failed.
+ */
+ public void notifyScreenshotError(int msgResId) {
+ Resources res = mContext.getResources();
+ String errorMsg = res.getString(msgResId);
+
+ // Repurpose the existing notification to notify the user of the error
+ Notification.Builder b = new Notification.Builder(mContext, NotificationChannels.ALERTS)
+ .setTicker(res.getString(R.string.screenshot_failed_title))
+ .setContentTitle(res.getString(R.string.screenshot_failed_title))
+ .setContentText(errorMsg)
+ .setSmallIcon(R.drawable.stat_notify_image_error)
+ .setWhen(System.currentTimeMillis())
+ .setVisibility(Notification.VISIBILITY_PUBLIC) // ok to show outside lockscreen
+ .setCategory(Notification.CATEGORY_ERROR)
+ .setAutoCancel(true)
+ .setColor(mContext.getColor(
+ com.android.internal.R.color.system_notification_accent_color));
+ final DevicePolicyManager dpm =
+ (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ final Intent intent =
+ dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
+ if (intent != null) {
+ final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
+ mContext, 0, intent, 0, null, UserHandle.CURRENT);
+ b.setContentIntent(pendingIntent);
+ }
+
+ SystemUI.overrideNotificationAppName(mContext, b, true);
+
+ Notification n = new Notification.BigTextStyle(b)
+ .bigText(errorMsg)
+ .build();
+ mNotificationManager.notify(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT, n);
+ }
+
+ /**
+ * Cancels the current screenshot notification.
+ */
+ public void cancelNotification() {
+ mNotificationManager.cancel(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT);
+ }
+
+ /**
+ * Generates a new hardware bitmap with specified values, copying the content from the
+ * passed in bitmap.
+ */
+ private Bitmap generateAdjustedHwBitmap(Bitmap bitmap, int width, int height, Matrix matrix,
+ Paint paint, int color) {
+ Picture picture = new Picture();
+ Canvas canvas = picture.beginRecording(width, height);
+ canvas.drawColor(color);
+ canvas.drawBitmap(bitmap, matrix, paint);
+ picture.endRecording();
+ return Bitmap.createBitmap(picture);
+ }
+
+ static void cancelScreenshotNotification(Context context) {
+ final NotificationManager nm =
+ (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
+ nm.cancel(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java
index fc2a1e4..522f729 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java
@@ -16,10 +16,10 @@
package com.android.systemui.screenshot;
-import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.view.WindowManager;
import com.android.systemui.R;
@@ -32,9 +32,9 @@
@Override
public void onReceive(final Context context, Intent intent) {
// Show a message that we've failed to save the image to disk
- NotificationManager nm = (NotificationManager)
- context.getSystemService(Context.NOTIFICATION_SERVICE);
- GlobalScreenshot.notifyScreenshotError(context, nm,
- R.string.screenshot_failed_to_save_unknown_text);
+ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ ScreenshotNotificationsController controller =
+ new ScreenshotNotificationsController(context, wm);
+ controller.notifyScreenshotError(R.string.screenshot_failed_to_save_unknown_text);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java
new file mode 100644
index 0000000..e76e37e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2019 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.screenshot;
+
+import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
+
+import android.app.ActivityManager;
+import android.app.Notification;
+import android.content.ComponentName;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.SystemUIFactory;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Collects the static functions for retrieving and acting on smart actions.
+ */
+public class ScreenshotSmartActions {
+ private static final String TAG = "ScreenshotSmartActions";
+
+ @VisibleForTesting
+ static CompletableFuture<List<Notification.Action>> getSmartActionsFuture(String screenshotId,
+ Bitmap image, ScreenshotNotificationSmartActionsProvider smartActionsProvider,
+ boolean smartActionsEnabled, boolean isManagedProfile) {
+ if (!smartActionsEnabled) {
+ Slog.i(TAG, "Screenshot Intelligence not enabled, returning empty list.");
+ return CompletableFuture.completedFuture(Collections.emptyList());
+ }
+ if (image.getConfig() != Bitmap.Config.HARDWARE) {
+ Slog.w(TAG, String.format(
+ "Bitmap expected: Hardware, Bitmap found: %s. Returning empty list.",
+ image.getConfig()));
+ return CompletableFuture.completedFuture(Collections.emptyList());
+ }
+
+ Slog.d(TAG, "Screenshot from a managed profile: " + isManagedProfile);
+ CompletableFuture<List<Notification.Action>> smartActionsFuture;
+ long startTimeMs = SystemClock.uptimeMillis();
+ try {
+ ActivityManager.RunningTaskInfo runningTask =
+ ActivityManagerWrapper.getInstance().getRunningTask();
+ ComponentName componentName =
+ (runningTask != null && runningTask.topActivity != null)
+ ? runningTask.topActivity
+ : new ComponentName("", "");
+ smartActionsFuture = smartActionsProvider.getActions(screenshotId, image,
+ componentName,
+ isManagedProfile);
+ } catch (Throwable e) {
+ long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
+ smartActionsFuture = CompletableFuture.completedFuture(Collections.emptyList());
+ Slog.e(TAG, "Failed to get future for screenshot notification smart actions.", e);
+ notifyScreenshotOp(screenshotId, smartActionsProvider,
+ ScreenshotNotificationSmartActionsProvider.ScreenshotOp.REQUEST_SMART_ACTIONS,
+ ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.ERROR,
+ waitTimeMs);
+ }
+ return smartActionsFuture;
+ }
+
+ @VisibleForTesting
+ static List<Notification.Action> getSmartActions(String screenshotId,
+ CompletableFuture<List<Notification.Action>> smartActionsFuture, int timeoutMs,
+ ScreenshotNotificationSmartActionsProvider smartActionsProvider) {
+ long startTimeMs = SystemClock.uptimeMillis();
+ try {
+ List<Notification.Action> actions = smartActionsFuture.get(timeoutMs,
+ TimeUnit.MILLISECONDS);
+ long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
+ Slog.d(TAG, String.format("Got %d smart actions. Wait time: %d ms",
+ actions.size(), waitTimeMs));
+ notifyScreenshotOp(screenshotId, smartActionsProvider,
+ ScreenshotNotificationSmartActionsProvider.ScreenshotOp.WAIT_FOR_SMART_ACTIONS,
+ ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.SUCCESS,
+ waitTimeMs);
+ return actions;
+ } catch (Throwable e) {
+ long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
+ Slog.e(TAG, String.format("Error getting smart actions. Wait time: %d ms", waitTimeMs),
+ e);
+ ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus status =
+ (e instanceof TimeoutException)
+ ? ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.TIMEOUT
+ : ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.ERROR;
+ notifyScreenshotOp(screenshotId, smartActionsProvider,
+ ScreenshotNotificationSmartActionsProvider.ScreenshotOp.WAIT_FOR_SMART_ACTIONS,
+ status, waitTimeMs);
+ return Collections.emptyList();
+ }
+ }
+
+ static void notifyScreenshotOp(String screenshotId,
+ ScreenshotNotificationSmartActionsProvider smartActionsProvider,
+ ScreenshotNotificationSmartActionsProvider.ScreenshotOp op,
+ ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus status, long durationMs) {
+ try {
+ smartActionsProvider.notifyOp(screenshotId, op, status, durationMs);
+ } catch (Throwable e) {
+ Slog.e(TAG, "Error in notifyScreenshotOp: ", e);
+ }
+ }
+
+ static void notifyScreenshotAction(Context context, String screenshotId, String action,
+ boolean isSmartAction) {
+ try {
+ ScreenshotNotificationSmartActionsProvider provider =
+ SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider(
+ context, THREAD_POOL_EXECUTOR, new Handler());
+ provider.notifyAction(screenshotId, action, isSmartAction);
+ } catch (Throwable e) {
+ Slog.e(TAG, "Error in notifyScreenshotAction: ", e);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 6243b4b..29b96a9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -42,14 +42,11 @@
@Override
public void handleMessage(Message msg) {
final Messenger callback = msg.replyTo;
- Consumer<Uri> finisher = new Consumer<Uri>() {
- @Override
- public void accept(Uri uri) {
- Message reply = Message.obtain(null, 1, uri);
- try {
- callback.send(reply);
- } catch (RemoteException e) {
- }
+ Consumer<Uri> finisher = uri -> {
+ Message reply = Message.obtain(null, 1, uri);
+ try {
+ callback.send(reply);
+ } catch (RemoteException e) {
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 3ee5d31..2f39c13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -37,7 +37,6 @@
import android.text.format.DateFormat;
import android.util.Log;
-import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -289,21 +288,21 @@
}
private final void updateSimState(Intent intent) {
- String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
- if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+ String stateExtra = intent.getStringExtra(Intent.EXTRA_SIM_STATE);
+ if (Intent.SIM_STATE_ABSENT.equals(stateExtra)) {
mSimState = TelephonyManager.SIM_STATE_READY;
- } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
+ } else if (Intent.SIM_STATE_CARD_IO_ERROR.equals(stateExtra)) {
mSimState = TelephonyManager.SIM_STATE_CARD_IO_ERROR;
- } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED.equals(stateExtra)) {
+ } else if (Intent.SIM_STATE_CARD_RESTRICTED.equals(stateExtra)) {
mSimState = TelephonyManager.SIM_STATE_CARD_RESTRICTED;
- } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+ } else if (Intent.SIM_STATE_READY.equals(stateExtra)) {
mSimState = TelephonyManager.SIM_STATE_READY;
- } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+ } else if (Intent.SIM_STATE_LOCKED.equals(stateExtra)) {
final String lockedReason =
- intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
- if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+ intent.getStringExtra(Intent.EXTRA_SIM_LOCKED_REASON);
+ if (Intent.SIM_LOCKED_ON_PIN.equals(lockedReason)) {
mSimState = TelephonyManager.SIM_STATE_PIN_REQUIRED;
- } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+ } else if (Intent.SIM_LOCKED_ON_PUK.equals(lockedReason)) {
mSimState = TelephonyManager.SIM_STATE_PUK_REQUIRED;
} else {
mSimState = TelephonyManager.SIM_STATE_NETWORK_LOCKED;
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt b/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt
index 62ae7b9..cca76bd 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt
@@ -679,6 +679,7 @@
internal var instanceConstructor: (Any) -> PhysicsAnimator<*> = ::PhysicsAnimator
@JvmStatic
+ @Suppress("UNCHECKED_CAST")
fun <T : Any> getInstance(target: T): PhysicsAnimator<T> {
if (!animators.containsKey(target)) {
animators[target] = instanceConstructor(target)
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimatorTestUtils.kt b/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimatorTestUtils.kt
index a1f74eb..e86970c 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimatorTestUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimatorTestUtils.kt
@@ -142,6 +142,7 @@
*/
@JvmStatic
@Throws(InterruptedException::class)
+ @Suppress("UNCHECKED_CAST")
fun <T : Any> blockUntilAnimationsEnd(
properties: FloatPropertyCompat<in T>
) {
@@ -236,6 +237,14 @@
vararg additionalUpdateMatchers: UpdateMatcher
) {
val updateFrames: UpdateFramesPerProperty<T> = getAnimationUpdateFrames(animator)
+
+ if (!updateFrames.containsKey(property)) {
+ error("No frames for given target object and property.")
+ }
+
+ // Copy the frames to avoid a ConcurrentModificationException if the animation update
+ // listeners attempt to add a new frame while we're verifying these.
+ val framesForProperty = ArrayList(updateFrames[property]!!)
val matchers = ArrayDeque<UpdateMatcher>(
additionalUpdateMatchers.toList())
val frameTraceMessage = StringBuilder()
@@ -243,8 +252,7 @@
var curMatcher = firstUpdateMatcher
// Loop through the updates from the testable animator.
- for (update in updateFrames[property]
- ?: error("No frames for given target object and property.")) {
+ for (update in framesForProperty) {
// Check whether this frame satisfies the current matcher.
if (curMatcher(update)) {
@@ -320,6 +328,7 @@
/**
* Returns all of the values that have ever been reported to update listeners, per property.
*/
+ @Suppress("UNCHECKED_CAST")
fun <T : Any> getAnimationUpdateFrames(animator: PhysicsAnimator<T>):
UpdateFramesPerProperty<T> {
return animatorTestHelpers[animator]?.getUpdates() as UpdateFramesPerProperty<T>
@@ -333,6 +342,7 @@
animatorTestHelpers[animator]?.clearUpdates()
}
+ @Suppress("UNCHECKED_CAST")
private fun <T> getAnimationTestHelper(animator: PhysicsAnimator<T>): AnimatorTestHelper<T> {
return animatorTestHelpers[animator] as AnimatorTestHelper<T>
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index f5c1587..af218c49 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -160,6 +160,7 @@
private boolean mHovering = false;
private boolean mShowActiveStreamOnly;
private boolean mConfigChanged = false;
+ private boolean mIsAnimatingDismiss = false;
private boolean mHasSeenODICaptionsTooltip;
private ViewStub mODICaptionsTooltipViewStub;
private View mODICaptionsTooltipView = null;
@@ -693,6 +694,7 @@
initSettingsH();
mShowing = true;
+ mIsAnimatingDismiss = false;
mDialog.show();
Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
mController.notifyVisible(true);
@@ -737,6 +739,10 @@
}
mHandler.removeMessages(H.DISMISS);
mHandler.removeMessages(H.SHOW);
+ if (mIsAnimatingDismiss) {
+ return;
+ }
+ mIsAnimatingDismiss = true;
mDialogView.animate().cancel();
if (mShowing) {
mShowing = false;
@@ -752,6 +758,7 @@
.withEndAction(() -> mHandler.postDelayed(() -> {
mDialog.dismiss();
tryToRemoveCaptionsTooltip();
+ mIsAnimatingDismiss = false;
}, 50));
if (!isLandscape()) animator.translationX(mDialogView.getWidth() / 2.0f);
animator.start();
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayWindowController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayWindowController.java
index ae82115..aa56ffb 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayWindowController.java
@@ -101,10 +101,11 @@
}
DisplayRecord record = new DisplayRecord();
record.mDisplayId = displayId;
- Display display = getDisplay(displayId);
- record.mContext = (displayId == Display.DEFAULT_DISPLAY) ? mContext
- : mContext.createDisplayContext(display);
- record.mDisplayLayout = new DisplayLayout(record.mContext, display);
+ // TODO(b/146566787): disabled for MultiDisplayActivityLaunchTests
+ // Display display = getDisplay(displayId);
+ // record.mContext = (displayId == Display.DEFAULT_DISPLAY) ? mContext
+ // : mContext.createDisplayContext(display);
+ // record.mDisplayLayout = new DisplayLayout(record.mContext, display);
mDisplays.put(displayId, record);
for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
mDisplayChangedListeners.get(i).onDisplayAdded(displayId);
@@ -123,13 +124,14 @@
+ " display.");
return;
}
- Display display = getDisplay(displayId);
- Context perDisplayContext = mContext;
- if (displayId != Display.DEFAULT_DISPLAY) {
- perDisplayContext = mContext.createDisplayContext(display);
- }
- dr.mContext = perDisplayContext.createConfigurationContext(newConfig);
- dr.mDisplayLayout = new DisplayLayout(dr.mContext, display);
+ // TODO(b/146566787): disabled for MultiDisplaySystemDecorationTests
+ // Display display = getDisplay(displayId);
+ // Context perDisplayContext = mContext;
+ // if (displayId != Display.DEFAULT_DISPLAY) {
+ // perDisplayContext = mContext.createDisplayContext(display);
+ // }
+ // dr.mContext = perDisplayContext.createConfigurationContext(newConfig);
+ // dr.mDisplayLayout = new DisplayLayout(dr.mContext, display);
for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
mDisplayChangedListeners.get(i).onDisplayConfigurationChanged(
displayId, newConfig);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 7be3e2b..4bf1e1c 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -57,7 +57,6 @@
import android.testing.TestableContext;
import android.testing.TestableLooper;
-import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.systemui.DumpController;
@@ -183,8 +182,8 @@
@Test
public void testTelephonyCapable_SimState_Absent() {
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
- intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE,
- IccCardConstants.INTENT_VALUE_ICC_ABSENT);
+ intent.putExtra(Intent.EXTRA_SIM_STATE,
+ Intent.SIM_STATE_ABSENT);
mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(),
putPhoneInfo(intent, null, false));
mTestableLooper.processAllMessages();
@@ -194,8 +193,8 @@
@Test
public void testTelephonyCapable_SimState_CardIOError() {
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
- intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE,
- IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR);
+ intent.putExtra(Intent.EXTRA_SIM_STATE,
+ Intent.SIM_STATE_CARD_IO_ERROR);
mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(),
putPhoneInfo(intent, null, false));
mTestableLooper.processAllMessages();
@@ -221,8 +220,8 @@
// Simulate AirplaneMode case, SERVICE_STATE - POWER_OFF, check TelephonyCapable False
// Only receive ServiceState callback IN_SERVICE -> OUT_OF_SERVICE -> POWER_OFF
Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
- intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE
- , IccCardConstants.INTENT_VALUE_ICC_LOADED);
+ intent.putExtra(Intent.EXTRA_SIM_STATE
+ , Intent.SIM_STATE_LOADED);
Bundle data = new Bundle();
ServiceState state = new ServiceState();
state.setState(ServiceState.STATE_POWER_OFF);
@@ -261,8 +260,8 @@
state.setState(ServiceState.STATE_OUT_OF_SERVICE);
state.fillInNotifierBundle(data);
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
- intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE
- , IccCardConstants.INTENT_VALUE_ICC_NOT_READY);
+ intent.putExtra(Intent.EXTRA_SIM_STATE
+ , Intent.SIM_STATE_NOT_READY);
mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intent, data, false));
mTestableLooper.processAllMessages();
@@ -276,8 +275,8 @@
state.setState(ServiceState.STATE_OUT_OF_SERVICE);
state.fillInNotifierBundle(data);
Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
- intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE
- , IccCardConstants.INTENT_VALUE_ICC_READY);
+ intent.putExtra(Intent.EXTRA_SIM_STATE
+ , Intent.SIM_STATE_READY);
mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intent, data, false));
mTestableLooper.processAllMessages();
@@ -317,8 +316,8 @@
state.setState(ServiceState.STATE_IN_SERVICE);
state.fillInNotifierBundle(data);
Intent intentSimState = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
- intentSimState.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE
- , IccCardConstants.INTENT_VALUE_ICC_LOADED);
+ intentSimState.putExtra(Intent.EXTRA_SIM_STATE
+ , Intent.SIM_STATE_LOADED);
mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intentSimState, data, true));
mTestableLooper.processAllMessages();
@@ -326,8 +325,8 @@
assertThat(mKeyguardUpdateMonitor.mTelephonyCapable).isFalse();
Intent intentServiceState = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
- intentSimState.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE
- , IccCardConstants.INTENT_VALUE_ICC_LOADED);
+ intentSimState.putExtra(Intent.EXTRA_SIM_STATE
+ , Intent.SIM_STATE_LOADED);
mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
, putPhoneInfo(intentServiceState, data, true));
mTestableLooper.processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/EglHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/EglHelperTest.java
index b4a60d6..a5722e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/EglHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/EglHelperTest.java
@@ -52,7 +52,7 @@
@Test
public void testInit_finish() {
- mEglHelper.init(mSurfaceHolder);
+ mEglHelper.init(mSurfaceHolder, false /* wideColorGamut */);
mEglHelper.finish();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
index 6d85d37..2c7cee3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
@@ -16,8 +16,6 @@
package com.android.systemui.screenshot;
-import static android.content.Context.NOTIFICATION_SERVICE;
-
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
@@ -29,7 +27,6 @@
import static org.mockito.Mockito.when;
import android.app.Notification;
-import android.app.NotificationManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
@@ -42,7 +39,6 @@
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.util.NotificationChannels;
import org.junit.Assert;
import org.junit.Before;
@@ -84,7 +80,7 @@
eq(false))).thenThrow(
RuntimeException.class);
CompletableFuture<List<Notification.Action>> smartActionsFuture =
- GlobalScreenshot.getSmartActionsFuture("", bitmap,
+ ScreenshotSmartActions.getSmartActionsFuture("", bitmap,
smartActionsProvider, true, false);
Assert.assertNotNull(smartActionsFuture);
List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
@@ -101,7 +97,7 @@
int timeoutMs = 1000;
when(smartActionsFuture.get(timeoutMs, TimeUnit.MILLISECONDS)).thenThrow(
RuntimeException.class);
- List<Notification.Action> actions = GlobalScreenshot.getSmartActions(
+ List<Notification.Action> actions = ScreenshotSmartActions.getSmartActions(
"", smartActionsFuture, timeoutMs, mSmartActionsProvider);
Assert.assertEquals(Collections.emptyList(), actions);
}
@@ -112,7 +108,7 @@
throws Exception {
doThrow(RuntimeException.class).when(mSmartActionsProvider).notifyOp(any(), any(), any(),
anyLong());
- GlobalScreenshot.notifyScreenshotOp(null, mSmartActionsProvider, null, null, -1);
+ ScreenshotSmartActions.notifyScreenshotOp(null, mSmartActionsProvider, null, null, -1);
}
// Tests for a non-hardware bitmap, ScreenshotNotificationSmartActionsProvider is never invoked
@@ -123,7 +119,7 @@
Bitmap bitmap = mock(Bitmap.class);
when(bitmap.getConfig()).thenReturn(Bitmap.Config.RGB_565);
CompletableFuture<List<Notification.Action>> smartActionsFuture =
- GlobalScreenshot.getSmartActionsFuture("", bitmap,
+ ScreenshotSmartActions.getSmartActionsFuture("", bitmap,
mSmartActionsProvider, true, true);
verify(mSmartActionsProvider, never()).getActions(any(), any(), any(),
eq(false));
@@ -137,7 +133,7 @@
public void testScreenshotNotificationSmartActionsProviderInvokedOnce() {
Bitmap bitmap = mock(Bitmap.class);
when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
- GlobalScreenshot.getSmartActionsFuture("", bitmap, mSmartActionsProvider,
+ ScreenshotSmartActions.getSmartActionsFuture("", bitmap, mSmartActionsProvider,
true, true);
verify(mSmartActionsProvider, times(1))
.getActions(any(), any(), any(), eq(true));
@@ -153,7 +149,7 @@
SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider(
mContext, null, mHandler);
CompletableFuture<List<Notification.Action>> smartActionsFuture =
- GlobalScreenshot.getSmartActionsFuture("", bitmap,
+ ScreenshotSmartActions.getSmartActionsFuture("", bitmap,
actionsProvider,
true, true);
Assert.assertNotNull(smartActionsFuture);
@@ -167,31 +163,23 @@
if (Looper.myLooper() == null) {
Looper.prepare();
}
- NotificationManager notificationManager =
- (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);
+
GlobalScreenshot.SaveImageInBackgroundData
data = new GlobalScreenshot.SaveImageInBackgroundData();
- data.context = mContext;
data.image = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
- data.iconSize = 10;
data.finisher = null;
data.mActionsReadyListener = null;
- data.previewWidth = 10;
- data.previewheight = 10;
- SaveImageInBackgroundTask task = new SaveImageInBackgroundTask(mContext, data,
- notificationManager);
- Notification.Builder notificationBuilder = new Notification.Builder(mContext,
- NotificationChannels.SCREENSHOTS_HEADSUP);
- task.populateNotificationActions(mContext, mContext.getResources(),
+ SaveImageInBackgroundTask task = new SaveImageInBackgroundTask(mContext, data);
+ List<Notification.Action> actions = task.populateNotificationActions(
+ mContext, mContext.getResources(),
Uri.parse("Screenshot_123.png"),
- CompletableFuture.completedFuture(Collections.emptyList()), notificationBuilder);
+ CompletableFuture.completedFuture(Collections.emptyList()));
- Notification notification = notificationBuilder.build();
- Assert.assertEquals(notification.actions.length, 3);
+ Assert.assertEquals(actions.size(), 3);
boolean isShareFound = false;
boolean isEditFound = false;
boolean isDeleteFound = false;
- for (Notification.Action action : notification.actions) {
+ for (Notification.Action action : actions) {
Intent intent = action.actionIntent.getIntent();
Assert.assertNotNull(intent);
Bundle bundle = intent.getExtras();
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index 3c953b3..08552cb 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -29,9 +29,11 @@
"netlink-client",
"networkstack-aidl-interfaces-unstable-java",
"android.hardware.tetheroffload.control-V1.0-java",
- "tethering-client",
],
- libs: ["unsupportedappusage"],
+ libs: [
+ "framework-tethering",
+ ],
+
manifest: "AndroidManifestBase.xml",
}
@@ -90,6 +92,10 @@
resource_dirs: [
"res",
],
+ libs: [
+ "framework-tethering",
+ ],
+ jarjar_rules: "jarjar-rules.txt",
optimize: {
proguard_flags_files: ["proguard.flags"],
},
@@ -104,7 +110,6 @@
manifest: "AndroidManifest_InProcess.xml",
// InProcessTethering is a replacement for Tethering
overrides: ["Tethering"],
- // TODO: use PlatformNetworkPermissionConfig.
}
// Updatable tethering packaged as an application
diff --git a/packages/Tethering/AndroidManifest.xml b/packages/Tethering/AndroidManifest.xml
index 8ba05df..87a8c3f 100644
--- a/packages/Tethering/AndroidManifest.xml
+++ b/packages/Tethering/AndroidManifest.xml
@@ -21,6 +21,21 @@
android:sharedUserId="android.uid.networkstack">
<uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
+ <!-- Permissions must be defined here, and not in the base manifest, as the tethering
+ running in the system server process does not need any permission, and having
+ privileged permissions added would cause crashes on startup unless they are also
+ added to the privileged permissions whitelist for that package. -->
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.BLUETOOTH" />
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+ <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.MANAGE_USB" />
+ <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+ <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
+ <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
+ <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+
<application
android:process="com.android.networkstack.process"
android:extractNativeLibs="false"
diff --git a/packages/Tethering/AndroidManifest_InProcess.xml b/packages/Tethering/AndroidManifest_InProcess.xml
index 029b6c3..02ea551 100644
--- a/packages/Tethering/AndroidManifest_InProcess.xml
+++ b/packages/Tethering/AndroidManifest_InProcess.xml
@@ -22,11 +22,9 @@
android:process="system">
<uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
<application>
- <!-- TODO: Using MAINLINE_NETWORK_STACK instead of NETWORK_STACK when tethering run in the
- same process with networkstack -->
<service android:name="com.android.server.connectivity.tethering.TetheringService"
android:process="system"
- android:permission="android.permission.NETWORK_STACK">
+ android:permission="android.permission.MAINLINE_NETWORK_STACK">
<intent-filter>
<action android:name="android.net.ITetheringConnector.InProcess"/>
</intent-filter>
diff --git a/packages/Tethering/apex/Android.bp b/packages/Tethering/apex/Android.bp
index af6af93..94ef11c 100644
--- a/packages/Tethering/apex/Android.bp
+++ b/packages/Tethering/apex/Android.bp
@@ -16,6 +16,7 @@
apex {
name: "com.android.tethering",
+ java_libs: ["framework-tethering"],
apps: ["Tethering"],
manifest: "manifest.json",
key: "com.android.tethering.key",
diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp
index adc5a72..5785707 100644
--- a/packages/Tethering/common/TetheringLib/Android.bp
+++ b/packages/Tethering/common/TetheringLib/Android.bp
@@ -12,7 +12,6 @@
// 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.
-//
// AIDL interfaces between the core system and the tethering mainline module.
aidl_interface {
@@ -20,10 +19,7 @@
local_include_dir: "src",
include_dirs: ["frameworks/base/core/java"], // For framework parcelables.
srcs: [
- "src/android/net/ITetherInternalCallback.aidl",
- "src/android/net/ITetheringConnector.aidl",
- "src/android/net/TetheringConfigurationParcel.aidl",
- "src/android/net/TetherStatesParcel.aidl",
+ "src/android/net/*.aidl",
],
backend: {
ndk: {
@@ -36,16 +32,32 @@
}
java_library {
- name: "tethering-client",
+ name: "framework-tethering",
sdk_version: "system_current",
+ srcs: [
+ "src/android/net/TetheringManager.java",
+ ":framework-tethering-annotations",
+ ],
static_libs: [
"tethering-aidl-interfaces-java",
],
+ jarjar_rules: "jarjar-rules.txt",
+ installable: true,
+
+ libs: [
+ "android_system_stubs_current",
+ ],
}
-// This is temporary file group which would be removed after TetheringManager is built
-// into tethering-client. Will be done by aosp/1156906.
filegroup {
- name: "tethering-manager",
- srcs: ["src/android/net/TetheringManager.java"],
+ name: "framework-tethering-srcs",
+ srcs: [
+ "src/android/net/TetheringManager.java",
+ "src/android/net/IIntResultListener.aidl",
+ "src/android/net/ITetheringEventCallback.aidl",
+ "src/android/net/ITetheringConnector.aidl",
+ "src/android/net/TetheringConfigurationParcel.aidl",
+ "src/android/net/TetherStatesParcel.aidl",
+ ],
+ path: "src"
}
diff --git a/packages/Tethering/common/TetheringLib/jarjar-rules.txt b/packages/Tethering/common/TetheringLib/jarjar-rules.txt
new file mode 100644
index 0000000..35e0f88
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/jarjar-rules.txt
@@ -0,0 +1 @@
+rule android.annotation.** com.android.networkstack.tethering.annotation.@1
diff --git a/core/java/android/net/ITetheringEventCallback.aidl b/packages/Tethering/common/TetheringLib/src/android/net/IIntResultListener.aidl
similarity index 77%
rename from core/java/android/net/ITetheringEventCallback.aidl
rename to packages/Tethering/common/TetheringLib/src/android/net/IIntResultListener.aidl
index d502088..c3d66ee 100644
--- a/core/java/android/net/ITetheringEventCallback.aidl
+++ b/packages/Tethering/common/TetheringLib/src/android/net/IIntResultListener.aidl
@@ -16,13 +16,10 @@
package android.net;
-import android.net.Network;
-
/**
- * Callback class for receiving tethering changed events
- * @hide
+ * Listener interface allowing objects to listen to various module event.
+ * {@hide}
*/
-oneway interface ITetheringEventCallback
-{
- void onUpstreamChanged(in Network network);
+oneway interface IIntResultListener {
+ void onResult(int resultCode);
}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl b/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl
index bfe502f..d30c399 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl
+++ b/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl
@@ -15,23 +15,31 @@
*/
package android.net;
-import android.net.ITetherInternalCallback;
+import android.net.IIntResultListener;
+import android.net.ITetheringEventCallback;
import android.os.ResultReceiver;
/** @hide */
oneway interface ITetheringConnector {
- void tether(String iface);
+ void tether(String iface, String callerPkg, IIntResultListener receiver);
- void untether(String iface);
+ void untether(String iface, String callerPkg, IIntResultListener receiver);
- void setUsbTethering(boolean enable);
+ void setUsbTethering(boolean enable, String callerPkg, IIntResultListener receiver);
- void startTethering(int type, in ResultReceiver receiver, boolean showProvisioningUi);
+ void startTethering(int type, in ResultReceiver receiver, boolean showProvisioningUi,
+ String callerPkg);
- void stopTethering(int type);
+ void stopTethering(int type, String callerPkg, IIntResultListener receiver);
void requestLatestTetheringEntitlementResult(int type, in ResultReceiver receiver,
- boolean showEntitlementUi);
+ boolean showEntitlementUi, String callerPkg);
- void registerTetherInternalCallback(ITetherInternalCallback callback);
+ void registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
+
+ void unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
+
+ void isTetheringSupported(String callerPkg, IIntResultListener receiver);
+
+ void stopAllTethering(String callerPkg, IIntResultListener receiver);
}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/ITetherInternalCallback.aidl b/packages/Tethering/common/TetheringLib/src/android/net/ITetheringEventCallback.aidl
similarity index 83%
rename from packages/Tethering/common/TetheringLib/src/android/net/ITetherInternalCallback.aidl
rename to packages/Tethering/common/TetheringLib/src/android/net/ITetheringEventCallback.aidl
index abb00e8..2836195 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/ITetherInternalCallback.aidl
+++ b/packages/Tethering/common/TetheringLib/src/android/net/ITetheringEventCallback.aidl
@@ -21,14 +21,15 @@
import android.net.TetherStatesParcel;
/**
- * Callback class for receiving tethering changed events
+ * Callback class for receiving tethering changed events.
* @hide
*/
-oneway interface ITetherInternalCallback
+oneway interface ITetheringEventCallback
{
+ void onCallbackStarted(in Network network, in TetheringConfigurationParcel config,
+ in TetherStatesParcel states);
+ void onCallbackStopped(int errorCode);
void onUpstreamChanged(in Network network);
void onConfigurationChanged(in TetheringConfigurationParcel config);
void onTetherStatesChanged(in TetherStatesParcel states);
- void onCallbackCreated(in Network network, in TetheringConfigurationParcel config,
- in TetherStatesParcel states);
}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
index 7fb286b..a49ab85 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
+++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
@@ -15,95 +15,142 @@
*/
package android.net;
-import static android.Manifest.permission.NETWORK_STACK;
import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
-import static android.net.ConnectivityManager.TETHER_ERROR_SERVICE_UNAVAIL;
import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.util.SharedLog;
+import android.content.Context;
+import android.net.ConnectivityManager.OnTetheringEventCallback;
import android.os.ConditionVariable;
import android.os.IBinder;
-import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
-import android.util.Slog;
+import android.util.ArrayMap;
+import android.util.Log;
-import com.android.internal.annotations.GuardedBy;
-
-import java.io.PrintWriter;
-import java.util.StringJoiner;
+import java.util.concurrent.Executor;
/**
- * Service used to communicate with the tethering, which is running in a separate module.
+ * This class provides the APIs to control the tethering service.
+ * <p> The primary responsibilities of this class are to provide the APIs for applications to
+ * start tethering, stop tethering, query configuration and query status.
+ *
* @hide
*/
+// TODO: make it @SystemApi
public class TetheringManager {
private static final String TAG = TetheringManager.class.getSimpleName();
+ private static final int DEFAULT_TIMEOUT_MS = 60_000;
private static TetheringManager sInstance;
- @Nullable
- private ITetheringConnector mConnector;
- private TetherInternalCallback mCallback;
- private Network mTetherUpstream;
+ private final ITetheringConnector mConnector;
+ private final TetheringCallbackInternal mCallback;
+ private final Context mContext;
+ private final ArrayMap<OnTetheringEventCallback, ITetheringEventCallback>
+ mTetheringEventCallbacks = new ArrayMap<>();
+
private TetheringConfigurationParcel mTetheringConfiguration;
private TetherStatesParcel mTetherStatesParcel;
- private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks =
- new RemoteCallbackList<>();
- @GuardedBy("mLog")
- private final SharedLog mLog = new SharedLog(TAG);
-
- private TetheringManager() { }
+ public static final int TETHER_ERROR_NO_ERROR = 0;
+ public static final int TETHER_ERROR_UNKNOWN_IFACE = 1;
+ public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2;
+ public static final int TETHER_ERROR_UNSUPPORTED = 3;
+ public static final int TETHER_ERROR_UNAVAIL_IFACE = 4;
+ public static final int TETHER_ERROR_MASTER_ERROR = 5;
+ public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
+ public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
+ public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8;
+ public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9;
+ public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10;
+ public static final int TETHER_ERROR_PROVISION_FAILED = 11;
+ public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12;
+ public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN = 13;
+ public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14;
+ public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15;
/**
- * Get the TetheringManager singleton instance.
+ * Create a TetheringManager object for interacting with the tethering service.
*/
- public static synchronized TetheringManager getInstance() {
- if (sInstance == null) {
- sInstance = new TetheringManager();
- }
- return sInstance;
- }
+ public TetheringManager(@NonNull final Context context, @NonNull final IBinder service) {
+ mContext = context;
+ mConnector = ITetheringConnector.Stub.asInterface(service);
+ mCallback = new TetheringCallbackInternal();
- private class TetheringConnection implements
- ConnectivityModuleConnector.ModuleServiceCallback {
- @Override
- public void onModuleServiceConnected(@NonNull IBinder service) {
- logi("Tethering service connected");
- registerTetheringService(service);
- }
- }
-
- private void registerTetheringService(@NonNull IBinder service) {
- final ITetheringConnector connector = ITetheringConnector.Stub.asInterface(service);
-
- log("Tethering service registered");
-
- // Currently TetheringManager instance is only used by ConnectivityService and mConnector
- // only expect to assign once when system server start and bind tethering service.
- // STOPSHIP: Change mConnector to final before TetheringManager put into boot classpath.
- mConnector = connector;
- mCallback = new TetherInternalCallback();
+ final String pkgName = mContext.getOpPackageName();
+ Log.i(TAG, "registerTetheringEventCallback:" + pkgName);
try {
- mConnector.registerTetherInternalCallback(mCallback);
+ mConnector.registerTetheringEventCallback(mCallback, pkgName);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw new IllegalStateException(e);
}
}
- private class TetherInternalCallback extends ITetherInternalCallback.Stub {
- private final ConditionVariable mWaitForCallback = new ConditionVariable(false);
- private static final int EVENT_CALLBACK_TIMEOUT_MS = 60_000;
+ private interface RequestHelper {
+ void runRequest(IIntResultListener listener);
+ }
+
+ private class RequestDispatcher {
+ private final ConditionVariable mWaiting;
+ public int mRemoteResult;
+
+ private final IIntResultListener mListener = new IIntResultListener.Stub() {
+ @Override
+ public void onResult(final int resultCode) {
+ mRemoteResult = resultCode;
+ mWaiting.open();
+ }
+ };
+
+ RequestDispatcher() {
+ mWaiting = new ConditionVariable();
+ }
+
+ int waitForResult(final RequestHelper request) {
+ request.runRequest(mListener);
+ if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) {
+ throw new IllegalStateException("Callback timeout");
+ }
+
+ throwIfPermissionFailure(mRemoteResult);
+
+ return mRemoteResult;
+ }
+ }
+
+ private void throwIfPermissionFailure(final int errorCode) {
+ switch (errorCode) {
+ case TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION:
+ throw new SecurityException("No android.permission.TETHER_PRIVILEGED"
+ + " or android.permission.WRITE_SETTINGS permission");
+ case TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION:
+ throw new SecurityException(
+ "No android.permission.ACCESS_NETWORK_STATE permission");
+ }
+ }
+
+ private class TetheringCallbackInternal extends ITetheringEventCallback.Stub {
+ private int mError = TETHER_ERROR_NO_ERROR;
+ private final ConditionVariable mWaitForCallback = new ConditionVariable();
@Override
- public void onUpstreamChanged(Network network) {
- mTetherUpstream = network;
- reportUpstreamChanged(network);
+ public void onCallbackStarted(Network network, TetheringConfigurationParcel config,
+ TetherStatesParcel states) {
+ mTetheringConfiguration = config;
+ mTetherStatesParcel = states;
+ mWaitForCallback.open();
}
@Override
+ public void onCallbackStopped(int errorCode) {
+ mError = errorCode;
+ mWaitForCallback.open();
+ }
+
+ @Override
+ public void onUpstreamChanged(Network network) { }
+
+ @Override
public void onConfigurationChanged(TetheringConfigurationParcel config) {
mTetheringConfiguration = config;
}
@@ -113,49 +160,10 @@
mTetherStatesParcel = states;
}
- @Override
- public void onCallbackCreated(Network network, TetheringConfigurationParcel config,
- TetherStatesParcel states) {
- mTetherUpstream = network;
- mTetheringConfiguration = config;
- mTetherStatesParcel = states;
- mWaitForCallback.open();
+ public void waitForStarted() {
+ mWaitForCallback.block(DEFAULT_TIMEOUT_MS);
+ throwIfPermissionFailure(mError);
}
-
- boolean awaitCallbackCreation() {
- return mWaitForCallback.block(EVENT_CALLBACK_TIMEOUT_MS);
- }
- }
-
- private void reportUpstreamChanged(Network network) {
- final int length = mTetheringEventCallbacks.beginBroadcast();
- try {
- for (int i = 0; i < length; i++) {
- try {
- mTetheringEventCallbacks.getBroadcastItem(i).onUpstreamChanged(network);
- } catch (RemoteException e) {
- // Not really very much to do here.
- }
- }
- } finally {
- mTetheringEventCallbacks.finishBroadcast();
- }
- }
-
- /**
- * Start the tethering service. Should be called only once on device startup.
- *
- * <p>This method will start the tethering service either in the network stack process,
- * or inside the system server on devices that do not support the tethering module.
- *
- * {@hide}
- */
- public void start() {
- // Using MAINLINE_NETWORK_STACK permission after cutting off the dpendency of system server.
- ConnectivityModuleConnector.getInstance().startModuleService(
- ITetheringConnector.class.getName(), NETWORK_STACK,
- new TetheringConnection());
- log("Tethering service start requested");
}
/**
@@ -165,108 +173,110 @@
* IP network interface is available, dhcp will still run and traffic will be
* allowed between the tethered devices and this device, though upstream net
* access will of course fail until an upstream network interface becomes
- * active. Note: return value do not have any meaning. It is better to use
- * #getTetherableIfaces() to ensure corresponding interface is available for
- * tethering before calling #tether().
+ * active.
*
- * @deprecated The only usages should be in PanService and Wifi P2P which
- * need direct access.
+ * @deprecated The only usages is PanService. It uses this for legacy reasons
+ * and will migrate away as soon as possible.
*
- * {@hide}
+ * @param iface the interface name to tether.
+ * @return error a {@code TETHER_ERROR} value indicating success or failure type
*/
@Deprecated
- public int tether(@NonNull String iface) {
- if (mConnector == null) {
- Slog.wtf(TAG, "Tethering not ready yet");
- return TETHER_ERROR_SERVICE_UNAVAIL;
- }
- try {
- mConnector.tether(iface);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- return TETHER_ERROR_NO_ERROR;
+ public int tether(@NonNull final String iface) {
+ final String callerPkg = mContext.getOpPackageName();
+ Log.i(TAG, "tether caller:" + callerPkg);
+ final RequestDispatcher dispatcher = new RequestDispatcher();
+
+ return dispatcher.waitForResult(listener -> {
+ try {
+ mConnector.tether(iface, callerPkg, listener);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ });
}
/**
* Stop tethering the named interface.
*
- * @deprecated
- * {@hide}
+ * @deprecated The only usages is PanService. It uses this for legacy reasons
+ * and will migrate away as soon as possible.
*/
@Deprecated
- public int untether(@NonNull String iface) {
- if (mConnector == null) {
- Slog.wtf(TAG, "Tethering not ready yet");
- return TETHER_ERROR_SERVICE_UNAVAIL;
- }
- try {
- mConnector.untether(iface);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- return TETHER_ERROR_NO_ERROR;
+ public int untether(@NonNull final String iface) {
+ final String callerPkg = mContext.getOpPackageName();
+ Log.i(TAG, "untether caller:" + callerPkg);
+
+ final RequestDispatcher dispatcher = new RequestDispatcher();
+
+ return dispatcher.waitForResult(listener -> {
+ try {
+ mConnector.untether(iface, callerPkg, listener);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ });
}
/**
- * Attempt to both alter the mode of USB and Tethering of USB. WARNING: New client should not
- * use this API anymore. All clients should use #startTethering or #stopTethering which
- * encapsulate proper entitlement logic. If the API is used and an entitlement check is needed,
- * downstream USB tethering will be enabled but will not have any upstream.
+ * Attempt to both alter the mode of USB and Tethering of USB.
*
- * @deprecated
- * {@hide}
+ * @deprecated New client should not use this API anymore. All clients should use
+ * #startTethering or #stopTethering which encapsulate proper entitlement logic. If the API is
+ * used and an entitlement check is needed, downstream USB tethering will be enabled but will
+ * not have any upstream.
*/
@Deprecated
- public int setUsbTethering(boolean enable) {
- if (mConnector == null) {
- Slog.wtf(TAG, "Tethering not ready yet");
- return TETHER_ERROR_SERVICE_UNAVAIL;
- }
- try {
- mConnector.setUsbTethering(enable);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- return TETHER_ERROR_NO_ERROR;
+ public int setUsbTethering(final boolean enable) {
+ final String callerPkg = mContext.getOpPackageName();
+ Log.i(TAG, "setUsbTethering caller:" + callerPkg);
+
+ final RequestDispatcher dispatcher = new RequestDispatcher();
+
+ return dispatcher.waitForResult(listener -> {
+ try {
+ mConnector.setUsbTethering(enable, callerPkg, listener);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ });
}
/**
* Starts tethering and runs tether provisioning for the given type if needed. If provisioning
* fails, stopTethering will be called automatically.
*
- * {@hide}
*/
// TODO: improve the usage of ResultReceiver, b/145096122
- public void startTethering(int type, @NonNull ResultReceiver receiver,
- boolean showProvisioningUi) {
- if (mConnector == null) {
- Slog.wtf(TAG, "Tethering not ready yet");
- return;
- }
+ public void startTethering(final int type, @NonNull final ResultReceiver receiver,
+ final boolean showProvisioningUi) {
+ final String callerPkg = mContext.getOpPackageName();
+ Log.i(TAG, "startTethering caller:" + callerPkg);
+
try {
- mConnector.startTethering(type, receiver, showProvisioningUi);
+ mConnector.startTethering(type, receiver, showProvisioningUi, callerPkg);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw new IllegalStateException(e);
}
}
/**
* Stops tethering for the given type. Also cancels any provisioning rechecks for that type if
* applicable.
- *
- * {@hide}
*/
- public void stopTethering(int type) {
- if (mConnector == null) {
- Slog.wtf(TAG, "Tethering not ready yet");
- return;
- }
- try {
- mConnector.stopTethering(type);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
+ public void stopTethering(final int type) {
+ final String callerPkg = mContext.getOpPackageName();
+ Log.i(TAG, "stopTethering caller:" + callerPkg);
+
+ final RequestDispatcher dispatcher = new RequestDispatcher();
+
+ dispatcher.waitForResult(listener -> {
+ try {
+ mConnector.stopTethering(type, callerPkg, listener);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ });
}
/**
@@ -277,47 +287,109 @@
* if it's really needed.
*/
// TODO: improve the usage of ResultReceiver, b/145096122
- public void requestLatestTetheringEntitlementResult(int type, @NonNull ResultReceiver receiver,
- boolean showEntitlementUi) {
- if (mConnector == null) {
- Slog.wtf(TAG, "Tethering not ready yet");
- return;
- }
+ public void requestLatestTetheringEntitlementResult(final int type,
+ @NonNull final ResultReceiver receiver, final boolean showEntitlementUi) {
+ final String callerPkg = mContext.getOpPackageName();
+ Log.i(TAG, "getLatestTetheringEntitlementResult caller:" + callerPkg);
+
try {
- mConnector.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
+ mConnector.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi,
+ callerPkg);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ throw new IllegalStateException(e);
}
}
/**
- * Register tethering event callback.
+ * Start listening to tethering change events. Any new added callback will receive the last
+ * tethering status right away. If callback is registered,
+ * {@link OnTetheringEventCallback#onUpstreamChanged} will immediately be called. If tethering
+ * has no upstream or disabled, the argument of callback will be null. The same callback object
+ * cannot be registered twice.
*
- * {@hide}
+ * @param executor the executor on which callback will be invoked.
+ * @param callback the callback to be called when tethering has change events.
*/
- public void registerTetheringEventCallback(@NonNull ITetheringEventCallback callback) {
- mTetheringEventCallbacks.register(callback);
+ public void registerTetheringEventCallback(@NonNull Executor executor,
+ @NonNull OnTetheringEventCallback callback) {
+ final String callerPkg = mContext.getOpPackageName();
+ Log.i(TAG, "registerTetheringEventCallback caller:" + callerPkg);
+
+ synchronized (mTetheringEventCallbacks) {
+ if (!mTetheringEventCallbacks.containsKey(callback)) {
+ throw new IllegalArgumentException("callback was already registered.");
+ }
+ final ITetheringEventCallback remoteCallback = new ITetheringEventCallback.Stub() {
+ @Override
+ public void onUpstreamChanged(Network network) throws RemoteException {
+ executor.execute(() -> {
+ callback.onUpstreamChanged(network);
+ });
+ }
+
+ @Override
+ public void onCallbackStarted(Network network, TetheringConfigurationParcel config,
+ TetherStatesParcel states) {
+ executor.execute(() -> {
+ callback.onUpstreamChanged(network);
+ });
+ }
+
+ @Override
+ public void onCallbackStopped(int errorCode) {
+ executor.execute(() -> {
+ throwIfPermissionFailure(errorCode);
+ });
+ }
+
+ @Override
+ public void onConfigurationChanged(TetheringConfigurationParcel config) { }
+
+ @Override
+ public void onTetherStatesChanged(TetherStatesParcel states) { }
+ };
+ try {
+ mConnector.registerTetheringEventCallback(remoteCallback, callerPkg);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ mTetheringEventCallbacks.put(callback, remoteCallback);
+ }
}
/**
- * Unregister tethering event callback.
+ * Remove tethering event callback previously registered with
+ * {@link #registerTetheringEventCallback}.
*
- * {@hide}
+ * @param callback previously registered callback.
*/
- public void unregisterTetheringEventCallback(@NonNull ITetheringEventCallback callback) {
- mTetheringEventCallbacks.unregister(callback);
+ public void unregisterTetheringEventCallback(@NonNull final OnTetheringEventCallback callback) {
+ final String callerPkg = mContext.getOpPackageName();
+ Log.i(TAG, "unregisterTetheringEventCallback caller:" + callerPkg);
+
+ synchronized (mTetheringEventCallbacks) {
+ ITetheringEventCallback remoteCallback = mTetheringEventCallbacks.remove(callback);
+ if (remoteCallback == null) {
+ throw new IllegalArgumentException("callback was not registered.");
+ }
+ try {
+ mConnector.unregisterTetheringEventCallback(remoteCallback, callerPkg);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ }
}
/**
* Get a more detailed error code after a Tethering or Untethering
* request asynchronously failed.
*
- * {@hide}
+ * @param iface The name of the interface of interest
+ * @return error The error code of the last error tethering or untethering the named
+ * interface
*/
- public int getLastTetherError(@NonNull String iface) {
- if (!mCallback.awaitCallbackCreation()) {
- throw new NullPointerException("callback was not ready yet");
- }
+ public int getLastTetherError(@NonNull final String iface) {
+ mCallback.waitForStarted();
if (mTetherStatesParcel == null) return TETHER_ERROR_NO_ERROR;
int i = 0;
@@ -334,12 +406,11 @@
* USB network interfaces. If USB tethering is not supported by the
* device, this list should be empty.
*
- * {@hide}
+ * @return an array of 0 or more regular expression Strings defining
+ * what interfaces are considered tetherable usb interfaces.
*/
public @NonNull String[] getTetherableUsbRegexs() {
- if (!mCallback.awaitCallbackCreation()) {
- throw new NullPointerException("callback was not ready yet");
- }
+ mCallback.waitForStarted();
return mTetheringConfiguration.tetherableUsbRegexs;
}
@@ -348,12 +419,11 @@
* Wifi network interfaces. If Wifi tethering is not supported by the
* device, this list should be empty.
*
- * {@hide}
+ * @return an array of 0 or more regular expression Strings defining
+ * what interfaces are considered tetherable wifi interfaces.
*/
public @NonNull String[] getTetherableWifiRegexs() {
- if (!mCallback.awaitCallbackCreation()) {
- throw new NullPointerException("callback was not ready yet");
- }
+ mCallback.waitForStarted();
return mTetheringConfiguration.tetherableWifiRegexs;
}
@@ -362,12 +432,11 @@
* Bluetooth network interfaces. If Bluetooth tethering is not supported by the
* device, this list should be empty.
*
- * {@hide}
+ * @return an array of 0 or more regular expression Strings defining
+ * what interfaces are considered tetherable bluetooth interfaces.
*/
public @NonNull String[] getTetherableBluetoothRegexs() {
- if (!mCallback.awaitCallbackCreation()) {
- throw new NullPointerException("callback was not ready yet");
- }
+ mCallback.waitForStarted();
return mTetheringConfiguration.tetherableBluetoothRegexs;
}
@@ -375,40 +444,42 @@
* Get the set of tetherable, available interfaces. This list is limited by
* device configuration and current interface existence.
*
- * {@hide}
+ * @return an array of 0 or more Strings of tetherable interface names.
*/
public @NonNull String[] getTetherableIfaces() {
- if (!mCallback.awaitCallbackCreation()) {
- throw new NullPointerException("callback was not ready yet");
- }
+ mCallback.waitForStarted();
if (mTetherStatesParcel == null) return new String[0];
+
return mTetherStatesParcel.availableList;
}
/**
* Get the set of tethered interfaces.
*
- * {@hide}
+ * @return an array of 0 or more String of currently tethered interface names.
*/
public @NonNull String[] getTetheredIfaces() {
- if (!mCallback.awaitCallbackCreation()) {
- throw new NullPointerException("callback was not ready yet");
- }
+ mCallback.waitForStarted();
if (mTetherStatesParcel == null) return new String[0];
+
return mTetherStatesParcel.tetheredList;
}
/**
* Get the set of interface names which attempted to tether but
- * failed.
+ * failed. Re-attempting to tether may cause them to reset to the Tethered
+ * state. Alternatively, causing the interface to be destroyed and recreated
+ * may cause them to reset to the available state.
+ * {@link ConnectivityManager#getLastTetherError} can be used to get more
+ * information on the cause of the errors.
*
- * {@hide}
+ * @return an array of 0 or more String indicating the interface names
+ * which failed to tether.
*/
public @NonNull String[] getTetheringErroredIfaces() {
- if (!mCallback.awaitCallbackCreation()) {
- throw new NullPointerException("callback was not ready yet");
- }
+ mCallback.waitForStarted();
if (mTetherStatesParcel == null) return new String[0];
+
return mTetherStatesParcel.erroredIfaceList;
}
@@ -416,123 +487,49 @@
* Get the set of tethered dhcp ranges.
*
* @deprecated This API just return the default value which is not used in DhcpServer.
- * {@hide}
*/
@Deprecated
public @NonNull String[] getTetheredDhcpRanges() {
- if (!mCallback.awaitCallbackCreation()) {
- throw new NullPointerException("callback was not ready yet");
- }
+ mCallback.waitForStarted();
return mTetheringConfiguration.legacyDhcpRanges;
}
/**
- * Check if the device allows for tethering.
+ * Check if the device allows for tethering. It may be disabled via
+ * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
+ * due to device configuration.
*
- * {@hide}
+ * @return a boolean - {@code true} indicating Tethering is supported.
*/
- public boolean hasTetherableConfiguration() {
- if (!mCallback.awaitCallbackCreation()) {
- throw new NullPointerException("callback was not ready yet");
- }
- final boolean hasDownstreamConfiguration =
- (mTetheringConfiguration.tetherableUsbRegexs.length != 0)
- || (mTetheringConfiguration.tetherableWifiRegexs.length != 0)
- || (mTetheringConfiguration.tetherableBluetoothRegexs.length != 0);
- final boolean hasUpstreamConfiguration =
- (mTetheringConfiguration.preferredUpstreamIfaceTypes.length != 0)
- || mTetheringConfiguration.chooseUpstreamAutomatically;
+ public boolean isTetheringSupported() {
+ final String callerPkg = mContext.getOpPackageName();
- return hasDownstreamConfiguration && hasUpstreamConfiguration;
+ final RequestDispatcher dispatcher = new RequestDispatcher();
+ final int ret = dispatcher.waitForResult(listener -> {
+ try {
+ mConnector.isTetheringSupported(callerPkg, listener);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ });
+
+ return ret == TETHER_ERROR_NO_ERROR;
}
/**
- * Log a message in the local log.
+ * Stop all active tethering.
*/
- private void log(@NonNull String message) {
- synchronized (mLog) {
- mLog.log(message);
- }
- }
+ public void stopAllTethering() {
+ final String callerPkg = mContext.getOpPackageName();
+ Log.i(TAG, "stopAllTethering caller:" + callerPkg);
- /**
- * Log a condition that should never happen.
- */
- private void logWtf(@NonNull String message, @Nullable Throwable e) {
- Slog.wtf(TAG, message);
- synchronized (mLog) {
- mLog.e(message, e);
- }
- }
-
- /**
- * Log a ERROR level message in the local and system logs.
- */
- private void loge(@NonNull String message, @Nullable Throwable e) {
- synchronized (mLog) {
- mLog.e(message, e);
- }
- }
-
- /**
- * Log a INFO level message in the local and system logs.
- */
- private void logi(@NonNull String message) {
- synchronized (mLog) {
- mLog.i(message);
- }
- }
-
- /**
- * Dump TetheringManager logs to the specified {@link PrintWriter}.
- */
- public void dump(@NonNull PrintWriter pw) {
- // dump is thread-safe on SharedLog
- mLog.dump(null, pw, null);
-
- pw.print("subId: ");
- pw.println(mTetheringConfiguration.subId);
-
- dumpStringArray(pw, "tetherableUsbRegexs",
- mTetheringConfiguration.tetherableUsbRegexs);
- dumpStringArray(pw, "tetherableWifiRegexs",
- mTetheringConfiguration.tetherableWifiRegexs);
- dumpStringArray(pw, "tetherableBluetoothRegexs",
- mTetheringConfiguration.tetherableBluetoothRegexs);
-
- pw.print("isDunRequired: ");
- pw.println(mTetheringConfiguration.isDunRequired);
-
- pw.print("chooseUpstreamAutomatically: ");
- pw.println(mTetheringConfiguration.chooseUpstreamAutomatically);
-
- dumpStringArray(pw, "legacyDhcpRanges", mTetheringConfiguration.legacyDhcpRanges);
- dumpStringArray(pw, "defaultIPv4DNS", mTetheringConfiguration.defaultIPv4DNS);
-
- dumpStringArray(pw, "provisioningApp", mTetheringConfiguration.provisioningApp);
- pw.print("provisioningAppNoUi: ");
- pw.println(mTetheringConfiguration.provisioningAppNoUi);
-
- pw.print("enableLegacyDhcpServer: ");
- pw.println(mTetheringConfiguration.enableLegacyDhcpServer);
-
- pw.println();
- }
-
- private static void dumpStringArray(@NonNull PrintWriter pw, @NonNull String label,
- @Nullable String[] values) {
- pw.print(label);
- pw.print(": ");
-
- if (values != null) {
- final StringJoiner sj = new StringJoiner(", ", "[", "]");
- for (String value : values) sj.add(value);
-
- pw.print(sj.toString());
- } else {
- pw.print("null");
- }
-
- pw.println();
+ final RequestDispatcher dispatcher = new RequestDispatcher();
+ dispatcher.waitForResult(listener -> {
+ try {
+ mConnector.stopAllTethering(callerPkg, listener);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ });
}
}
diff --git a/packages/Tethering/jarjar-rules.txt b/packages/Tethering/jarjar-rules.txt
new file mode 100644
index 0000000..dd9eab7
--- /dev/null
+++ b/packages/Tethering/jarjar-rules.txt
@@ -0,0 +1,15 @@
+# These must be kept in sync with the framework-tethering-shared-srcs filegroup.
+# If there are files in that filegroup that do not appear here, the classes in the
+# module will be overwritten by the ones in the framework.
+# Don't jar-jar the entire package because tethering still use some internal classes
+# (like TrafficStatsConstants in com.android.internal.util)
+# TODO: simply these when tethering is built as system_current.
+rule com.android.internal.util.BitUtils* com.android.networkstack.tethering.util.BitUtils@1
+rule com.android.internal.util.IndentingPrintWriter.java* com.android.networkstack.tethering.util.IndentingPrintWriter.java@1
+rule com.android.internal.util.IState.java* com.android.networkstack.tethering.util.IState.java@1
+rule com.android.internal.util.MessageUtils* com.android.networkstack.tethering.util.MessageUtils@1
+rule com.android.internal.util.Preconditions* com.android.networkstack.tethering.util.Preconditions@1
+rule com.android.internal.util.State* com.android.networkstack.tethering.util.State@1
+rule com.android.internal.util.StateMachine* com.android.networkstack.tethering.util.StateMachine@1
+
+rule android.net.LocalLog* com.android.networkstack.tethering.LocalLog@1
diff --git a/packages/Tethering/proguard.flags b/packages/Tethering/proguard.flags
index 77fc024..1f83a66 100644
--- a/packages/Tethering/proguard.flags
+++ b/packages/Tethering/proguard.flags
@@ -1 +1,9 @@
-#TBD
+# Keep class's integer static field for MessageUtils to parsing their name.
+-keep class com.android.server.connectivity.tethering.Tethering$TetherMasterSM {
+ static final int CMD_*;
+ static final int EVENT_*;
+}
+
+-keepclassmembers class android.net.ip.IpServer {
+ static final int CMD_*;
+}
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index ff3d7bc..8fde520 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -30,7 +30,6 @@
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
-import android.net.NetworkStackClient;
import android.net.RouteInfo;
import android.net.dhcp.DhcpServerCallbacks;
import android.net.dhcp.DhcpServingParamsParcel;
@@ -122,7 +121,7 @@
* @param state one of STATE_*
* @param lastError one of ConnectivityManager.TETHER_ERROR_*
*/
- public void updateInterfaceState(IpServer who, int state, int lastError) {}
+ public void updateInterfaceState(IpServer who, int state, int lastError) { }
/**
* Notify that |who| has new LinkProperties.
@@ -130,11 +129,11 @@
* @param who the calling instance of IpServer
* @param newLp the new LinkProperties to report
*/
- public void updateLinkProperties(IpServer who, LinkProperties newLp) {}
+ public void updateLinkProperties(IpServer who, LinkProperties newLp) { }
}
/** Capture IpServer dependencies, for injection. */
- public static class Dependencies {
+ public abstract static class Dependencies {
/** Create a RouterAdvertisementDaemon instance to be used by IpServer.*/
public RouterAdvertisementDaemon getRouterAdvertisementDaemon(InterfaceParams ifParams) {
return new RouterAdvertisementDaemon(ifParams);
@@ -149,13 +148,9 @@
return NetdService.getInstance();
}
- /**
- * Create a DhcpServer instance to be used by IpServer.
- */
- public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
- DhcpServerCallbacks cb) {
- NetworkStackClient.getInstance().makeDhcpServer(ifName, params, cb);
- }
+ /** Create a DhcpServer instance to be used by IpServer. */
+ public abstract void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
+ DhcpServerCallbacks cb);
}
private static final int BASE_IFACE = Protocol.BASE_TETHERING + 100;
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
index c4b360d..a68b9b2 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
@@ -16,6 +16,7 @@
package com.android.server.connectivity.tethering;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.hardware.usb.UsbManager.USB_CONFIGURED;
import static android.hardware.usb.UsbManager.USB_CONNECTED;
import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
@@ -63,7 +64,7 @@
import android.net.INetd;
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
-import android.net.ITetherInternalCallback;
+import android.net.ITetheringEventCallback;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -89,6 +90,7 @@
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.UserHandle;
@@ -103,7 +105,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.MessageUtils;
import com.android.internal.util.Protocol;
@@ -162,6 +163,8 @@
}
private final SharedLog mLog = new SharedLog(TAG);
+ private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks =
+ new RemoteCallbackList<>();
// used to synchronize public access to members
private final Object mPublicSync;
@@ -188,8 +191,8 @@
private final NetdCallback mNetdCallback;
private final UserRestrictionActionListener mTetheringRestriction;
private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
- // All the usage of mTetherInternalCallback should run in the same thread.
- private ITetherInternalCallback mTetherInternalCallback = null;
+ // All the usage of mTetheringEventCallback should run in the same thread.
+ private ITetheringEventCallback mTetheringEventCallback = null;
private volatile TetheringConfiguration mConfig;
private InterfaceSet mCurrentUpstreamIfaceSet;
@@ -573,6 +576,11 @@
}
}
+ boolean isTetherProvisioningRequired() {
+ final TetheringConfiguration cfg = mConfig;
+ return mEntitlementMgr.isTetherProvisioningRequired(cfg);
+ }
+
// TODO: Figure out how to update for local hotspot mode interfaces.
private void sendTetherStateChangedBroadcast() {
if (!mDeps.isTetheringSupported()) return;
@@ -588,7 +596,7 @@
boolean bluetoothTethered = false;
final TetheringConfiguration cfg = mConfig;
- final TetherStatesParcel mTetherStatesParcel = new TetherStatesParcel();
+ mTetherStatesParcel = new TetherStatesParcel();
synchronized (mPublicSync) {
for (int i = 0; i < mTetherStates.size(); i++) {
@@ -1796,47 +1804,67 @@
}
/** Register tethering event callback */
- void registerTetherInternalCallback(ITetherInternalCallback callback) {
+ void registerTetheringEventCallback(ITetheringEventCallback callback) {
mHandler.post(() -> {
- mTetherInternalCallback = callback;
+ mTetheringEventCallbacks.register(callback);
try {
- mTetherInternalCallback.onCallbackCreated(mTetherUpstream,
- mConfig.toStableParcelable(), mTetherStatesParcel);
+ callback.onCallbackStarted(mTetherUpstream, mConfig.toStableParcelable(),
+ mTetherStatesParcel);
} catch (RemoteException e) {
// Not really very much to do here.
}
});
}
- private void reportUpstreamChanged(Network network) {
- // Don't need to synchronized mTetherInternalCallback because all the usage of this variable
- // should run at the same thread.
- if (mTetherInternalCallback == null) return;
+ /** Unregister tethering event callback */
+ void unregisterTetheringEventCallback(ITetheringEventCallback callback) {
+ mHandler.post(() -> {
+ mTetheringEventCallbacks.unregister(callback);
+ });
+ }
+ private void reportUpstreamChanged(Network network) {
+ final int length = mTetheringEventCallbacks.beginBroadcast();
try {
- mTetherInternalCallback.onUpstreamChanged(network);
- } catch (RemoteException e) {
- // Not really very much to do here.
+ for (int i = 0; i < length; i++) {
+ try {
+ mTetheringEventCallbacks.getBroadcastItem(i).onUpstreamChanged(network);
+ } catch (RemoteException e) {
+ // Not really very much to do here.
+ }
+ }
+ } finally {
+ mTetheringEventCallbacks.finishBroadcast();
}
}
private void reportConfigurationChanged(TetheringConfigurationParcel config) {
- if (mTetherInternalCallback == null) return;
-
+ final int length = mTetheringEventCallbacks.beginBroadcast();
try {
- mTetherInternalCallback.onConfigurationChanged(config);
- } catch (RemoteException e) {
- // Not really very much to do here.
+ for (int i = 0; i < length; i++) {
+ try {
+ mTetheringEventCallbacks.getBroadcastItem(i).onConfigurationChanged(config);
+ } catch (RemoteException e) {
+ // Not really very much to do here.
+ }
+ }
+ } finally {
+ mTetheringEventCallbacks.finishBroadcast();
}
}
private void reportTetherStateChanged(TetherStatesParcel states) {
- if (mTetherInternalCallback == null) return;
-
+ final int length = mTetheringEventCallbacks.beginBroadcast();
try {
- mTetherInternalCallback.onTetherStatesChanged(states);
- } catch (RemoteException e) {
- // Not really very much to do here.
+ for (int i = 0; i < length; i++) {
+ try {
+ mTetheringEventCallbacks.getBroadcastItem(i).onTetherStatesChanged(states);
+ } catch (RemoteException e) {
+ // Not really very much to do here.
+ }
+ }
+ } finally {
+ mTetheringEventCallbacks.finishBroadcast();
}
}
@@ -1844,7 +1872,11 @@
// Binder.java closes the resource for us.
@SuppressWarnings("resource")
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump.");
+ return;
+ }
pw.println("Tethering:");
pw.increaseIndent();
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java
index 0ba8412..b16b329 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java
@@ -39,7 +39,7 @@
*
* @hide
*/
-public class TetheringDependencies {
+public abstract class TetheringDependencies {
/**
* Get a reference to the offload hardware interface to be used by tethering.
*/
@@ -66,9 +66,7 @@
/**
* Get dependencies to be used by IpServer.
*/
- public IpServer.Dependencies getIpServerDependencies() {
- return new IpServer.Dependencies();
- }
+ public abstract IpServer.Dependencies getIpServerDependencies();
/**
* Indicates whether tethering is supported on the device.
@@ -80,9 +78,7 @@
/**
* Get the NetworkRequest that should be fulfilled by the default network.
*/
- public NetworkRequest getDefaultNetworkRequest() {
- return null;
- }
+ public abstract NetworkRequest getDefaultNetworkRequest();
/**
* Get a reference to the EntitlementManager to be used by tethering.
@@ -138,14 +134,10 @@
/**
* Get tethering thread looper.
*/
- public Looper getTetheringLooper() {
- return null;
- }
+ public abstract Looper getTetheringLooper();
/**
* Get Context of TetheringSerice.
*/
- public Context getContext() {
- return null;
- }
+ public abstract Context getContext();
}
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java
index 456f2f7..ba30845 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java
@@ -16,20 +16,36 @@
package com.android.server.connectivity.tethering;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION;
+import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
+import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
+import static android.net.TetheringManager.TETHER_ERROR_UNSUPPORTED;
+
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
-import android.net.ITetherInternalCallback;
+import android.net.IIntResultListener;
+import android.net.INetworkStackConnector;
import android.net.ITetheringConnector;
+import android.net.ITetheringEventCallback;
import android.net.NetworkRequest;
+import android.net.dhcp.DhcpServerCallbacks;
+import android.net.dhcp.DhcpServingParamsParcel;
+import android.net.ip.IpServer;
import android.net.util.SharedLog;
+import android.os.Binder;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
+import android.os.RemoteException;
import android.os.ResultReceiver;
+import android.os.ServiceManager;
import android.os.SystemProperties;
+import android.os.UserManager;
import android.provider.Settings;
+import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -52,6 +68,7 @@
private Context mContext;
private TetheringDependencies mDeps;
private Tethering mTethering;
+ private UserManager mUserManager;
@Override
public void onCreate() {
@@ -59,6 +76,7 @@
mDeps = getTetheringDependencies();
mContext = mDeps.getContext();
mTethering = makeTethering(mDeps);
+ mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
}
/**
@@ -74,7 +92,7 @@
*/
private synchronized IBinder makeConnector() {
if (mConnector == null) {
- mConnector = new TetheringConnector(mTethering);
+ mConnector = new TetheringConnector(mTethering, TetheringService.this);
}
return mConnector;
}
@@ -87,55 +105,197 @@
}
private static class TetheringConnector extends ITetheringConnector.Stub {
- private final Tethering mService;
+ private final TetheringService mService;
+ private final Tethering mTethering;
- TetheringConnector(Tethering tether) {
- mService = tether;
+ TetheringConnector(Tethering tether, TetheringService service) {
+ mTethering = tether;
+ mService = service;
}
@Override
- public void tether(String iface) {
- mService.tether(iface);
+ public void tether(String iface, String callerPkg, IIntResultListener listener) {
+ if (checkAndNotifyCommonError(callerPkg, listener)) return;
+
+ try {
+ listener.onResult(mTethering.tether(iface));
+ } catch (RemoteException e) { }
}
@Override
- public void untether(String iface) {
- mService.untether(iface);
+ public void untether(String iface, String callerPkg, IIntResultListener listener) {
+ if (checkAndNotifyCommonError(callerPkg, listener)) return;
+
+ try {
+ listener.onResult(mTethering.untether(iface));
+ } catch (RemoteException e) { }
}
@Override
- public void setUsbTethering(boolean enable) {
- mService.setUsbTethering(enable);
+ public void setUsbTethering(boolean enable, String callerPkg, IIntResultListener listener) {
+ if (checkAndNotifyCommonError(callerPkg, listener)) return;
+
+ try {
+ listener.onResult(mTethering.setUsbTethering(enable));
+ } catch (RemoteException e) { }
}
@Override
- public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
- mService.startTethering(type, receiver, showProvisioningUi);
+ public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi,
+ String callerPkg) {
+ if (checkAndNotifyCommonError(callerPkg, receiver)) return;
+
+ mTethering.startTethering(type, receiver, showProvisioningUi);
}
@Override
- public void stopTethering(int type) {
- mService.stopTethering(type);
+ public void stopTethering(int type, String callerPkg, IIntResultListener listener) {
+ if (checkAndNotifyCommonError(callerPkg, listener)) return;
+
+ try {
+ mTethering.stopTethering(type);
+ listener.onResult(TETHER_ERROR_NO_ERROR);
+ } catch (RemoteException e) { }
}
@Override
public void requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
- boolean showEntitlementUi) {
- mService.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
+ boolean showEntitlementUi, String callerPkg) {
+ if (checkAndNotifyCommonError(callerPkg, receiver)) return;
+
+ mTethering.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
}
@Override
- public void registerTetherInternalCallback(ITetherInternalCallback callback) {
- mService.registerTetherInternalCallback(callback);
+ public void registerTetheringEventCallback(ITetheringEventCallback callback,
+ String callerPkg) {
+ try {
+ if (!mService.hasTetherAccessPermission()) {
+ callback.onCallbackStopped(TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
+ return;
+ }
+ mTethering.registerTetheringEventCallback(callback);
+ } catch (RemoteException e) { }
}
+
+ @Override
+ public void unregisterTetheringEventCallback(ITetheringEventCallback callback,
+ String callerPkg) {
+ try {
+ if (!mService.hasTetherAccessPermission()) {
+ callback.onCallbackStopped(TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
+ return;
+ }
+ mTethering.unregisterTetheringEventCallback(callback);
+ } catch (RemoteException e) { }
+ }
+
+ @Override
+ public void stopAllTethering(String callerPkg, IIntResultListener listener) {
+ if (checkAndNotifyCommonError(callerPkg, listener)) return;
+
+ try {
+ mTethering.untetherAll();
+ listener.onResult(TETHER_ERROR_NO_ERROR);
+ } catch (RemoteException e) { }
+ }
+
+ @Override
+ public void isTetheringSupported(String callerPkg, IIntResultListener listener) {
+ if (checkAndNotifyCommonError(callerPkg, listener)) return;
+
+ try {
+ listener.onResult(TETHER_ERROR_NO_ERROR);
+ } catch (RemoteException e) { }
+ }
+
+ @Override
+ protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
+ @Nullable String[] args) {
+ mTethering.dump(fd, writer, args);
+ }
+
+ private boolean checkAndNotifyCommonError(String callerPkg, IIntResultListener listener) {
+ try {
+ if (!mService.hasTetherChangePermission(callerPkg)) {
+ listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+ return true;
+ }
+ if (!mService.isTetheringSupported()) {
+ listener.onResult(TETHER_ERROR_UNSUPPORTED);
+ return true;
+ }
+ } catch (RemoteException e) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean checkAndNotifyCommonError(String callerPkg, ResultReceiver receiver) {
+ if (!mService.hasTetherChangePermission(callerPkg)) {
+ receiver.send(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, null);
+ return true;
+ }
+ if (!mService.isTetheringSupported()) {
+ receiver.send(TETHER_ERROR_UNSUPPORTED, null);
+ return true;
+ }
+
+ return false;
+ }
+
}
- @Override
- protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
- @Nullable String[] args) {
- mTethering.dump(fd, writer, args);
+ // if ro.tether.denied = true we default to no tethering
+ // gservices could set the secure setting to 1 though to enable it on a build where it
+ // had previously been turned off.
+ private boolean isTetheringSupported() {
+ final int defaultVal =
+ SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1;
+ final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
+ final boolean tetherEnabledInSettings = tetherSupported
+ && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
+
+ return tetherEnabledInSettings && mTethering.hasTetherableConfiguration();
}
+ private boolean hasTetherChangePermission(String callerPkg) {
+ if (checkCallingOrSelfPermission(
+ android.Manifest.permission.TETHER_PRIVILEGED) == PERMISSION_GRANTED) {
+ return true;
+ }
+
+ if (mTethering.isTetherProvisioningRequired()) return false;
+
+
+ int uid = Binder.getCallingUid();
+ // If callerPkg's uid is not same as Binder.getCallingUid(),
+ // checkAndNoteWriteSettingsOperation will return false and the operation will be denied.
+ if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid, callerPkg,
+ false /* throwException */)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean hasTetherAccessPermission() {
+ if (checkCallingOrSelfPermission(
+ android.Manifest.permission.TETHER_PRIVILEGED) == PERMISSION_GRANTED) {
+ return true;
+ }
+
+ if (checkCallingOrSelfPermission(
+ android.Manifest.permission.ACCESS_NETWORK_STATE) == PERMISSION_GRANTED) {
+ return true;
+ }
+
+ return false;
+ }
+
+
/**
* An injection method for testing.
*/
@@ -159,20 +319,55 @@
@Override
public boolean isTetheringSupported() {
- int defaultVal =
- SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1;
- boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
- return tetherSupported;
+ return TetheringService.this.isTetheringSupported();
}
@Override
public Context getContext() {
return TetheringService.this;
}
+
+ @Override
+ public IpServer.Dependencies getIpServerDependencies() {
+ return new IpServer.Dependencies() {
+ @Override
+ public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
+ DhcpServerCallbacks cb) {
+ try {
+ final INetworkStackConnector service = getNetworkStackConnector();
+ if (service == null) return;
+
+ service.makeDhcpServer(ifName, params, cb);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+ };
+ }
+
+ // TODO: replace this by NetworkStackClient#getRemoteConnector after refactoring
+ // networkStackClient.
+ static final int NETWORKSTACK_TIMEOUT_MS = 60_000;
+ private INetworkStackConnector getNetworkStackConnector() {
+ IBinder connector;
+ try {
+ final long before = System.currentTimeMillis();
+ while ((connector = ServiceManager.getService(
+ Context.NETWORK_STACK_SERVICE)) == null) {
+ if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) {
+ Log.wtf(TAG, "Timeout, fail to get INetworkStackConnector");
+ return null;
+ }
+ Thread.sleep(200);
+ }
+ } catch (InterruptedException e) {
+ Log.wtf(TAG, "Interrupted, fail to get INetworkStackConnector");
+ return null;
+ }
+ return INetworkStackConnector.Stub.asInterface(connector);
+ }
};
}
-
return mDeps;
}
}
diff --git a/packages/Tethering/tests/unit/Android.bp b/packages/Tethering/tests/unit/Android.bp
index 5b018df..81a0548 100644
--- a/packages/Tethering/tests/unit/Android.bp
+++ b/packages/Tethering/tests/unit/Android.bp
@@ -33,10 +33,12 @@
"android.test.runner",
"android.test.base",
"android.test.mock",
+ "framework-tethering",
],
jni_libs: [
// For mockito extended
"libdexmakerjvmtiagent",
"libstaticjvmtiagent",
],
+ jarjar_rules: "jarjar-rules.txt",
}
diff --git a/packages/Tethering/tests/unit/jarjar-rules.txt b/packages/Tethering/tests/unit/jarjar-rules.txt
new file mode 100644
index 0000000..64fdebd
--- /dev/null
+++ b/packages/Tethering/tests/unit/jarjar-rules.txt
@@ -0,0 +1,11 @@
+# Don't jar-jar the entire package because this test use some
+# internal classes (like ArrayUtils in com.android.internal.util)
+rule com.android.internal.util.BitUtils* com.android.networkstack.tethering.util.BitUtils@1
+rule com.android.internal.util.IndentingPrintWriter.java* com.android.networkstack.tethering.util.IndentingPrintWriter.java@1
+rule com.android.internal.util.IState.java* com.android.networkstack.tethering.util.IState.java@1
+rule com.android.internal.util.MessageUtils* com.android.networkstack.tethering.util.MessageUtils@1
+rule com.android.internal.util.Preconditions* com.android.networkstack.tethering.util.Preconditions@1
+rule com.android.internal.util.State* com.android.networkstack.tethering.util.State@1
+rule com.android.internal.util.StateMachine* com.android.networkstack.tethering.util.StateMachine@1
+
+rule android.net.LocalLog* com.android.networkstack.tethering.LocalLog@1
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
index cdbc541..31ed823 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
@@ -72,7 +72,7 @@
import android.net.INetd;
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
-import android.net.ITetherInternalCallback;
+import android.net.ITetheringEventCallback;
import android.net.InterfaceConfiguration;
import android.net.IpPrefix;
import android.net.LinkAddress;
@@ -81,6 +81,7 @@
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
+import android.net.NetworkRequest;
import android.net.NetworkState;
import android.net.NetworkUtils;
import android.net.RouteInfo;
@@ -167,6 +168,7 @@
@Mock private IDhcpServer mDhcpServer;
@Mock private INetd mNetd;
@Mock private UserManager mUserManager;
+ @Mock private NetworkRequest mNetworkRequest;
private final MockIpServerDependencies mIpServerDependencies =
spy(new MockIpServerDependencies());
@@ -311,6 +313,11 @@
}
@Override
+ public NetworkRequest getDefaultNetworkRequest() {
+ return mNetworkRequest;
+ }
+
+ @Override
public boolean isTetheringSupported() {
mIsTetheringSupportedCalls++;
return true;
@@ -1039,7 +1046,7 @@
expectedInteractionsWithShowNotification);
}
- private class TestTetherInternalCallback extends ITetherInternalCallback.Stub {
+ private class TestTetheringEventCallback extends ITetheringEventCallback.Stub {
private final ArrayList<Network> mActualUpstreams = new ArrayList<>();
private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs =
new ArrayList<>();
@@ -1100,13 +1107,16 @@
}
@Override
- public void onCallbackCreated(Network network, TetheringConfigurationParcel config,
+ public void onCallbackStarted(Network network, TetheringConfigurationParcel config,
TetherStatesParcel states) {
mActualUpstreams.add(network);
mTetheringConfigs.add(config);
mTetherStates.add(states);
}
+ @Override
+ public void onCallbackStopped(int errorCode) { }
+
public void assertNoUpstreamChangeCallback() {
assertTrue(mActualUpstreams.isEmpty());
}
@@ -1115,10 +1125,20 @@
assertTrue(mTetheringConfigs.isEmpty());
}
+ public void assertNoStateChangeCallback() {
+ assertTrue(mTetherStates.isEmpty());
+ }
+
public void assertStateChangeCallback() {
assertFalse(mTetherStates.isEmpty());
}
+ public void assertNoCallback() {
+ assertNoUpstreamChangeCallback();
+ assertNoConfigChangeCallback();
+ assertNoStateChangeCallback();
+ }
+
private void assertTetherConfigParcelEqual(@NonNull TetheringConfigurationParcel actual,
@NonNull TetheringConfigurationParcel expect) {
assertEquals(actual.subId, expect.subId);
@@ -1139,18 +1159,19 @@
}
@Test
- public void testRegisterTetherInternalCallback() throws Exception {
- TestTetherInternalCallback callback = new TestTetherInternalCallback();
+ public void testRegisterTetheringEventCallback() throws Exception {
+ TestTetheringEventCallback callback = new TestTetheringEventCallback();
+ TestTetheringEventCallback callback2 = new TestTetheringEventCallback();
// 1. Register one callback before running any tethering.
- mTethering.registerTetherInternalCallback(callback);
+ mTethering.registerTetheringEventCallback(callback);
mLooper.dispatchAll();
callback.expectUpstreamChanged(new Network[] {null});
callback.expectConfigurationChanged(
mTethering.getTetheringConfiguration().toStableParcelable());
TetherStatesParcel tetherState = callback.pollTetherStatesChanged();
assertEquals(tetherState, null);
- // 2. Enable wifi tethering
+ // 2. Enable wifi tethering.
NetworkState upstreamState = buildMobileDualStackUpstreamState();
when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
@@ -1168,14 +1189,26 @@
assertArrayEquals(tetherState.tetheredList, new String[] {TEST_WLAN_IFNAME});
callback.expectUpstreamChanged(upstreamState.network);
- // 3. Disable wifi tethering.
+ // 3. Register second callback.
+ mTethering.registerTetheringEventCallback(callback2);
+ mLooper.dispatchAll();
+ callback2.expectUpstreamChanged(upstreamState.network);
+ callback2.expectConfigurationChanged(
+ mTethering.getTetheringConfiguration().toStableParcelable());
+ tetherState = callback2.pollTetherStatesChanged();
+ assertEquals(tetherState.tetheredList, new String[] {TEST_WLAN_IFNAME});
+
+ // 4. Unregister first callback and disable wifi tethering
+ mTethering.unregisterTetheringEventCallback(callback);
+ mLooper.dispatchAll();
mTethering.stopTethering(TETHERING_WIFI);
sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
mLooper.dispatchAll();
- tetherState = callback.pollTetherStatesChanged();
+ tetherState = callback2.pollTetherStatesChanged();
assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME});
mLooper.dispatchAll();
- callback.expectUpstreamChanged(new Network[] {null});
+ callback2.expectUpstreamChanged(new Network[] {null});
+ callback.assertNoCallback();
}
@Test
diff --git a/services/Android.bp b/services/Android.bp
index cf0c15c..501496d 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -73,6 +73,7 @@
libs: [
"android.hidl.manager-V1.0-java",
+ "framework-tethering"
],
plugins: [
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/Swipe.java b/services/accessibility/java/com/android/server/accessibility/gestures/Swipe.java
index b246c67..a285c10 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/Swipe.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/Swipe.java
@@ -26,6 +26,7 @@
import android.util.Slog;
import android.util.TypedValue;
import android.view.MotionEvent;
+import android.view.ViewConfiguration;
import java.util.ArrayList;
@@ -85,6 +86,10 @@
private static final float MIN_CM_BETWEEN_SAMPLES = 0.25f;
private final float mMinPixelsBetweenSamplesX;
private final float mMinPixelsBetweenSamplesY;
+ // The minmimum distance the finger must travel before we evaluate the initial direction of the
+ // swipe.
+ // Anything less is still considered a touch.
+ private int mTouchSlop;
// Constants for separating gesture segments
private static final float ANGLE_THRESHOLD = 0.0f;
@@ -122,6 +127,7 @@
final float pixelsPerCmY = displayMetrics.ydpi / 2.54f;
mMinPixelsBetweenSamplesX = MIN_CM_BETWEEN_SAMPLES * pixelsPerCmX;
mMinPixelsBetweenSamplesY = MIN_CM_BETWEEN_SAMPLES * pixelsPerCmY;
+ mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
clear();
}
@@ -165,7 +171,10 @@
+ Float.toString(mGestureDetectionThreshold));
}
if (getState() == STATE_CLEAR) {
- if (mStrokeBuffer.size() == 0) {
+ if (moveDelta < mTouchSlop) {
+ // This still counts as a touch not a swipe.
+ return;
+ } else if (mStrokeBuffer.size() == 0) {
// First, make sure the pointer is going in the right direction.
cancelAfterDelay(event, rawEvent, policyFlags);
int direction = toDirection(x - mBaseX, y - mBaseY);
diff --git a/services/core/Android.bp b/services/core/Android.bp
index b7adfa4..5b98f06 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -96,6 +96,7 @@
"android.hardware.tv.cec-V1.0-java",
"app-compat-annotations",
"vintf-vibrator-java",
+ "framework-tethering",
],
required: [
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index d2f1113..f363a73 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -63,6 +63,9 @@
public static final int PACKAGE_INCIDENT_REPORT_APPROVER = 10;
public static final int PACKAGE_APP_PREDICTOR = 11;
public static final int PACKAGE_TELEPHONY = 12;
+ public static final int PACKAGE_WIFI = 13;
+ public static final int PACKAGE_COMPANION = 14;
+
@IntDef(value = {
PACKAGE_SYSTEM,
PACKAGE_SETUP_WIZARD,
@@ -77,6 +80,8 @@
PACKAGE_INCIDENT_REPORT_APPROVER,
PACKAGE_APP_PREDICTOR,
PACKAGE_TELEPHONY,
+ PACKAGE_WIFI,
+ PACKAGE_COMPANION,
})
@Retention(RetentionPolicy.SOURCE)
public @interface KnownPackage {}
@@ -646,16 +651,12 @@
public abstract SparseArray<String> getAppsWithSharedUserIds();
/**
- * Get the value of attribute android:sharedUserId for the given packageName if specified,
- * otherwise {@code null}.
+ * Get all packages which share the same userId as the specified package, or an empty array
+ * if the package does not have a shared userId.
*/
- public abstract String getSharedUserIdForPackage(@NonNull String packageName);
-
- /**
- * Get all packages which specified the given sharedUserId as android:sharedUserId attribute
- * or an empty array if no package specified it.
- */
- public abstract String[] getPackagesForSharedUserId(@NonNull String sharedUserId, int userId);
+ @NonNull
+ public abstract String[] getSharedUserPackagesForPackage(@NonNull String packageName,
+ int userId);
/**
* Return if device is currently in a "core" boot environment, typically
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b719435..bb78ace 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -77,7 +77,6 @@
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
import android.net.ISocketKeepaliveCallback;
-import android.net.ITetheringEventCallback;
import android.net.InetAddresses;
import android.net.IpMemoryStore;
import android.net.IpPrefix;
@@ -278,8 +277,6 @@
private MockableSystemProperties mSystemProperties;
- private TetheringManager mTetheringManager;
-
@VisibleForTesting
protected final PermissionMonitor mPermissionMonitor;
@@ -867,13 +864,6 @@
}
/**
- * Get a reference to the TetheringManager.
- */
- public TetheringManager getTetheringManager() {
- return TetheringManager.getInstance();
- }
-
- /**
* @see ProxyTracker
*/
public ProxyTracker makeProxyTracker(@NonNull Context context,
@@ -1072,8 +1062,6 @@
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- mTetheringManager = mDeps.getTetheringManager();
-
mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
// Set up the listener for user state for creating user VPNs.
@@ -1887,14 +1875,6 @@
}
mHandler.sendMessage(mHandler.obtainMessage(
EVENT_DATA_SAVER_CHANGED, restrictBackground ? 1 : 0, 0));
-
- // TODO: relocate this specific callback in Tethering.
- if (restrictBackground) {
- log("onRestrictBackgroundChanged(true): disabling tethering");
- mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
- mTetheringManager.stopTethering(ConnectivityManager.TETHERING_USB);
- mTetheringManager.stopTethering(ConnectivityManager.TETHERING_BLUETOOTH);
- }
}
};
@@ -2024,12 +2004,6 @@
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid);
}
- private void enforceTetherAccessPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_NETWORK_STATE,
- "ConnectivityService");
- }
-
private void enforceControlAlwaysOnVpnPermission() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CONTROL_ALWAYS_ON_VPN,
@@ -2463,12 +2437,6 @@
mKeepaliveTracker.dump(pw);
pw.println();
- pw.println("TetheringManager logs:");
- pw.increaseIndent();
- TetheringManager.getInstance().dump(pw);
- pw.decreaseIndent();
-
- pw.println();
dumpAvoidBadWifiSettings(pw);
pw.println();
@@ -3993,183 +3961,55 @@
}
}
- // javadoc from interface
@Override
- public int tether(String iface, String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- if (isTetheringSupported()) {
- return mTetheringManager.tether(iface);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // javadoc from interface
- @Override
- public int untether(String iface, String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
-
- if (isTetheringSupported()) {
- return mTetheringManager.untether(iface);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // javadoc from interface
- @Override
+ @Deprecated
public int getLastTetherError(String iface) {
- enforceTetherAccessPermission();
-
- if (isTetheringSupported()) {
- return mTetheringManager.getLastTetherError(iface);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // TODO - proper iface API for selection by property, inspection, etc
- @Override
- public String[] getTetherableUsbRegexs() {
- enforceTetherAccessPermission();
- if (isTetheringSupported()) {
- return mTetheringManager.getTetherableUsbRegexs();
- } else {
- return new String[0];
- }
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+ return tm.getLastTetherError(iface);
}
@Override
- public String[] getTetherableWifiRegexs() {
- enforceTetherAccessPermission();
- if (isTetheringSupported()) {
- return mTetheringManager.getTetherableWifiRegexs();
- } else {
- return new String[0];
- }
- }
-
- @Override
- public String[] getTetherableBluetoothRegexs() {
- enforceTetherAccessPermission();
- if (isTetheringSupported()) {
- return mTetheringManager.getTetherableBluetoothRegexs();
- } else {
- return new String[0];
- }
- }
-
- @Override
- public int setUsbTethering(boolean enable, String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- if (isTetheringSupported()) {
- return mTetheringManager.setUsbTethering(enable);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // TODO - move iface listing, queries, etc to new module
- // javadoc from interface
- @Override
+ @Deprecated
public String[] getTetherableIfaces() {
- enforceTetherAccessPermission();
- return mTetheringManager.getTetherableIfaces();
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+ return tm.getTetherableIfaces();
}
@Override
+ @Deprecated
public String[] getTetheredIfaces() {
- enforceTetherAccessPermission();
- return mTetheringManager.getTetheredIfaces();
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+ return tm.getTetheredIfaces();
}
+
@Override
+ @Deprecated
public String[] getTetheringErroredIfaces() {
- enforceTetherAccessPermission();
- return mTetheringManager.getTetheringErroredIfaces();
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+
+ return tm.getTetheringErroredIfaces();
}
@Override
- public String[] getTetheredDhcpRanges() {
- enforceSettingsPermission();
- return mTetheringManager.getTetheredDhcpRanges();
+ @Deprecated
+ public String[] getTetherableUsbRegexs() {
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+
+ return tm.getTetherableUsbRegexs();
}
@Override
- public boolean isTetheringSupported(String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- return isTetheringSupported();
- }
-
- // if ro.tether.denied = true we default to no tethering
- // gservices could set the secure setting to 1 though to enable it on a build where it
- // had previously been turned off.
- private boolean isTetheringSupported() {
- int defaultVal = encodeBool(!mSystemProperties.get("ro.tether.denied").equals("true"));
- boolean tetherSupported = toBool(Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.TETHER_SUPPORTED, defaultVal));
- boolean tetherEnabledInSettings = tetherSupported
- && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
-
- // Elevate to system UID to avoid caller requiring MANAGE_USERS permission.
- boolean adminUser = false;
- final long token = Binder.clearCallingIdentity();
- try {
- adminUser = mUserManager.isAdminUser();
- } finally {
- Binder.restoreCallingIdentity(token);
- }
-
- return tetherEnabledInSettings && adminUser
- && mTetheringManager.hasTetherableConfiguration();
- }
-
- @Override
- public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi,
- String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- if (!isTetheringSupported()) {
- receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null);
- return;
- }
- mTetheringManager.startTethering(type, receiver, showProvisioningUi);
- }
-
- @Override
- public void stopTethering(int type, String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- mTetheringManager.stopTethering(type);
- }
-
- /**
- * Get the latest value of the tethering entitlement check.
- *
- * Note: Allow privileged apps who have TETHER_PRIVILEGED permission to access. If it turns
- * out some such apps are observed to abuse this API, change to per-UID limits on this API
- * if it's really needed.
- */
- @Override
- public void getLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
- boolean showEntitlementUi, String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- mTetheringManager.requestLatestTetheringEntitlementResult(
- type, receiver, showEntitlementUi);
- }
-
- /** Register tethering event callback. */
- @Override
- public void registerTetheringEventCallback(ITetheringEventCallback callback,
- String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- mTetheringManager.registerTetheringEventCallback(callback);
- }
-
- /** Unregister tethering event callback. */
- @Override
- public void unregisterTetheringEventCallback(ITetheringEventCallback callback,
- String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- mTetheringManager.unregisterTetheringEventCallback(callback);
+ @Deprecated
+ public String[] getTetherableWifiRegexs() {
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+ return tm.getTetherableWifiRegexs();
}
// Called when we lose the default network and have no replacement yet.
@@ -7050,14 +6890,6 @@
// Turn airplane mode off
setAirplaneMode(false);
- if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) {
- // Untether
- String pkgName = mContext.getOpPackageName();
- for (String tether : getTetheredIfaces()) {
- untether(tether, pkgName);
- }
- }
-
if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
// Remove always-on package
synchronized (mVpns) {
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 5bec7a3..2091c2a 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -551,16 +551,13 @@
if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
unregisterScreenOffEvent();
}
- // Only persist setting if not in car mode
- if (!mCarModeEnabled) {
- Secure.putIntForUser(getContext().getContentResolver(),
- Secure.UI_NIGHT_MODE, mode, user);
- Secure.putIntForUser(getContext().getContentResolver(),
- OVERRIDE_NIGHT_MODE, mNightModeOverride, user);
- }
mNightMode = mode;
mNightModeOverride = mode;
+ // Only persist setting if not in car mode
+ if (!mCarModeEnabled) {
+ persistNightMode(user);
+ }
// on screen off will update configuration instead
if (mNightMode != UiModeManager.MODE_NIGHT_AUTO || mCar) {
updateLocked(0, 0);
@@ -610,6 +607,7 @@
@Override
public boolean setNightModeActivated(boolean active) {
synchronized (mLock) {
+ final int user = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
try {
if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
@@ -625,6 +623,7 @@
}
updateConfigurationLocked();
applyConfigurationExternallyLocked();
+ persistNightMode(user);
return true;
} finally {
Binder.restoreCallingIdentity(ident);
@@ -834,6 +833,13 @@
}
}
+ private void persistNightMode(int user) {
+ Secure.putIntForUser(getContext().getContentResolver(),
+ Secure.UI_NIGHT_MODE, mNightMode, user);
+ Secure.putIntForUser(getContext().getContentResolver(),
+ OVERRIDE_NIGHT_MODE, mNightModeOverride, user);
+ }
+
private void updateConfigurationLocked() {
int uiMode = mDefaultUiModeType;
if (mUiModeLocked) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1852e01..6dc49b7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13051,14 +13051,31 @@
pw.println(totalPss - cachedPss);
}
}
- long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
+ long kernelUsed = memInfo.getKernelUsedSizeKb();
+ final long ionHeap = Debug.getIonHeapsSizeKb();
+ if (ionHeap > 0) {
+ final long ionMapped = Debug.getIonMappedSizeKb();
+ final long ionUnmapped = ionHeap - ionMapped;
+ final long ionPool = Debug.getIonPoolsSizeKb();
+ pw.print(" ION: ");
+ pw.print(stringifyKBSize(ionHeap + ionPool));
+ pw.print(" (");
+ pw.print(stringifyKBSize(ionMapped));
+ pw.print(" mapped + ");
+ pw.print(stringifyKBSize(ionUnmapped));
+ pw.print(" unmapped + ");
+ pw.print(stringifyKBSize(ionPool));
+ pw.println(" pools)");
+ kernelUsed += ionUnmapped;
+ }
+ final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
+ - kernelUsed - memInfo.getZramTotalSizeKb();
if (!opts.isCompact) {
pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
- + memInfo.getKernelUsedSizeKb())); pw.print(" (");
+ + kernelUsed)); pw.print(" (");
pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
- pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
+ pw.print(stringifyKBSize(kernelUsed)); pw.print(" kernel)\n");
pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
} else {
pw.print("lostram,"); pw.println(lostRAM);
@@ -13824,14 +13841,25 @@
memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
+ memInfo.getFreeSizeKb()));
memInfoBuilder.append("\n");
+ long kernelUsed = memInfo.getKernelUsedSizeKb();
+ final long ionHeap = Debug.getIonHeapsSizeKb();
+ if (ionHeap > 0) {
+ final long ionMapped = Debug.getIonMappedSizeKb();
+ final long ionUnmapped = ionHeap - ionMapped;
+ final long ionPool = Debug.getIonPoolsSizeKb();
+ memInfoBuilder.append(" ION: ");
+ memInfoBuilder.append(stringifyKBSize(ionHeap + ionPool));
+ memInfoBuilder.append("\n");
+ kernelUsed += ionUnmapped;
+ }
memInfoBuilder.append(" Used RAM: ");
memInfoBuilder.append(stringifyKBSize(
- totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
+ totalPss - cachedPss + kernelUsed));
memInfoBuilder.append("\n");
memInfoBuilder.append(" Lost RAM: ");
memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
- (totalPss - totalSwapPss) - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
+ - kernelUsed - memInfo.getZramTotalSizeKb()));
memInfoBuilder.append("\n");
Slog.i(TAG, "Low on memory:");
Slog.i(TAG, shortNativeBuilder.toString());
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 557def4..772f9b3 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1918,9 +1918,8 @@
// Get all packages belongs to the same shared uid. sharedPackages is empty array
// if it doesn't have shared uid.
final PackageManagerInternal pmInt = mService.getPackageManagerInternalLocked();
- final String sharedUserId = pmInt.getSharedUserIdForPackage(app.info.packageName);
- final String[] sharedPackages = pmInt.getPackagesForSharedUserId(sharedUserId,
- app.userId);
+ final String[] sharedPackages = pmInt.getSharedUserPackagesForPackage(
+ app.info.packageName, app.userId);
pkgDataInfoMap = getPackageAppDataInfoMap(pmInt, sharedPackages.length == 0
? new String[]{app.info.packageName} : sharedPackages, uid);
} else {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 728291d..f9730a9 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -407,6 +407,7 @@
*/
private boolean finishUserUnlocking(final UserState uss) {
final int userId = uss.mHandle.getIdentifier();
+ Slog.d(TAG, "UserController event: finishUserUnlocking(" + userId + ")");
// Only keep marching forward if user is actually unlocked
if (!StorageManager.isUserKeyUnlocked(userId)) return false;
synchronized (mLock) {
@@ -451,6 +452,7 @@
*/
void finishUserUnlocked(final UserState uss) {
final int userId = uss.mHandle.getIdentifier();
+ Slog.d(TAG, "UserController event: finishUserUnlocked(" + userId + ")");
// Only keep marching forward if user is actually unlocked
if (!StorageManager.isUserKeyUnlocked(userId)) return;
synchronized (mLock) {
@@ -521,6 +523,7 @@
private void finishUserUnlockedCompleted(UserState uss) {
final int userId = uss.mHandle.getIdentifier();
+ Slog.d(TAG, "UserController event: finishUserUnlockedCompleted(" + userId + ")");
synchronized (mLock) {
// Bail if we ended up with a stale user
if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
@@ -730,6 +733,7 @@
}
void finishUserStopping(final int userId, final UserState uss) {
+ Slog.d(TAG, "UserController event: finishUserStopping(" + userId + ")");
// On to the next.
final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
// This is the result receiver for the final shutdown broadcast.
@@ -769,6 +773,7 @@
void finishUserStopped(UserState uss) {
final int userId = uss.mHandle.getIdentifier();
+ Slog.d(TAG, "UserController event: finishUserStopped(" + userId + ")");
final boolean stopped;
boolean lockUser = true;
final ArrayList<IStopUserCallback> stopCallbacks;
@@ -1280,6 +1285,7 @@
boolean unlockUser(final @UserIdInt int userId, byte[] token, byte[] secret,
IProgressListener listener) {
checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "unlockUser");
+ Slog.i(TAG, "unlocking user " + userId);
final long binderToken = Binder.clearCallingIdentity();
try {
return unlockUserCleared(userId, token, secret, listener);
@@ -1364,6 +1370,7 @@
boolean switchUser(final int targetUserId) {
enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
+ Slog.i(TAG, "switching to user " + targetUserId);
int currentUserId = getCurrentUserId();
UserInfo targetUserInfo = getUserInfo(targetUserId);
if (targetUserId == currentUserId) {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 14f9654..0b74840 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -17,11 +17,12 @@
package com.android.server.appop;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
-import static android.app.AppOpsManager.MAX_PRIORITY_UID_STATE;
-import static android.app.AppOpsManager.MIN_PRIORITY_UID_STATE;
+import static android.app.AppOpsManager.NoteOpEvent;
+import static android.app.AppOpsManager.OpEventProxyInfo;
import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.AppOpsManager.OP_COARSE_LOCATION;
import static android.app.AppOpsManager.OP_FLAGS_ALL;
+import static android.app.AppOpsManager.OP_FLAG_SELF;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.OP_PLAY_AUDIO;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
@@ -33,6 +34,9 @@
import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
import static android.app.AppOpsManager.UID_STATE_TOP;
import static android.app.AppOpsManager._NUM_OP;
+import static android.app.AppOpsManager.extractFlagsFromKey;
+import static android.app.AppOpsManager.extractUidStateFromKey;
+import static android.app.AppOpsManager.makeKey;
import static android.app.AppOpsManager.modeToName;
import static android.app.AppOpsManager.opToName;
import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState;
@@ -93,7 +97,6 @@
import android.util.AtomicFile;
import android.util.KeyValueListParser;
import android.util.LongSparseArray;
-import android.util.LongSparseLongArray;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -365,8 +368,6 @@
public long pendingStateCommitTime;
public int capability;
public int pendingCapability;
- // For all features combined
- public int startNesting;
public ArrayMap<String, Ops> pkgOps;
public SparseIntArray opModes;
@@ -474,126 +475,318 @@
}
}
- private static final class FeatureOp {
+ /** A in progress startOp->finishOp event */
+ private static final class InProgressStartOpEvent implements IBinder.DeathRecipient {
+ /** Time of startOp event */
+ final long startTime;
+
+ /** Id of the client that started the event */
+ final @NonNull IBinder clientId;
+
+ /** To call when client dies */
+ final @NonNull Runnable onDeath;
+
+ /** uidstate used when calling startOp */
+ final @AppOpsManager.UidState int uidState;
+
+ /** How many times the op was started but not finished yet */
+ int numUnfinishedStarts;
+
+ private InProgressStartOpEvent(long startTime, @NonNull IBinder clientId,
+ @NonNull Runnable onDeath, int uidState) throws RemoteException {
+ this.startTime = startTime;
+ this.clientId = clientId;
+ this.onDeath = onDeath;
+ this.uidState = uidState;
+
+ clientId.linkToDeath(this, 0);
+ }
+
+ /** Clean up event */
+ public void finish() {
+ clientId.unlinkToDeath(this, 0);
+ }
+
+ @Override
+ public void binderDied() {
+ onDeath.run();
+ }
+ }
+
+ private final class FeatureOp {
public final @NonNull Op parent;
- public boolean running;
+ /**
+ * Last successful accesses (noteOp + finished startOp) for each uidState/opFlag combination
+ *
+ * <p>Key is {@link AppOpsManager#makeKey}
+ */
+ @GuardedBy("AppOpsService.this")
+ private @Nullable LongSparseArray<AppOpsManager.NoteOpEvent> mAccessEvents;
- private @Nullable LongSparseLongArray mAccessTimes;
- private @Nullable LongSparseLongArray mRejectTimes;
- private @Nullable LongSparseLongArray mDurations;
- private @Nullable LongSparseLongArray mProxyUids;
- private @Nullable LongSparseArray<String> mProxyFeatureIds;
- private @Nullable LongSparseArray<String> mProxyPackageNames;
+ /**
+ * Last rejected accesses for each uidState/opFlag combination
+ *
+ * <p>Key is {@link AppOpsManager#makeKey}
+ */
+ @GuardedBy("AppOpsService.this")
+ private @Nullable LongSparseArray<AppOpsManager.NoteOpEvent> mRejectEvents;
- public int startNesting;
- public long startRealtime;
+ /**
+ * Currently in progress startOp events
+ *
+ * <p>Key is clientId
+ */
+ @GuardedBy("AppOpsService.this")
+ private @Nullable ArrayMap<IBinder, InProgressStartOpEvent> mInProgressEvents;
FeatureOp(@NonNull Op parent) {
this.parent = parent;
}
- public void accessed(long time, int proxyUid, @Nullable String proxyPackageName,
+ /**
+ * Update state when noteOp was rejected or startOp->finishOp event finished
+ *
+ * @param proxyUid The uid of the proxy
+ * @param proxyPackageName The package name of the proxy
+ * @param proxyFeatureId the featureId in the proxies package
+ * @param uidState UID state of the app noteOp/startOp was called for
+ * @param flags OpFlags of the call
+ */
+ public void accessed(int proxyUid, @Nullable String proxyPackageName,
@Nullable String proxyFeatureId, @AppOpsManager.UidState int uidState,
@OpFlags int flags) {
- final long key = AppOpsManager.makeKey(uidState, flags);
- if (mAccessTimes == null) {
- mAccessTimes = new LongSparseLongArray();
- }
- mAccessTimes.put(key, time);
- updateProxyState(key, proxyUid, proxyPackageName, proxyFeatureId);
- if (mDurations != null) {
- mDurations.delete(key);
- }
+ accessed(System.currentTimeMillis(), -1, proxyUid, proxyPackageName,
+ proxyFeatureId, uidState, flags);
}
- public void rejected(long time, int proxyUid, @Nullable String proxyPackageName,
- @Nullable String proxyFeatureId, @AppOpsManager.UidState int uidState,
- @OpFlags int flags) {
- final long key = AppOpsManager.makeKey(uidState, flags);
- if (mRejectTimes == null) {
- mRejectTimes = new LongSparseLongArray();
- }
- mRejectTimes.put(key, time);
- updateProxyState(key, proxyUid, proxyPackageName, proxyFeatureId);
- if (mDurations != null) {
- mDurations.delete(key);
- }
- }
-
- public void started(long time, @AppOpsManager.UidState int uidState, @OpFlags int flags) {
- updateAccessTimeAndDuration(time, -1 /*duration*/, uidState, flags);
- running = true;
- }
-
- public void finished(long time, long duration, @AppOpsManager.UidState int uidState,
- @OpFlags int flags) {
- updateAccessTimeAndDuration(time, duration, uidState, flags);
- running = false;
- }
-
- public void running(long time, long duration, @AppOpsManager.UidState int uidState,
- @OpFlags int flags) {
- updateAccessTimeAndDuration(time, duration, uidState, flags);
- }
-
- public void continuing(long duration, @AppOpsManager.UidState int uidState,
- @OpFlags int flags) {
- final long key = AppOpsManager.makeKey(uidState, flags);
- if (mDurations == null) {
- mDurations = new LongSparseLongArray();
- }
- mDurations.put(key, duration);
- }
-
- private void updateAccessTimeAndDuration(long time, long duration,
+ /**
+ * Add an access that was previously collected.
+ *
+ * @param noteTime The time of the event
+ * @param duration The duration of the event
+ * @param proxyUid The uid of the proxy
+ * @param proxyPackageName The package name of the proxy
+ * @param proxyFeatureId the featureId in the proxies package
+ * @param uidState UID state of the app noteOp/startOp was called for
+ * @param flags OpFlags of the call
+ */
+ public void accessed(long noteTime, long duration, int proxyUid,
+ @Nullable String proxyPackageName, @Nullable String proxyFeatureId,
@AppOpsManager.UidState int uidState, @OpFlags int flags) {
- final long key = AppOpsManager.makeKey(uidState, flags);
- if (mAccessTimes == null) {
- mAccessTimes = new LongSparseLongArray();
+ long key = makeKey(uidState, flags);
+
+ if (mAccessEvents == null) {
+ mAccessEvents = new LongSparseArray<>(1);
}
- mAccessTimes.put(key, time);
- if (mDurations == null) {
- mDurations = new LongSparseLongArray();
+
+ OpEventProxyInfo proxyInfo = null;
+ if (proxyUid != Process.INVALID_UID) {
+ proxyInfo = new OpEventProxyInfo(proxyUid, proxyPackageName, proxyFeatureId);
}
- mDurations.put(key, duration);
+ mAccessEvents.put(key, new NoteOpEvent(noteTime, duration, proxyInfo));
}
- private void updateProxyState(long key, int proxyUid,
- @Nullable String proxyPackageName, @Nullable String featureId) {
- if (proxyUid == Process.INVALID_UID) {
+ /**
+ * Update state when noteOp/startOp was rejected.
+ *
+ * @param uidState UID state of the app noteOp is called for
+ * @param flags OpFlags of the call
+ */
+ public void rejected(@AppOpsManager.UidState int uidState, @OpFlags int flags) {
+ rejected(System.currentTimeMillis(), uidState, flags);
+ }
+
+ /**
+ * Add an rejection that was previously collected
+ *
+ * @param noteTime The time of the event
+ * @param uidState UID state of the app noteOp/startOp was called for
+ * @param flags OpFlags of the call
+ */
+ public void rejected(long noteTime, @AppOpsManager.UidState int uidState,
+ @OpFlags int flags) {
+ long key = makeKey(uidState, flags);
+
+ if (mRejectEvents == null) {
+ mRejectEvents = new LongSparseArray<>(1);
+ }
+
+ // We do not collect proxy information for rejections yet
+ mRejectEvents.put(key, new NoteOpEvent(noteTime, -1, null));
+ }
+
+ /**
+ * Update state when start was called
+ *
+ * @param clientId Id of the startOp caller
+ * @param uidState UID state of the app startOp is called for
+ */
+ public void started(@NonNull IBinder clientId, @AppOpsManager.UidState int uidState)
+ throws RemoteException {
+ if (!parent.isRunning()) {
+ scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid,
+ parent.packageName, true);
+ }
+
+ if (mInProgressEvents == null) {
+ mInProgressEvents = new ArrayMap<>(1);
+ }
+
+
+ InProgressStartOpEvent event = mInProgressEvents.get(clientId);
+ if (event == null) {
+ event = new InProgressStartOpEvent(System.currentTimeMillis(), clientId, () -> {
+ // In the case the client dies without calling finish first
+ synchronized (AppOpsService.this) {
+ if (mInProgressEvents == null) {
+ return;
+ }
+
+ InProgressStartOpEvent deadEvent = mInProgressEvents.get(clientId);
+ if (deadEvent != null) {
+ deadEvent.numUnfinishedStarts = 1;
+ }
+
+ finished(clientId);
+ }
+ }, uidState);
+ mInProgressEvents.put(clientId, event);
+ } else {
+ if (uidState != event.uidState) {
+ onUidStateChanged(uidState);
+ }
+ }
+
+ event.numUnfinishedStarts++;
+
+ // startOp events don't support proxy, hence use flags==SELF
+ mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid, parent.packageName,
+ uidState, OP_FLAG_SELF);
+ }
+
+ /**
+ * Update state when finishOp was called
+ *
+ * @param clientId Id of the finishOp caller
+ */
+ public void finished(@NonNull IBinder clientId) {
+ finished(clientId, true);
+ }
+
+ private void finished(@NonNull IBinder clientId, boolean triggerCallbackIfNeeded) {
+ if (mInProgressEvents == null) {
+ Slog.wtf(TAG, "No ops running");
return;
}
- if (mProxyUids == null) {
- mProxyUids = new LongSparseLongArray();
+ int indexOfToken = mInProgressEvents.indexOfKey(clientId);
+ if (indexOfToken < 0) {
+ Slog.wtf(TAG, "No op running for the client");
+ return;
}
- mProxyUids.put(key, proxyUid);
- if (mProxyPackageNames == null) {
- mProxyPackageNames = new LongSparseArray<>();
- }
- mProxyPackageNames.put(key, proxyPackageName);
+ InProgressStartOpEvent event = mInProgressEvents.valueAt(indexOfToken);
+ event.numUnfinishedStarts--;
+ if (event.numUnfinishedStarts == 0) {
+ event.finish();
+ mInProgressEvents.removeAt(indexOfToken);
- if (mProxyFeatureIds == null) {
- mProxyFeatureIds = new LongSparseArray<>();
+ if (mAccessEvents == null) {
+ mAccessEvents = new LongSparseArray<>(1);
+ }
+
+ // startOp events don't support proxy, hence use flags==SELF
+ NoteOpEvent finishedEvent = new NoteOpEvent(event.startTime,
+ System.currentTimeMillis() - event.startTime, null);
+ mAccessEvents.put(makeKey(event.uidState, OP_FLAG_SELF), finishedEvent);
+
+ mHistoricalRegistry.increaseOpAccessDuration(parent.op, parent.uid,
+ parent.packageName, event.uidState, AppOpsManager.OP_FLAG_SELF,
+ finishedEvent.duration);
+
+ if (mInProgressEvents.isEmpty()) {
+ mInProgressEvents = null;
+
+ // TODO moltmann: Also callback for single feature activity changes
+ if (triggerCallbackIfNeeded && !parent.isRunning()) {
+ scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid,
+ parent.packageName, false);
+ }
+ }
}
- mProxyFeatureIds.put(key, featureId);
+ }
+
+ /**
+ * Notify that the state of the uid changed
+ *
+ * @param newState The new state
+ */
+ public void onUidStateChanged(@AppOpsManager.UidState int newState) {
+ if (mInProgressEvents == null) {
+ return;
+ }
+
+ int numInProgressEvents = mInProgressEvents.size();
+ for (int i = 0; i < numInProgressEvents; i++) {
+ InProgressStartOpEvent event = mInProgressEvents.valueAt(i);
+
+ if (event.uidState != newState) {
+ try {
+ finished(event.clientId, false);
+ started(event.clientId, newState);
+ } catch (RemoteException e) {
+ if (DEBUG) Slog.e(TAG, "Cannot switch to new uidState " + newState);
+ }
+ }
+ }
+ }
+
+ public boolean isRunning() {
+ return mInProgressEvents != null;
}
boolean hasAnyTime() {
- return (mAccessTimes != null && mAccessTimes.size() > 0)
- || (mRejectTimes != null && mRejectTimes.size() > 0);
+ return (mAccessEvents != null && mAccessEvents.size() > 0)
+ || (mRejectEvents != null && mRejectEvents.size() > 0);
}
- @NonNull OpFeatureEntry.Builder createFeatureEntryBuilderLocked() {
- return new OpFeatureEntry.Builder(running, mAccessTimes, mRejectTimes, mDurations,
- mProxyUids, mProxyPackageNames, mProxyFeatureIds);
+ @NonNull OpFeatureEntry createFeatureEntryLocked() {
+ LongSparseArray<NoteOpEvent> accessEvents = null;
+ if (mAccessEvents != null) {
+ accessEvents = mAccessEvents.clone();
+ }
+
+ // Add in progress events as access events
+ if (mInProgressEvents != null) {
+ long now = System.currentTimeMillis();
+ int numInProgressEvents = mInProgressEvents.size();
+
+ if (accessEvents == null) {
+ accessEvents = new LongSparseArray<>(numInProgressEvents);
+ }
+
+ for (int i = 0; i < numInProgressEvents; i++) {
+ InProgressStartOpEvent event = mInProgressEvents.valueAt(i);
+
+ // startOp events don't support proxy
+ accessEvents.append(makeKey(event.uidState, OP_FLAG_SELF),
+ new NoteOpEvent(event.startTime, now - event.startTime, null));
+ }
+ }
+
+ LongSparseArray<NoteOpEvent> rejectEvents = null;
+ if (mRejectEvents != null) {
+ rejectEvents = mRejectEvents.clone();
+ }
+
+ return new OpFeatureEntry(parent.op, isRunning(), accessEvents, rejectEvents);
}
}
- final static class Op {
+ final class Op {
int op;
+ int uid;
final UidState uidState;
final @NonNull String packageName;
@@ -602,8 +795,9 @@
/** featureId -> FeatureOp */
final ArrayMap<String, FeatureOp> mFeatures = new ArrayMap<>(1);
- Op(UidState uidState, String packageName, int op) {
+ Op(UidState uidState, String packageName, int op, int uid) {
this.op = op;
+ this.uid = uid;
this.uidState = uidState;
this.packageName = packageName;
this.mode = AppOpsManager.opToDefaultMode(op);
@@ -641,11 +835,10 @@
@NonNull OpEntry createEntryLocked() {
final int numFeatures = mFeatures.size();
- final Pair<String, OpFeatureEntry.Builder>[] featureEntries =
- new Pair[numFeatures];
+ final ArrayMap<String, OpFeatureEntry> featureEntries = new ArrayMap<>(numFeatures);
for (int i = 0; i < numFeatures; i++) {
- featureEntries[i] = new Pair<>(mFeatures.keyAt(i),
- mFeatures.valueAt(i).createFeatureEntryBuilderLocked());
+ featureEntries.put(mFeatures.keyAt(i),
+ mFeatures.valueAt(i).createFeatureEntryLocked());
}
return new OpEntry(op, mode, featureEntries);
@@ -654,18 +847,28 @@
@NonNull OpEntry createSingleFeatureEntryLocked(@Nullable String featureId) {
final int numFeatures = mFeatures.size();
- final Pair<String, AppOpsManager.OpFeatureEntry.Builder>[] featureEntries =
- new Pair[1];
+ final ArrayMap<String, OpFeatureEntry> featureEntries = new ArrayMap<>(1);
for (int i = 0; i < numFeatures; i++) {
if (Objects.equals(mFeatures.keyAt(i), featureId)) {
- featureEntries[0] = new Pair<>(mFeatures.keyAt(i),
- mFeatures.valueAt(i).createFeatureEntryBuilderLocked());
+ featureEntries.put(mFeatures.keyAt(i),
+ mFeatures.valueAt(i).createFeatureEntryLocked());
break;
}
}
return new OpEntry(op, mode, featureEntries);
}
+
+ boolean isRunning() {
+ final int numFeatures = mFeatures.size();
+ for (int i = 0; i < numFeatures; i++) {
+ if (mFeatures.valueAt(i).isRunning()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
final SparseArray<ArraySet<ModeCallback>> mOpModeWatchers = new SparseArray<>();
@@ -815,53 +1018,6 @@
}
}
- final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<>();
-
- final class ClientState extends Binder implements DeathRecipient {
- final ArrayList<Pair<Op, String>> mStartedOps = new ArrayList<>();
- final IBinder mAppToken;
- final int mPid;
-
- ClientState(IBinder appToken) {
- mAppToken = appToken;
- mPid = Binder.getCallingPid();
- // Watch only for remote processes dying
- if (!(appToken instanceof Binder)) {
- try {
- mAppToken.linkToDeath(this, 0);
- } catch (RemoteException e) {
- /* do nothing */
- }
- }
- }
-
- @Override
- public String toString() {
- return "ClientState{" +
- "mAppToken=" + mAppToken +
- ", " + "pid=" + mPid +
- '}';
- }
-
- @Override
- public void binderDied() {
- synchronized (AppOpsService.this) {
- for (int i=mStartedOps.size()-1; i>=0; i--) {
- final Pair<Op, String> startedOp = mStartedOps.get(i);
- final Op op = startedOp.first;
- final String featureId = startedOp.second;
-
- finishOperationLocked(op, featureId, /*finishNested*/ true);
- if (op.mFeatures.get(featureId).startNesting <= 0) {
- scheduleOpActiveChangedIfNeededLocked(op.op, op.uidState.uid,
- op.packageName, false);
- }
- }
- mClients.remove(mAppToken);
- }
- }
- }
-
public AppOpsService(File storagePath, Handler handler) {
LockGuard.installLock(this, LockGuard.INDEX_APP_OPS);
mFile = new AtomicFile(storagePath, "appops");
@@ -1024,43 +1180,19 @@
mUidStates.remove(uid);
}
- // Finish ops other packages started on behalf of the package.
- final int clientCount = mClients.size();
- for (int i = 0; i < clientCount; i++) {
- final ClientState client = mClients.valueAt(i);
- if (client.mStartedOps == null) {
- continue;
- }
- final int startedOpCount = client.mStartedOps.size();
- for (int j = startedOpCount - 1; j >= 0; j--) {
- final Pair<Op, String> startedOp = client.mStartedOps.get(j);
- final Op op = startedOp.first;
- final String featureId = startedOp.second;
-
- if (uid == op.uidState.uid && packageName.equals(op.packageName)) {
- finishOperationLocked(op, featureId, /*finishNested*/ true);
- client.mStartedOps.remove(j);
- if (op.mFeatures.get(featureId).startNesting <= 0) {
- scheduleOpActiveChangedIfNeededLocked(op.op,
- uid, packageName, false);
- }
- }
- }
- }
-
if (ops != null) {
scheduleFastWriteLocked();
- final int opCount = ops.size();
- for (int opNum = 0; opNum < opCount; opNum++) {
+ final int numOps = ops.size();
+ for (int opNum = 0; opNum < numOps; opNum++) {
final Op op = ops.valueAt(opNum);
final int numFeatures = op.mFeatures.size();
for (int featureNum = 0; featureNum < numFeatures; featureNum++) {
- if (op.mFeatures.valueAt(featureNum).running) {
- scheduleOpActiveChangedIfNeededLocked(
- op.op, op.uidState.uid, op.packageName, false);
- break;
+ FeatureOp featureOp = op.mFeatures.valueAt(featureNum);
+
+ while (featureOp.mInProgressEvents != null) {
+ featureOp.mInProgressEvents.valueAt(0).onDeath.run();
}
}
}
@@ -1112,35 +1244,21 @@
}
uidState.pendingStateCommitTime = SystemClock.elapsedRealtime() + settleTime;
}
- if (uidState.startNesting != 0) {
- // There is some actively running operation... need to find it
- // and appropriately update its state.
- final long now = System.currentTimeMillis();
- final long nowElapsed = SystemClock.elapsedRealtime();
- for (int i = uidState.pkgOps.size() - 1; i >= 0; i--) {
- final Ops ops = uidState.pkgOps.valueAt(i);
- for (int j = ops.size() - 1; j >= 0; j--) {
- final Op op = ops.valueAt(j);
+
+ if (uidState.pkgOps != null) {
+ int numPkgs = uidState.pkgOps.size();
+ for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
+ Ops ops = uidState.pkgOps.valueAt(pkgNum);
+
+ int numOps = ops.size();
+ for (int opNum = 0; opNum < numOps; opNum++) {
+ Op op = ops.valueAt(opNum);
int numFeatures = op.mFeatures.size();
- for (int featureNum = 0; featureNum < numFeatures;
- featureNum++) {
- final FeatureOp featureOp = op.mFeatures.valueAt(
- featureNum);
- if (featureOp.startNesting > 0) {
- final long duration = SystemClock.elapsedRealtime()
- - featureOp.startRealtime;
- // We don't support proxy long running ops (start/stop)
- mHistoricalRegistry.increaseOpAccessDuration(op.op,
- op.uidState.uid, op.packageName, oldPendingState,
- AppOpsManager.OP_FLAG_SELF, duration);
- // Finish the op in the old state
- featureOp.finished(now, duration, oldPendingState,
- AppOpsManager.OP_FLAG_SELF);
- // Start the op in the new state
- featureOp.startRealtime = nowElapsed;
- featureOp.started(now, newState, AppOpsManager.OP_FLAG_SELF);
- }
+ for (int featureNum = 0; featureNum < numFeatures; featureNum++) {
+ FeatureOp featureOp = op.mFeatures.valueAt(featureNum);
+
+ featureOp.onUidStateChanged(newState);
}
}
}
@@ -1202,7 +1320,7 @@
resOps = new ArrayList<>();
for (int i = 0; i < opModeCount; i++) {
int code = uidState.opModes.keyAt(i);
- resOps.add(new OpEntry(code, uidState.opModes.get(code), new Pair[0]));
+ resOps.add(new OpEntry(code, uidState.opModes.get(code), Collections.emptyMap()));
}
} else {
for (int j=0; j<ops.length; j++) {
@@ -1211,7 +1329,8 @@
if (resOps == null) {
resOps = new ArrayList<>();
}
- resOps.add(new OpEntry(code, uidState.opModes.get(code), new Pair[0]));
+ resOps.add(new OpEntry(code, uidState.opModes.get(code),
+ Collections.emptyMap()));
}
}
}
@@ -1219,16 +1338,6 @@
}
private static @NonNull OpEntry getOpEntryForResult(@NonNull Op op, long elapsedNow) {
- final int numFeatures = op.mFeatures.size();
-
- for (int i = 0; i < numFeatures; i++) {
- final FeatureOp featureOp = op.mFeatures.valueAt(i);
- if (featureOp.running) {
- featureOp.continuing(elapsedNow - featureOp.startRealtime,
- op.uidState.state, AppOpsManager.OP_FLAG_SELF);
- }
- }
-
return op.createEntryLocked();
}
@@ -1962,18 +2071,6 @@
}
}
- @Override
- public IBinder getToken(IBinder clientToken) {
- synchronized (this) {
- ClientState cs = mClients.get(clientToken);
- if (cs == null) {
- cs = new ClientState(clientToken);
- mClients.put(clientToken, cs);
- }
- return cs;
- }
- }
-
public CheckOpsDelegate getAppOpsServiceDelegate() {
synchronized (this) {
return mCheckOpsDelegate;
@@ -2214,15 +2311,10 @@
return AppOpsManager.MODE_IGNORED;
}
final UidState uidState = ops.uidState;
- if (featureOp.running) {
- final OpFeatureEntry entry = getOpLocked(ops, code,
- false).createSingleFeatureEntryLocked(featureId).getFeatures().get(
- featureId);
-
- Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName
- + " code " + code + " time=" + entry.getLastAccessTime(uidState.state,
- uidState.state, flags) + " duration=" + entry.getLastDuration(
- uidState.state, uidState.state, flags));
+ if (featureOp.isRunning()) {
+ Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName + " code "
+ + code + " startTime of in progress event="
+ + featureOp.mInProgressEvents.valueAt(0).startTime);
}
final int switchCode = AppOpsManager.opToSwitch(code);
@@ -2234,8 +2326,7 @@
if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code "
+ switchCode + " (" + code + ") uid " + uid + " package "
+ packageName);
- featureOp.rejected(System.currentTimeMillis(), proxyUid, proxyPackageName,
- proxyFeatureId, uidState.state, flags);
+ featureOp.rejected(uidState.state, flags);
mHistoricalRegistry.incrementOpRejected(code, uid, packageName,
uidState.state, flags);
scheduleOpNotedIfNeededLocked(code, uid, packageName, uidMode);
@@ -2248,8 +2339,7 @@
if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + mode + " for code "
+ switchCode + " (" + code + ") uid " + uid + " package "
+ packageName);
- featureOp.rejected(System.currentTimeMillis(), proxyUid, proxyPackageName,
- proxyFeatureId, uidState.state, flags);
+ featureOp.rejected(uidState.state, flags);
mHistoricalRegistry.incrementOpRejected(code, uid, packageName,
uidState.state, flags);
scheduleOpNotedIfNeededLocked(code, uid, packageName, mode);
@@ -2258,8 +2348,7 @@
}
if (DEBUG) Slog.d(TAG, "noteOperation: allowing code " + code + " uid " + uid
+ " package " + packageName + (featureId == null ? "" : "." + featureId));
- featureOp.accessed(System.currentTimeMillis(), proxyUid, proxyPackageName,
- proxyFeatureId, uidState.state, flags);
+ featureOp.accessed(proxyUid, proxyPackageName, proxyFeatureId, uidState.state, flags);
// TODO moltmann: Add features to historical app-ops
mHistoricalRegistry.incrementOpAccessedCount(op.op, uid, packageName,
uidState.state, flags);
@@ -2496,7 +2585,7 @@
}
@Override
- public int startOperation(IBinder token, int code, int uid, String packageName,
+ public int startOperation(IBinder clientId, int code, int uid, String packageName,
String featureId, boolean startIfModeDefault) {
verifyIncomingUid(uid);
verifyIncomingOp(code);
@@ -2504,7 +2593,6 @@
if (resolvedPackageName == null) {
return AppOpsManager.MODE_IGNORED;
}
- ClientState client = (ClientState)token;
boolean isPrivileged;
try {
@@ -2539,10 +2627,7 @@
if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code "
+ switchCode + " (" + code + ") uid " + uid + " package "
+ resolvedPackageName);
- // We don't support proxy long running ops (start/stop)
- featureOp.rejected(System.currentTimeMillis(), -1 /*proxyUid*/,
- null /*proxyPackage*/, null, uidState.state,
- AppOpsManager.OP_FLAG_SELF);
+ featureOp.rejected(uidState.state, AppOpsManager.OP_FLAG_SELF);
mHistoricalRegistry.incrementOpRejected(opCode, uid, packageName,
uidState.state, AppOpsManager.OP_FLAG_SELF);
return uidMode;
@@ -2555,10 +2640,7 @@
if (DEBUG) Slog.d(TAG, "startOperation: reject #" + mode + " for code "
+ switchCode + " (" + code + ") uid " + uid + " package "
+ resolvedPackageName);
- // We don't support proxy long running ops (start/stop)
- featureOp.rejected(System.currentTimeMillis(), -1 /*proxyUid*/,
- null /*proxyPackage*/, null, uidState.state,
- AppOpsManager.OP_FLAG_SELF);
+ featureOp.rejected(uidState.state, AppOpsManager.OP_FLAG_SELF);
mHistoricalRegistry.incrementOpRejected(opCode, uid, packageName,
uidState.state, AppOpsManager.OP_FLAG_SELF);
return mode;
@@ -2566,29 +2648,19 @@
}
if (DEBUG) Slog.d(TAG, "startOperation: allowing code " + code + " uid " + uid
+ " package " + resolvedPackageName);
- if (featureOp.startNesting == 0) {
- featureOp.startRealtime = SystemClock.elapsedRealtime();
- // We don't support proxy long running ops (start/stop)
- featureOp.started(System.currentTimeMillis(), uidState.state,
- AppOpsManager.OP_FLAG_SELF);
- mHistoricalRegistry.incrementOpAccessedCount(opCode, uid, packageName,
- uidState.state, AppOpsManager.OP_FLAG_SELF);
- // TODO moltmann: call back when a feature became inactive
- if (uidState.startNesting == 0) {
- scheduleOpActiveChangedIfNeededLocked(code, uid, packageName, true);
- }
+ try {
+ featureOp.started(clientId, uidState.state);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
}
- featureOp.startNesting++;
- uidState.startNesting++;
- client.mStartedOps.add(new Pair<>(op, featureId));
}
return AppOpsManager.MODE_ALLOWED;
}
@Override
- public void finishOperation(IBinder token, int code, int uid, String packageName,
+ public void finishOperation(IBinder clientId, int code, int uid, String packageName,
String featureId) {
verifyIncomingUid(uid);
verifyIncomingOp(code);
@@ -2596,10 +2668,6 @@
if (resolvedPackageName == null) {
return;
}
- if (!(token instanceof ClientState)) {
- return;
- }
- ClientState client = (ClientState) token;
boolean isPrivileged;
try {
@@ -2619,36 +2687,13 @@
return;
}
- if (client.mStartedOps.remove(new Pair<>(op, featureId))) {
- finishOperationLocked(op, featureId, /*finishNested*/ false);
-
- // TODO moltmann: call back when a feature became inactive
- if (op.uidState.startNesting <= 0) {
- scheduleOpActiveChangedIfNeededLocked(code, uid, packageName, false);
- }
-
- return;
+ try {
+ featureOp.finished(clientId);
+ } catch (IllegalStateException e) {
+ Slog.e(TAG, "Operation not started: uid=" + uid + " pkg="
+ + packageName + " op=" + AppOpsManager.opToName(code), e);
}
}
-
- // We finish ops when packages get removed to guarantee no dangling
- // started ops. However, some part of the system may asynchronously
- // finish ops for an already gone package. Hence, finishing an op
- // for a non existing package is fine and we don't log as a wtf.
- final long identity = Binder.clearCallingIdentity();
- try {
- if (LocalServices.getService(PackageManagerInternal.class).getPackageUid(
- resolvedPackageName, 0, UserHandle.getUserId(uid)) < 0) {
- Slog.i(TAG, "Finishing op=" + AppOpsManager.opToName(code)
- + " for non-existing package=" + resolvedPackageName
- + " in uid=" + uid);
- return;
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- Slog.wtf(TAG, "Operation not started: uid=" + uid + " pkg="
- + packageName + " op=" + AppOpsManager.opToName(code));
}
private void scheduleOpActiveChangedIfNeededLocked(int code, int uid, String packageName,
@@ -2769,38 +2814,6 @@
return permInfo.getProtection() == PROTECTION_DANGEROUS;
}
- void finishOperationLocked(@NonNull Op op, @Nullable String featureId, boolean finishNested) {
- final FeatureOp featureOp = op.mFeatures.get(featureId);
- final int opCode = featureOp.parent.op;
- final int uid = featureOp.parent.uidState.uid;
- if (featureOp.startNesting <= 1 || finishNested) {
- if (featureOp.startNesting == 1 || finishNested) {
- // We don't support proxy long running ops (start/stop)
- final long duration = SystemClock.elapsedRealtime() - featureOp.startRealtime;
- featureOp.finished(System.currentTimeMillis(), duration, op.uidState.state,
- AppOpsManager.OP_FLAG_SELF);
- mHistoricalRegistry.increaseOpAccessDuration(opCode, uid, op.packageName,
- op.uidState.state, AppOpsManager.OP_FLAG_SELF, duration);
- } else {
- final OpFeatureEntry entry = op.createSingleFeatureEntryLocked(
- featureId).getFeatures().get(featureId);
- Slog.w(TAG, "Finishing op nesting under-run: uid " + uid + " pkg "
- + op.packageName + " code " + opCode + " time="
- + entry.getLastAccessTime(OP_FLAGS_ALL)
- + " duration=" + entry.getLastDuration(MAX_PRIORITY_UID_STATE,
- MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL) + " nesting="
- + featureOp.startNesting);
- }
- if (featureOp.startNesting >= 1) {
- op.uidState.startNesting -= featureOp.startNesting;
- }
- featureOp.startNesting = 0;
- } else {
- featureOp.startNesting--;
- op.uidState.startNesting--;
- }
- }
-
private void verifyIncomingUid(int uid) {
if (uid == Binder.getCallingUid()) {
return;
@@ -3064,7 +3077,7 @@
if (!edit) {
return null;
}
- op = new Op(ops.uidState, ops.packageName, code);
+ op = new Op(ops.uidState, ops.packageName, code, ops.uidState.uid);
ops.put(code, op);
}
if (edit) {
@@ -3208,7 +3221,7 @@
final Op op = ops.get(AppOpsManager.OP_RUN_IN_BACKGROUND);
if (op != null && op.mode != AppOpsManager.opToDefaultMode(op.op)) {
final Op copy = new Op(op.uidState, op.packageName,
- AppOpsManager.OP_RUN_ANY_IN_BACKGROUND);
+ AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uidState.uid);
copy.mode = op.mode;
ops.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, copy);
changed = true;
@@ -3336,25 +3349,22 @@
final FeatureOp featureOp = parent.getOrCreateFeature(parent, feature);
final long key = XmlUtils.readLongAttribute(parser, "n");
-
- final int flags = AppOpsManager.extractFlagsFromKey(key);
- final int state = AppOpsManager.extractUidStateFromKey(key);
+ final int uidState = extractUidStateFromKey(key);
+ final int opFlags = extractFlagsFromKey(key);
final long accessTime = XmlUtils.readLongAttribute(parser, "t", 0);
final long rejectTime = XmlUtils.readLongAttribute(parser, "r", 0);
- final long accessDuration = XmlUtils.readLongAttribute(parser, "d", 0);
+ final long accessDuration = XmlUtils.readLongAttribute(parser, "d", -1);
final String proxyPkg = XmlUtils.readStringAttribute(parser, "pp");
- final int proxyUid = XmlUtils.readIntAttribute(parser, "pu", 0);
+ final int proxyUid = XmlUtils.readIntAttribute(parser, "pu", Process.INVALID_UID);
final String proxyFeatureId = XmlUtils.readStringAttribute(parser, "pc");
if (accessTime > 0) {
- featureOp.accessed(accessTime, proxyUid, proxyPkg, proxyFeatureId, state, flags);
+ featureOp.accessed(accessTime, accessDuration, proxyUid, proxyPkg, proxyFeatureId,
+ uidState, opFlags);
}
if (rejectTime > 0) {
- featureOp.rejected(rejectTime, proxyUid, proxyPkg, proxyFeatureId, state, flags);
- }
- if (accessDuration > 0) {
- featureOp.running(accessTime, accessDuration, state, flags);
+ featureOp.rejected(rejectTime, uidState, opFlags);
}
}
@@ -3362,7 +3372,8 @@
@NonNull String pkgName, boolean isPrivileged) throws NumberFormatException,
XmlPullParserException, IOException {
Op op = new Op(uidState, pkgName,
- Integer.parseInt(parser.getAttributeValue(null, "n")));
+ Integer.parseInt(parser.getAttributeValue(null, "n")),
+ uidState.uid);
final int mode = XmlUtils.readIntAttribute(parser, "m",
AppOpsManager.opToDefaultMode(op.op));
@@ -3496,35 +3507,39 @@
final OpFeatureEntry feature = op.getFeatures().get(
featureId);
- final LongSparseArray keys = feature.collectKeys();
- if (keys == null || keys.size() <= 0) {
- continue;
- }
- final int keyCount = keys.size();
+ final ArraySet<Long> keys = feature.collectKeys();
+ final int keyCount = keys.size();
for (int k = 0; k < keyCount; k++) {
- final long key = keys.keyAt(k);
+ final long key = keys.valueAt(k);
final int uidState = AppOpsManager.extractUidStateFromKey(key);
final int flags = AppOpsManager.extractFlagsFromKey(key);
- final long accessTime = feature.getLastAccessTime(
- uidState, uidState, flags);
- final long rejectTime = feature.getLastRejectTime(
- uidState, uidState, flags);
- final long accessDuration = feature.getLastDuration(
- uidState, uidState, flags);
- final String proxyPkg = feature.getProxyPackageName(uidState,
- flags);
- final String proxyFeatureId = feature.getProxyFeatureId(
+ final long accessTime = feature.getLastAccessTime(uidState,
uidState, flags);
- final int proxyUid = feature.getProxyUid(uidState, flags);
+ final long rejectTime = feature.getLastRejectTime(uidState,
+ uidState, flags);
+ final long accessDuration = feature.getLastDuration(uidState,
+ uidState, flags);
+ // Proxy information for rejections is not backed up
+ final OpEventProxyInfo proxy = feature.getLastProxyInfo(
+ uidState, uidState, flags);
if (accessTime <= 0 && rejectTime <= 0 && accessDuration <= 0
- && proxyPkg == null && proxyUid < 0) {
+ && proxy == null) {
continue;
}
+ String proxyPkg = null;
+ String proxyFeatureId = null;
+ int proxyUid = Process.INVALID_UID;
+ if (proxy != null) {
+ proxyPkg = proxy.getPackageName();
+ proxyFeatureId = proxy.getFeatureId();
+ proxyUid = proxy.getUid();
+ }
+
out.startTag(null, "st");
if (featureId != null) {
out.attribute(null, "id", featureId);
@@ -3591,10 +3606,7 @@
Shell(IAppOpsService iface, AppOpsService internal) {
mInterface = iface;
mInternal = internal;
- try {
- mToken = mInterface.getToken(sBinder);
- } catch (RemoteException e) {
- }
+ mToken = AppOpsManager.getClientId();
}
@Override
@@ -3889,42 +3901,48 @@
pw.print(": ");
pw.print(AppOpsManager.modeToName(ent.getMode()));
if (shell.featureId == null) {
- if (ent.getTime() != 0) {
+ if (ent.getLastAccessTime(OP_FLAGS_ALL) != -1) {
pw.print("; time=");
- TimeUtils.formatDuration(now - ent.getTime(), pw);
+ TimeUtils.formatDuration(
+ now - ent.getLastAccessTime(OP_FLAGS_ALL), pw);
pw.print(" ago");
}
- if (ent.getRejectTime() != 0) {
+ if (ent.getLastRejectTime(OP_FLAGS_ALL) != -1) {
pw.print("; rejectTime=");
- TimeUtils.formatDuration(now - ent.getRejectTime(), pw);
+ TimeUtils.formatDuration(
+ now - ent.getLastRejectTime(OP_FLAGS_ALL), pw);
pw.print(" ago");
}
- if (ent.getDuration() == -1) {
+ if (ent.isRunning()) {
pw.print(" (running)");
- } else if (ent.getDuration() != 0) {
+ } else if (ent.getLastDuration(OP_FLAGS_ALL) != -1) {
pw.print("; duration=");
- TimeUtils.formatDuration(ent.getDuration(), pw);
+ TimeUtils.formatDuration(ent.getLastDuration(OP_FLAGS_ALL), pw);
}
} else {
final OpFeatureEntry featureEnt = ent.getFeatures().get(
shell.featureId);
if (featureEnt != null) {
- if (featureEnt.getTime() != 0) {
+ if (featureEnt.getLastAccessTime(OP_FLAGS_ALL) != -1) {
pw.print("; time=");
- TimeUtils.formatDuration(now - featureEnt.getTime(), pw);
+ TimeUtils.formatDuration(now - featureEnt.getLastAccessTime(
+ OP_FLAGS_ALL), pw);
pw.print(" ago");
}
- if (featureEnt.getRejectTime() != 0) {
+ if (featureEnt.getLastRejectTime(OP_FLAGS_ALL) != -1) {
pw.print("; rejectTime=");
- TimeUtils.formatDuration(now - featureEnt.getRejectTime(),
+ TimeUtils.formatDuration(
+ now - featureEnt.getLastRejectTime(OP_FLAGS_ALL),
pw);
pw.print(" ago");
}
- if (featureEnt.getDuration() == -1) {
+ if (featureEnt.isRunning()) {
pw.print(" (running)");
- } else if (featureEnt.getDuration() != 0) {
+ } else if (featureEnt.getLastDuration(OP_FLAGS_ALL)
+ != -1) {
pw.print("; duration=");
- TimeUtils.formatDuration(featureEnt.getDuration(), pw);
+ TimeUtils.formatDuration(
+ featureEnt.getLastDuration(OP_FLAGS_ALL), pw);
}
}
}
@@ -4095,27 +4113,28 @@
final OpFeatureEntry entry = op.createSingleFeatureEntryLocked(
featureId).getFeatures().get(featureId);
- final LongSparseArray keys = entry.collectKeys();
- if (keys == null || keys.size() <= 0) {
- return;
- }
+ final ArraySet<Long> keys = entry.collectKeys();
final int keyCount = keys.size();
for (int k = 0; k < keyCount; k++) {
- final long key = keys.keyAt(k);
+ final long key = keys.valueAt(k);
final int uidState = AppOpsManager.extractUidStateFromKey(key);
final int flags = AppOpsManager.extractFlagsFromKey(key);
- final long accessTime = entry.getLastAccessTime(
- uidState, uidState, flags);
- final long rejectTime = entry.getLastRejectTime(
- uidState, uidState, flags);
- final long accessDuration = entry.getLastDuration(
- uidState, uidState, flags);
- final String proxyPkg = entry.getProxyPackageName(uidState, flags);
- final String proxyFeatureId = entry.getProxyFeatureId(uidState, flags);
- final int proxyUid = entry.getProxyUid(uidState, flags);
+ final long accessTime = entry.getLastAccessTime(uidState, uidState, flags);
+ final long rejectTime = entry.getLastRejectTime(uidState, uidState, flags);
+ final long accessDuration = entry.getLastDuration(uidState, uidState, flags);
+ final OpEventProxyInfo proxy = entry.getLastProxyInfo(uidState, uidState, flags);
+
+ String proxyPkg = null;
+ String proxyFeatureId = null;
+ int proxyUid = Process.INVALID_UID;
+ if (proxy != null) {
+ proxyPkg = proxy.getPackageName();
+ proxyFeatureId = proxy.getFeatureId();
+ proxyUid = proxy.getUid();
+ }
if (accessTime > 0) {
pw.print(prefix);
@@ -4168,14 +4187,25 @@
}
final FeatureOp featureOp = op.mFeatures.get(featureId);
- if (featureOp.running) {
+ if (featureOp.isRunning()) {
+ long earliestStartTime = Long.MAX_VALUE;
+ long maxNumStarts = 0;
+ int numInProgressEvents = featureOp.mInProgressEvents.size();
+ for (int i = 0; i < numInProgressEvents; i++) {
+ InProgressStartOpEvent event = featureOp.mInProgressEvents.valueAt(i);
+
+ earliestStartTime = Math.min(earliestStartTime, event.startTime);
+ maxNumStarts = Math.max(maxNumStarts, event.numUnfinishedStarts);
+ }
+
pw.print(prefix + "Running start at: ");
- TimeUtils.formatDuration(nowElapsed - featureOp.startRealtime, pw);
+ TimeUtils.formatDuration(nowElapsed - earliestStartTime, pw);
pw.println();
- }
- if (featureOp.startNesting != 0) {
- pw.print(prefix + "startNesting=");
- pw.println(featureOp.startNesting);
+
+ if (maxNumStarts > 1) {
+ pw.print(prefix + "startNesting=");
+ pw.println(maxNumStarts);
+ }
}
}
@@ -4423,44 +4453,6 @@
pw.println(cb);
}
}
- if (mClients.size() > 0 && dumpMode < 0 && !dumpWatchers && !dumpHistory) {
- needSep = true;
- boolean printedHeader = false;
- for (int i=0; i<mClients.size(); i++) {
- boolean printedClient = false;
- ClientState cs = mClients.valueAt(i);
- if (cs.mStartedOps.size() > 0) {
- boolean printedStarted = false;
- for (int j=0; j<cs.mStartedOps.size(); j++) {
- final Pair<Op, String> startedOp = cs.mStartedOps.get(j);
- final Op op = startedOp.first;
- if (dumpOp >= 0 && op.op != dumpOp) {
- continue;
- }
- if (dumpPackage != null && !dumpPackage.equals(op.packageName)) {
- continue;
- }
- if (!printedHeader) {
- pw.println(" Clients:");
- printedHeader = true;
- }
- if (!printedClient) {
- pw.print(" "); pw.print(mClients.keyAt(i)); pw.println(":");
- pw.print(" "); pw.println(cs);
- printedClient = true;
- }
- if (!printedStarted) {
- pw.println(" Started ops:");
- printedStarted = true;
- }
- pw.print(" "); pw.print("uid="); pw.print(op.uidState.uid);
- pw.print(" pkg="); pw.print(op.packageName);
- pw.print(" featureId="); pw.print(startedOp.second);
- pw.print(" op="); pw.println(AppOpsManager.opToName(op.op));
- }
- }
- }
- }
if (mAudioRestrictionManager.hasActiveRestrictions() && dumpOp < 0
&& dumpPackage != null && dumpMode < 0 && !dumpWatchers && !dumpWatchers) {
needSep = mAudioRestrictionManager.dump(pw) | needSep ;
@@ -4536,10 +4528,6 @@
TimeUtils.formatDuration(uidState.pendingStateCommitTime, nowElapsed, pw);
pw.println();
}
- if (uidState.startNesting != 0) {
- pw.print(" startNesting=");
- pw.println(uidState.startNesting);
- }
if (uidState.foregroundOps != null && (dumpMode < 0
|| dumpMode == AppOpsManager.MODE_FOREGROUND)) {
pw.println(" foregroundOps:");
@@ -4813,17 +4801,18 @@
}
// TODO moltmann: Allow to check for feature op activeness
synchronized (AppOpsService.this) {
- for (int i = mClients.size() - 1; i >= 0; i--) {
- final ClientState client = mClients.valueAt(i);
- for (int j = client.mStartedOps.size() - 1; j >= 0; j--) {
- final Pair<Op, String> startedOp = client.mStartedOps.get(j);
- if (startedOp.first.op == code && startedOp.first.uidState.uid == uid) {
- return true;
- }
- }
+ Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false, false);
+ if (pkgOps == null) {
+ return false;
}
+
+ Op op = pkgOps.get(code);
+ if (op == null) {
+ return false;
+ }
+
+ return op.isRunning();
}
- return false;
}
@Override
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 352d0d5..21c4784 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -241,15 +241,17 @@
} else {
makeA2dpDeviceUnavailableNow(address, di.mDeviceCodecFormat);
}
+ } else if (state == BluetoothProfile.STATE_CONNECTED) {
+ // device is not already connected
+ if (a2dpVolume != -1) {
+ mDeviceBroker.postSetVolumeIndexOnDevice(AudioSystem.STREAM_MUSIC,
+ // convert index to internal representation in VolumeStreamState
+ a2dpVolume * 10,
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "onSetA2dpSinkConnectionState");
+ }
+ makeA2dpDeviceAvailable(address, BtHelper.getName(btDevice),
+ "onSetA2dpSinkConnectionState", a2dpCodec);
}
- if (a2dpVolume != -1) {
- mDeviceBroker.postSetVolumeIndexOnDevice(AudioSystem.STREAM_MUSIC,
- // convert index to internal representation in VolumeStreamState
- a2dpVolume * 10,
- AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "onSetA2dpSinkConnectionState");
- }
- makeA2dpDeviceAvailable(address, BtHelper.getName(btDevice),
- "onSetA2dpSinkConnectionState", a2dpCodec);
}
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 335cac8..21cecc2 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -310,7 +310,8 @@
7, // STREAM_SYSTEM_ENFORCED
15, // STREAM_DTMF
15, // STREAM_TTS
- 15 // STREAM_ACCESSIBILITY
+ 15, // STREAM_ACCESSIBILITY
+ 15 // STREAM_ASSISTANT
};
/** Minimum volume index values for audio streams */
@@ -325,7 +326,8 @@
0, // STREAM_SYSTEM_ENFORCED
0, // STREAM_DTMF
0, // STREAM_TTS
- 1 // STREAM_ACCESSIBILITY
+ 1, // STREAM_ACCESSIBILITY
+ 0 // STREAM_ASSISTANT
};
/* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings
@@ -348,7 +350,8 @@
AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED
AudioSystem.STREAM_RING, // STREAM_DTMF
AudioSystem.STREAM_MUSIC, // STREAM_TTS
- AudioSystem.STREAM_MUSIC // STREAM_ACCESSIBILITY
+ AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY
+ AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT
};
private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] {
AudioSystem.STREAM_MUSIC, // STREAM_VOICE_CALL
@@ -361,7 +364,8 @@
AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM_ENFORCED
AudioSystem.STREAM_MUSIC, // STREAM_DTMF
AudioSystem.STREAM_MUSIC, // STREAM_TTS
- AudioSystem.STREAM_MUSIC // STREAM_ACCESSIBILITY
+ AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY
+ AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT
};
private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL
@@ -374,7 +378,8 @@
AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED
AudioSystem.STREAM_RING, // STREAM_DTMF
AudioSystem.STREAM_MUSIC, // STREAM_TTS
- AudioSystem.STREAM_MUSIC // STREAM_ACCESSIBILITY
+ AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY
+ AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT
};
protected static int[] mStreamVolumeAlias;
@@ -394,6 +399,7 @@
AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_DTMF
AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_TTS
AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME, // STREAM_ACCESSIBILITY
+ AppOpsManager.OP_AUDIO_MEDIA_VOLUME // STREAM_ASSISTANT
};
private final boolean mUseFixedVolume;
@@ -1253,6 +1259,9 @@
int dtmfStreamAlias;
final int a11yStreamAlias = sIndependentA11yVolume ?
AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC;
+ final int assistantStreamAlias = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_useAssistantVolume) ?
+ AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC;
if (mIsSingleVolume) {
mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION;
@@ -1282,6 +1291,7 @@
mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
+ mStreamVolumeAlias[AudioSystem.STREAM_ASSISTANT] = assistantStreamAlias;
if (updateVolumes && mStreamStates != null) {
updateDefaultVolumes();
@@ -1808,6 +1818,17 @@
return;
}
+ // If the stream is STREAM_ASSISTANT,
+ // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission.
+ if (streamType == AudioSystem.STREAM_ASSISTANT &&
+ mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ != PackageManager.PERMISSION_GRANTED) {
+ Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+
// use stream type alias here so that streams with same alias have the same behavior,
// including with regard to silent mode control (e.g the use of STREAM_RING below and in
// checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
@@ -2244,6 +2265,14 @@
+ " MODIFY_PHONE_STATE callingPackage=" + callingPackage);
return;
}
+ if ((streamType == AudioManager.STREAM_ASSISTANT)
+ && (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ != PackageManager.PERMISSION_GRANTED)) {
+ Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without"
+ + " MODIFY_AUDIO_ROUTING callingPackage=" + callingPackage);
+ return;
+ }
sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
index/*val1*/, flags/*val2*/, callingPackage));
setStreamVolume(streamType, index, flags, callingPackage, callingPackage,
diff --git a/services/core/java/com/android/server/incremental/IncrementalManagerService.java b/services/core/java/com/android/server/incremental/IncrementalManagerService.java
index 789551b..3049522 100644
--- a/services/core/java/com/android/server/incremental/IncrementalManagerService.java
+++ b/services/core/java/com/android/server/incremental/IncrementalManagerService.java
@@ -67,13 +67,14 @@
mDataLoaderManager = mContext.getSystemService(DataLoaderManager.class);
ServiceManager.addService(BINDER_SERVICE_NAME, this);
// Starts and register IIncrementalManagerNative service
- // TODO(b/136132412): add jni implementation
+ mNativeInstance = nativeStartService();
}
+
/**
* Notifies native IIncrementalManager service that system is ready.
*/
public void systemReady() {
- // TODO(b/136132412): add jni implementation
+ nativeSystemReady(mNativeInstance);
}
/**
@@ -152,4 +153,8 @@
(new IncrementalManagerShellCommand(mContext)).exec(
this, in, out, err, args, callback, resultReceiver);
}
+
+ private static native long nativeStartService();
+
+ private static native void nativeSystemReady(long nativeInstance);
}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
index fdbb7d9..73a815a 100644
--- a/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
+++ b/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
@@ -27,6 +27,9 @@
import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS;
import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS;
import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.APP_CERTIFICATE_INDEXED;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.NOT_INDEXED;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.PACKAGE_NAME_INDEXED;
import android.content.integrity.AtomicFormula;
import android.content.integrity.CompoundFormula;
@@ -36,36 +39,16 @@
import com.android.server.integrity.model.BitOutputStream;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
/** A helper class to serialize rules from the {@link Rule} model to Binary representation. */
public class RuleBinarySerializer implements RuleSerializer {
- // Get the byte representation for a list of rules, and write them to an output stream.
- @Override
- public void serialize(
- List<Rule> rules, Optional<Integer> formatVersion, OutputStream outputStream)
- throws RuleSerializeException {
- try {
- BitOutputStream bitOutputStream = new BitOutputStream();
-
- int formatVersionValue = formatVersion.orElse(DEFAULT_FORMAT_VERSION);
- bitOutputStream.setNext(FORMAT_VERSION_BITS, formatVersionValue);
- outputStream.write(bitOutputStream.toByteArray());
-
- for (Rule rule : rules) {
- bitOutputStream.clear();
- serializeRule(rule, bitOutputStream);
- outputStream.write(bitOutputStream.toByteArray());
- }
- } catch (Exception e) {
- throw new RuleSerializeException(e.getMessage(), e);
- }
- }
-
// Get the byte representation for a list of rules.
@Override
public byte[] serialize(List<Rule> rules, Optional<Integer> formatVersion)
@@ -79,6 +62,45 @@
}
}
+ // Get the byte representation for a list of rules, and write them to an output stream.
+ @Override
+ public void serialize(
+ List<Rule> rules, Optional<Integer> formatVersion, OutputStream outputStream)
+ throws RuleSerializeException {
+ try {
+ // Determine the indexing groups and the order of the rules within each indexed group.
+ Map<Integer, List<Rule>> indexedRules =
+ RuleIndexingDetailsIdentifier.splitRulesIntoIndexBuckets(rules);
+
+ serializeRuleFileMetadata(formatVersion, outputStream);
+
+ serializeIndexedRules(indexedRules.get(PACKAGE_NAME_INDEXED), outputStream);
+ serializeIndexedRules(indexedRules.get(APP_CERTIFICATE_INDEXED), outputStream);
+ serializeIndexedRules(indexedRules.get(NOT_INDEXED), outputStream);
+ } catch (Exception e) {
+ throw new RuleSerializeException(e.getMessage(), e);
+ }
+ }
+
+ private void serializeRuleFileMetadata(
+ Optional<Integer> formatVersion, OutputStream outputStream) throws IOException {
+ int formatVersionValue = formatVersion.orElse(DEFAULT_FORMAT_VERSION);
+
+ BitOutputStream bitOutputStream = new BitOutputStream();
+ bitOutputStream.setNext(FORMAT_VERSION_BITS, formatVersionValue);
+ outputStream.write(bitOutputStream.toByteArray());
+ }
+
+ private void serializeIndexedRules(List<Rule> rules, OutputStream outputStream)
+ throws IOException {
+ BitOutputStream bitOutputStream = new BitOutputStream();
+ for (Rule rule : rules) {
+ bitOutputStream.clear();
+ serializeRule(rule, bitOutputStream);
+ outputStream.write(bitOutputStream.toByteArray());
+ }
+ }
+
private void serializeRule(Rule rule, BitOutputStream bitOutputStream) {
if (rule == null) {
throw new IllegalArgumentException("Null rule can not be serialized");
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifier.java b/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifier.java
index 7d5e836..f9c7912 100644
--- a/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifier.java
+++ b/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifier.java
@@ -62,7 +62,14 @@
// Split the rules into the appropriate indexed pattern. The Tree Maps help us to keep the
// entries sorted by their index key.
for (Rule rule : rules) {
- RuleIndexingDetails indexingDetails = getIndexingDetails(rule.getFormula());
+ RuleIndexingDetails indexingDetails;
+ try {
+ indexingDetails = getIndexingDetails(rule.getFormula());
+ } catch (Exception e) {
+ throw new IllegalArgumentException(
+ String.format("Malformed rule identified. [%s]", rule.toString()));
+ }
+
String ruleKey =
indexingDetails.getIndexType() != NOT_INDEXED
? indexingDetails.getRuleKey()
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 0acf7c8..c12395e 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -572,6 +572,7 @@
info.installFlags = params.installFlags;
info.isMultiPackage = params.isMultiPackage;
info.isStaged = params.isStaged;
+ info.rollbackDataPolicy = params.rollbackDataPolicy;
info.parentSessionId = mParentSessionId;
info.childSessionIds = mChildSessionIds.copyKeys();
if (info.childSessionIds == null) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index cb362b0..da104ee 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -96,6 +96,8 @@
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
+import static com.android.internal.util.ArrayUtils.emptyIfNull;
+import static com.android.internal.util.ArrayUtils.filter;
import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
@@ -249,7 +251,6 @@
import android.os.storage.VolumeRecord;
import android.permission.IPermissionManager;
import android.provider.DeviceConfig;
-import android.provider.MediaStore;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.security.KeyStore;
@@ -385,6 +386,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -16629,37 +16631,48 @@
+ " Activities needs verification ...");
int count = 0;
-
+ boolean handlesWebUris = false;
+ final boolean alreadyVerified;
synchronized (mLock) {
// If this is a new install and we see that we've already run verification for this
// package, we have nothing to do: it means the state was restored from backup.
- if (!replacing) {
- IntentFilterVerificationInfo ivi =
- mSettings.getIntentFilterVerificationLPr(packageName);
- if (ivi != null) {
- if (DEBUG_DOMAIN_VERIFICATION) {
- Slog.i(TAG, "Package " + packageName+ " already verified: status="
- + ivi.getStatusString());
- }
- return;
+ final IntentFilterVerificationInfo ivi =
+ mSettings.getIntentFilterVerificationLPr(packageName);
+ alreadyVerified = (ivi != null);
+ if (!replacing && alreadyVerified) {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Package " + packageName + " already verified: status="
+ + ivi.getStatusString());
}
+ return;
}
- // If any filters need to be verified, then all need to be.
+ // If any filters need to be verified, then all need to be. In addition, we need to
+ // know whether an updating app has any web navigation intent filters, to re-
+ // examine handling policy even if not re-verifying.
boolean needToVerify = false;
for (ParsedActivity a : activities) {
for (ParsedActivityIntentInfo filter : a.intents) {
+ if (filter.handlesWebUris(true)) {
+ handlesWebUris = true;
+ }
if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
if (DEBUG_DOMAIN_VERIFICATION) {
Slog.d(TAG,
"Intent filter needs verification, so processing all filters");
}
needToVerify = true;
+ // It's safe to break out here because filter.needsVerification()
+ // can only be true if filter.handlesWebUris(true) returns true, so
+ // we've already noted that.
break;
}
}
}
+ // Note whether this app publishes any web navigation handling support at all,
+ // and whether there are any web-nav filters that fit the profile for running
+ // a verification pass now.
if (needToVerify) {
final int verificationId = mIntentFilterVerificationToken++;
for (ParsedActivity a : activities) {
@@ -16677,13 +16690,23 @@
}
if (count > 0) {
+ // count > 0 means that we're running a full verification pass
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
+ " IntentFilter verification" + (count > 1 ? "s" : "")
+ " for userId:" + userId);
mIntentFilterVerifier.startVerifications(userId);
+ } else if (alreadyVerified && handlesWebUris) {
+ // App used autoVerify in the past, no longer does, but still handles web
+ // navigation starts.
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy");
+ }
+ synchronized (mLock) {
+ clearIntentFilterVerificationsLPw(packageName, userId);
+ }
} else {
if (DEBUG_DOMAIN_VERIFICATION) {
- Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
+ Slog.d(TAG, "No web filters or no prior verify policy for " + packageName);
}
}
}
@@ -19261,6 +19284,18 @@
return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName());
}
+ private @NonNull String[] dropNonSystemPackages(@NonNull String[] pkgNames) {
+ return emptyIfNull(filter(pkgNames, String[]::new, mIsSystemPackage), String.class);
+ }
+
+ private Predicate<String> mIsSystemPackage = (pkgName) -> {
+ if ("android".equals(pkgName)) {
+ return true;
+ }
+ AndroidPackage pkg = mPackages.get(pkgName);
+ return pkg != null && pkg.isSystem();
+ };
+
@Override
public String getSystemCaptionsServicePackageName() {
String flattenedSystemCaptionsServiceComponentName =
@@ -22539,7 +22574,11 @@
@Override
public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
- switch (knownPackage) {
+ return dropNonSystemPackages(getKnownPackageNamesInternal(knownPackage, userId));
+ }
+
+ private String[] getKnownPackageNamesInternal(int knownPackage, int userId) {
+ switch(knownPackage) {
case PackageManagerInternal.PACKAGE_BROWSER:
return new String[]{mPermissionManager.getDefaultBrowser(userId)};
case PackageManagerInternal.PACKAGE_INSTALLER:
@@ -22566,6 +22605,8 @@
return filterOnlySystemPackages(mAppPredictionServicePackage);
case PackageManagerInternal.PACKAGE_TELEPHONY:
return filterOnlySystemPackages(mTelephonyPackages);
+ case PackageManagerInternal.PACKAGE_COMPANION:
+ return filterOnlySystemPackages("com.android.companiondevicemanager");
default:
return ArrayUtils.emptyArray(String.class);
}
@@ -23063,16 +23104,10 @@
}
@Override
- public String getSharedUserIdForPackage(String packageName) {
+ @NonNull
+ public String[] getSharedUserPackagesForPackage(String packageName, int userId) {
synchronized (mLock) {
- return getSharedUserIdForPackageLocked(packageName);
- }
- }
-
- @Override
- public String[] getPackagesForSharedUserId(String sharedUserId, int userId) {
- synchronized (mLock) {
- return getPackagesForSharedUserIdLocked(sharedUserId, userId);
+ return getSharedUserPackagesForPackageLocked(packageName, userId);
}
}
@@ -23305,36 +23340,25 @@
}
@GuardedBy("mLock")
- private String getSharedUserIdForPackageLocked(String packageName) {
- final PackageSetting ps = mSettings.mPackages.get(packageName);
- return (ps != null && ps.isSharedUser()) ? ps.sharedUser.name : null;
- }
-
- @GuardedBy("mLock")
- private String[] getPackagesForSharedUserIdLocked(String sharedUserId, int userId) {
- try {
- final SharedUserSetting sus = mSettings.getSharedUserLPw(
- sharedUserId, 0, 0, false);
- if (sus == null) {
- return EmptyArray.STRING;
- }
- String[] res = new String[sus.packages.size()];
- final Iterator<PackageSetting> it = sus.packages.iterator();
- int i = 0;
- while (it.hasNext()) {
- PackageSetting ps = it.next();
- if (ps.getInstalled(userId)) {
- res[i++] = ps.name;
- }
- }
- res = ArrayUtils.trimToSize(res, i);
- if (res != null) {
- return res;
- }
- } catch (PackageManagerException e) {
- // Should not happen
+ @NonNull
+ private String[] getSharedUserPackagesForPackageLocked(String packageName, int userId) {
+ final PackageSetting packageSetting = mSettings.mPackages.get(packageName);
+ if (packageSetting == null || !packageSetting.isSharedUser()) {
+ return EmptyArray.STRING;
}
- return EmptyArray.STRING;
+
+ ArraySet<PackageSetting> packages = packageSetting.sharedUser.packages;
+ String[] res = new String[packages.size()];
+ final Iterator<PackageSetting> it = packages.iterator();
+ int i = 0;
+ while (it.hasNext()) {
+ PackageSetting ps = it.next();
+ if (ps.getInstalled(userId)) {
+ res[i++] = ps.name;
+ }
+ }
+ res = ArrayUtils.trimToSize(res, i);
+ return res != null ? res : EmptyArray.STRING;
}
@Override
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 6653011..9642a1a 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1249,6 +1249,7 @@
return false;
}
ps.clearDomainVerificationStatusForUser(userId);
+ ps.setIntentFilterVerificationInfo(null);
return true;
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 3515cb7..5854e32 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3977,6 +3977,10 @@
@Override
public boolean isUserNameSet(@UserIdInt int userId) {
+ if (!hasManageUsersOrPermission(android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) {
+ throw new SecurityException("You need MANAGE_USERS or GET_ACCOUNTS_PRIVILEGED "
+ + "permissions to: get whether user name is set");
+ }
synchronized (mUsersLock) {
final UserInfo userInfo = getUserInfoLU(userId);
return userInfo != null && userInfo.name != null;
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 05545cd..565a85f 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -280,6 +280,9 @@
public boolean isTelephony() {
return (protectionLevel & PermissionInfo.PROTECTION_FLAG_TELEPHONY) != 0;
}
+ public boolean isCompanion() {
+ return (protectionLevel & PermissionInfo.PROTECTION_FLAG_COMPANION) != 0;
+ }
public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) {
if (!origPackageName.equals(sourcePackageName)) {
diff --git a/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java
new file mode 100644
index 0000000..b809951
--- /dev/null
+++ b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.permission;
+
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;
+
+import android.annotation.NonNull;
+import android.app.ActivityManager;
+import android.app.AlarmManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.permission.PermissionControllerManager;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * Class that handles one-time permissions for a user
+ */
+public class OneTimePermissionUserManager {
+
+ private static final String LOG_TAG = OneTimePermissionUserManager.class.getSimpleName();
+
+ private final @NonNull Context mContext;
+ private final @NonNull ActivityManager mActivityManager;
+ private final @NonNull AlarmManager mAlarmManager;
+ private final @NonNull PermissionControllerManager mPermissionControllerManager;
+
+ private final Object mLock = new Object();
+
+ /** Maps the uid to the PackageInactivityListener */
+ @GuardedBy("mLock")
+ private final SparseArray<PackageInactivityListener> mListeners = new SparseArray<>();
+
+ OneTimePermissionUserManager(@NonNull Context context) {
+ mContext = context;
+ mActivityManager = context.getSystemService(ActivityManager.class);
+ mAlarmManager = context.getSystemService(AlarmManager.class);
+ mPermissionControllerManager = context.getSystemService(PermissionControllerManager.class);
+ }
+
+ /**
+ * Starts a one-time permission session for a given package. A one-time permission session is
+ * ended if app becomes inactive. Inactivity is defined as the package's uid importance level
+ * staying > importanceToResetTimer for timeoutMillis milliseconds. If the package's uid
+ * importance level goes <= importanceToResetTimer then the timer is reset and doesn't start
+ * until going > importanceToResetTimer.
+ * <p>
+ * When this timeoutMillis is reached if the importance level is <= importanceToKeepSessionAlive
+ * then the session is extended until either the importance goes above
+ * importanceToKeepSessionAlive which will end the session or <= importanceToResetTimer which
+ * will continue the session and reset the timer.
+ * </p>
+ * <p>
+ * Importance levels are defined in {@link android.app.ActivityManager.RunningAppProcessInfo}.
+ * </p>
+ * <p>
+ * Once the session ends PermissionControllerService#onNotifyOneTimePermissionSessionTimeout
+ * is invoked.
+ * </p>
+ * <p>
+ * Note that if there is currently an active session for a package a new one isn't created and
+ * the existing one isn't changed.
+ * </p>
+ * @param packageName The package to start a one-time permission session for
+ * @param timeoutMillis Number of milliseconds for an app to be in an inactive state
+ * @param importanceToResetTimer The least important level to uid must be to reset the timer
+ * @param importanceToKeepSessionAlive The least important level the uid must be to keep the
+ * session alive
+ *
+ * @hide
+ */
+ void startPackageOneTimeSession(@NonNull String packageName, long timeoutMillis,
+ int importanceToResetTimer, int importanceToKeepSessionAlive) {
+ int uid;
+ try {
+ uid = mContext.getPackageManager().getPackageUid(packageName, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(LOG_TAG, "Unknown package name " + packageName, e);
+ return;
+ }
+
+ synchronized (mLock) {
+ PackageInactivityListener listener = mListeners.get(uid);
+ if (listener == null) {
+ listener = new PackageInactivityListener(uid, packageName, timeoutMillis,
+ importanceToResetTimer, importanceToKeepSessionAlive);
+ mListeners.put(uid, listener);
+ }
+ }
+ }
+
+ /**
+ * Stops the one-time permission session for the package. The callback to the end of session is
+ * not invoked. If there is no one-time session for the package then nothing happens.
+ *
+ * @param packageName Package to stop the one-time permission session for
+ */
+ void stopPackageOneTimeSession(@NonNull String packageName) {
+ int uid;
+ try {
+ uid = mContext.getPackageManager().getPackageUid(packageName, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(LOG_TAG, "Unknown package name " + packageName, e);
+ return;
+ }
+
+ synchronized (mLock) {
+ PackageInactivityListener listener = mListeners.get(uid);
+ if (listener != null) {
+ mListeners.remove(uid);
+ listener.cancel();
+ }
+ }
+ }
+
+ /**
+ * A class which watches a package for inactivity and notifies the permission controller when
+ * the package becomes inactive
+ */
+ private class PackageInactivityListener implements AlarmManager.OnAlarmListener {
+
+ private static final long TIMER_INACTIVE = -1;
+
+ private final int mUid;
+ private final @NonNull String mPackageName;
+ private final long mTimeout;
+ private final int mImportanceToResetTimer;
+ private final int mImportanceToKeepSessionAlive;
+
+ private boolean mIsAlarmSet;
+ private boolean mIsFinished;
+
+ private long mTimerStart = TIMER_INACTIVE;
+
+ private final ActivityManager.OnUidImportanceListener mStartTimerListener;
+ private final ActivityManager.OnUidImportanceListener mSessionKillableListener;
+ private final ActivityManager.OnUidImportanceListener mGoneListener;
+
+ private final Object mInnerLock = new Object();
+
+ private PackageInactivityListener(int uid, @NonNull String packageName, long timeout,
+ int importanceToResetTimer, int importanceToKeepSessionAlive) {
+ mUid = uid;
+ mPackageName = packageName;
+ mTimeout = timeout;
+ mImportanceToResetTimer = importanceToResetTimer;
+ mImportanceToKeepSessionAlive = importanceToKeepSessionAlive;
+
+ mStartTimerListener =
+ (changingUid, importance) -> onImportanceChanged(changingUid, importance);
+ mSessionKillableListener =
+ (changingUid, importance) -> onImportanceChanged(changingUid, importance);
+ mGoneListener =
+ (changingUid, importance) -> onImportanceChanged(changingUid, importance);
+
+ mActivityManager.addOnUidImportanceListener(mStartTimerListener,
+ importanceToResetTimer);
+ mActivityManager.addOnUidImportanceListener(mSessionKillableListener,
+ importanceToKeepSessionAlive);
+ mActivityManager.addOnUidImportanceListener(mGoneListener, IMPORTANCE_CACHED);
+
+ onImportanceChanged(mUid, mActivityManager.getPackageImportance(packageName));
+ }
+
+ private void onImportanceChanged(int uid, int importance) {
+ if (uid != mUid) {
+ return;
+ }
+ synchronized (mInnerLock) {
+ if (importance > IMPORTANCE_CACHED) {
+ onPackageInactiveLocked();
+ return;
+ }
+ if (importance > mImportanceToResetTimer) {
+ if (mTimerStart == TIMER_INACTIVE) {
+ mTimerStart = System.currentTimeMillis();
+ }
+ } else {
+ mTimerStart = TIMER_INACTIVE;
+ }
+ if (importance > mImportanceToKeepSessionAlive) {
+ setAlarmLocked();
+ } else {
+ cancelAlarmLocked();
+ }
+ }
+ }
+
+ /**
+ * Stop watching the package for inactivity
+ */
+ private void cancel() {
+ synchronized (mInnerLock) {
+ mIsFinished = true;
+ cancelAlarmLocked();
+ mActivityManager.removeOnUidImportanceListener(mStartTimerListener);
+ mActivityManager.removeOnUidImportanceListener(mSessionKillableListener);
+ mActivityManager.removeOnUidImportanceListener(mGoneListener);
+ }
+ }
+
+ /**
+ * Set the alarm which will callback when the package is inactive
+ */
+ @GuardedBy("mInnerLock")
+ private void setAlarmLocked() {
+ if (mIsAlarmSet) {
+ return;
+ }
+
+ long revokeTime = mTimerStart + mTimeout;
+ if (revokeTime > System.currentTimeMillis()) {
+ mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, revokeTime, LOG_TAG, this,
+ mContext.getMainThreadHandler());
+ mIsAlarmSet = true;
+ } else {
+ mIsAlarmSet = true;
+ onAlarm();
+ }
+ }
+
+ /**
+ * Cancel the alarm
+ */
+ @GuardedBy("mInnerLock")
+ private void cancelAlarmLocked() {
+ if (mIsAlarmSet) {
+ mAlarmManager.cancel(this);
+ mIsAlarmSet = false;
+ }
+ }
+
+ /**
+ * Called when the package is considered inactive. This is the end of the session
+ */
+ @GuardedBy("mInnerLock")
+ private void onPackageInactiveLocked() {
+ if (mIsFinished) {
+ return;
+ }
+ mIsFinished = true;
+ cancelAlarmLocked();
+ mContext.getMainThreadHandler().post(
+ () -> mPermissionControllerManager.notifyOneTimePermissionSessionTimeout(
+ mPackageName));
+ mActivityManager.removeOnUidImportanceListener(mStartTimerListener);
+ mActivityManager.removeOnUidImportanceListener(mSessionKillableListener);
+ mActivityManager.removeOnUidImportanceListener(mGoneListener);
+ synchronized (mLock) {
+ mListeners.remove(mUid);
+ }
+ }
+
+ @Override
+ public void onAlarm() {
+ synchronized (mInnerLock) {
+ if (!mIsAlarmSet) {
+ return;
+ }
+ mIsAlarmSet = false;
+ onPackageInactiveLocked();
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 8ce1a52..605f869 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -204,6 +204,10 @@
/** Permission controller: User space permission management */
private PermissionControllerManager mPermissionControllerManager;
+ /** Map of OneTimePermissionUserManagers keyed by userId */
+ private final SparseArray<OneTimePermissionUserManager> mOneTimePermissionUserManagers =
+ new SparseArray<>();
+
/** Default permission policy to provide proper behaviour out-of-the-box */
private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
@@ -1579,15 +1583,11 @@
}
// If shared user we just reset the state to which only this app contributed.
- final String sharedUserId =
- mPackageManagerInt.getSharedUserIdForPackage(pkg.getPackageName());
- final String[] pkgNames =
- mPackageManagerInt.getPackagesForSharedUserId(sharedUserId, userId);
- if (pkgNames != null && pkgNames.length > 0) {
+ final String[] pkgNames = mPackageManagerInt.getSharedUserPackagesForPackage(
+ pkg.getPackageName(), userId);
+ if (pkgNames.length > 0) {
boolean used = false;
- final int packageCount = pkgNames.length;
- for (int j = 0; j < packageCount; j++) {
- final String sharedPkgName = pkgNames[j];
+ for (String sharedPkgName : pkgNames) {
final AndroidPackage sharedPkg =
mPackageManagerInt.getPackage(sharedPkgName);
if (sharedPkg != null && !sharedPkg.getPackageName().equals(packageName)
@@ -3009,6 +3009,53 @@
SystemConfig.getInstance().getSplitPermissions());
}
+ private OneTimePermissionUserManager getOneTimePermissionUserManager(@UserIdInt int userId) {
+ synchronized (mLock) {
+ OneTimePermissionUserManager oneTimePermissionUserManager =
+ mOneTimePermissionUserManagers.get(userId);
+ if (oneTimePermissionUserManager == null) {
+ oneTimePermissionUserManager = new OneTimePermissionUserManager(
+ mContext.createContextAsUser(UserHandle.of(userId), /*flags*/ 0));
+ mOneTimePermissionUserManagers.put(userId, oneTimePermissionUserManager);
+ }
+ return oneTimePermissionUserManager;
+ }
+ }
+
+ @Override
+ public void startOneTimePermissionSession(String packageName, @UserIdInt int userId,
+ long timeoutMillis, int importanceToResetTimer, int importanceToKeepSessionAlive) {
+ mContext.enforceCallingPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
+ "Must be able to revoke runtime permissions to register permissions as one time.");
+ mContext.enforceCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS,
+ "Must be able to access usage stats to register permissions as one time.");
+ packageName = Preconditions.checkNotNull(packageName);
+
+ long token = Binder.clearCallingIdentity();
+ try {
+ getOneTimePermissionUserManager(userId).startPackageOneTimeSession(packageName,
+ timeoutMillis, importanceToResetTimer, importanceToKeepSessionAlive);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
+ public void stopOneTimePermissionSession(String packageName, @UserIdInt int userId) {
+ mContext.enforceCallingPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
+ "Must be able to revoke runtime permissions to remove permissions as one time.");
+ mContext.enforceCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS,
+ "Must be able to access usage stats to remove permissions as one time.");
+ Preconditions.checkNotNull(packageName);
+
+ long token = Binder.clearCallingIdentity();
+ try {
+ getOneTimePermissionUserManager(userId).stopPackageOneTimeSession(packageName);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
private boolean isNewPlatformPermissionForPackage(String perm, AndroidPackage pkg) {
boolean allowed = false;
final int NP = PackageParser.NEW_PERMISSIONS.length;
@@ -3279,6 +3326,13 @@
// Special permissions for the system telephony apps.
allowed = true;
}
+ if (!allowed && bp.isCompanion()
+ && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
+ PackageManagerInternal.PACKAGE_COMPANION, UserHandle.USER_SYSTEM),
+ pkg.getPackageName())) {
+ // Special permissions for the system companion device manager.
+ allowed = true;
+ }
}
return allowed;
}
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index b1feb14..e7269a6 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -353,15 +353,14 @@
final PermissionToOpSynchroniser synchroniser = new PermissionToOpSynchroniser(
getUserContext(getContext(), UserHandle.of(userId)));
synchroniser.addPackage(pkg.packageName);
- final String[] sharedPkgNames = packageManagerInternal.getPackagesForSharedUserId(
- pkg.sharedUserId, userId);
- if (sharedPkgNames != null) {
- for (String sharedPkgName : sharedPkgNames) {
- final AndroidPackage sharedPkg = packageManagerInternal
- .getPackage(sharedPkgName);
- if (sharedPkg != null) {
- synchroniser.addPackage(sharedPkg.getPackageName());
- }
+ final String[] sharedPkgNames = packageManagerInternal.getSharedUserPackagesForPackage(
+ pkg.packageName, userId);
+
+ for (String sharedPkgName : sharedPkgNames) {
+ final AndroidPackage sharedPkg = packageManagerInternal
+ .getPackage(sharedPkgName);
+ if (sharedPkg != null) {
+ synchroniser.addPackage(sharedPkg.getPackageName());
}
}
synchroniser.syncPackages();
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index d99e03b..c50248d 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -24,7 +24,6 @@
import android.app.timedetector.PhoneTimeSuggestion;
import android.content.Intent;
import android.telephony.TelephonyManager;
-import android.util.ArrayMap;
import android.util.LocalLog;
import android.util.Slog;
import android.util.TimestampedValue;
@@ -32,12 +31,11 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.timezonedetector.ArrayMapWithHistory;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.LinkedList;
-import java.util.Map;
/**
* An implementation of TimeDetectorStrategy that passes phone and manual suggestions to
@@ -99,14 +97,12 @@
private TimestampedValue<Long> mLastAutoSystemClockTimeSet;
/**
- * A mapping from phoneId to a linked list of time suggestions (the "first" being the latest).
- * We typically expect one or two entries in this Map: devices will have a small number
- * of telephony devices and phoneIds are assumed to be stable. The LinkedList associated with
- * the ID will not exceed {@link #KEEP_SUGGESTION_HISTORY_SIZE} in size.
+ * A mapping from phoneId to a time suggestion. We typically expect one or two mappings: devices
+ * will have a small number of telephony devices and phoneIds are assumed to be stable.
*/
@GuardedBy("this")
- private ArrayMap<Integer, LinkedList<PhoneTimeSuggestion>> mSuggestionByPhoneId =
- new ArrayMap<>();
+ private ArrayMapWithHistory<Integer, PhoneTimeSuggestion> mSuggestionByPhoneId =
+ new ArrayMapWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
@Override
public void initialize(@NonNull Callback callback) {
@@ -179,16 +175,7 @@
ipw.println("Phone suggestion history:");
ipw.increaseIndent(); // level 2
- for (Map.Entry<Integer, LinkedList<PhoneTimeSuggestion>> entry
- : mSuggestionByPhoneId.entrySet()) {
- ipw.println("Phone " + entry.getKey());
-
- ipw.increaseIndent(); // level 3
- for (PhoneTimeSuggestion suggestion : entry.getValue()) {
- ipw.println(suggestion);
- }
- ipw.decreaseIndent(); // level 3
- }
+ mSuggestionByPhoneId.dump(ipw);
ipw.decreaseIndent(); // level 2
ipw.decreaseIndent(); // level 1
@@ -205,20 +192,10 @@
}
int phoneId = suggestion.getPhoneId();
- LinkedList<PhoneTimeSuggestion> phoneSuggestions = mSuggestionByPhoneId.get(phoneId);
- if (phoneSuggestions == null) {
- // The first time we've seen this phoneId.
- phoneSuggestions = new LinkedList<>();
- mSuggestionByPhoneId.put(phoneId, phoneSuggestions);
- } else if (phoneSuggestions.isEmpty()) {
- Slog.w(LOG_TAG, "Suggestions unexpectedly empty when adding suggestion=" + suggestion);
- }
-
- if (!phoneSuggestions.isEmpty()) {
+ PhoneTimeSuggestion previousSuggestion = mSuggestionByPhoneId.get(phoneId);
+ if (previousSuggestion != null) {
// We can log / discard suggestions with obvious issues with the reference time clock.
- PhoneTimeSuggestion previousSuggestion = phoneSuggestions.getFirst();
- if (previousSuggestion == null
- || previousSuggestion.getUtcTime() == null
+ if (previousSuggestion.getUtcTime() == null
|| previousSuggestion.getUtcTime().getValue() == null) {
// This should be impossible given we only store validated suggestions.
Slog.w(LOG_TAG, "Previous suggestion is null or has a null time."
@@ -240,10 +217,7 @@
}
// Store the latest suggestion.
- phoneSuggestions.addFirst(suggestion);
- if (phoneSuggestions.size() > KEEP_SUGGESTION_HISTORY_SIZE) {
- phoneSuggestions.removeLast();
- }
+ mSuggestionByPhoneId.put(phoneId, suggestion);
return true;
}
@@ -331,15 +305,7 @@
int bestScore = PHONE_INVALID_SCORE;
for (int i = 0; i < mSuggestionByPhoneId.size(); i++) {
Integer phoneId = mSuggestionByPhoneId.keyAt(i);
- LinkedList<PhoneTimeSuggestion> phoneSuggestions = mSuggestionByPhoneId.valueAt(i);
- if (phoneSuggestions == null) {
- // Unexpected - map is missing a value.
- Slog.w(LOG_TAG, "Suggestions unexpectedly missing for phoneId."
- + " phoneId=" + phoneId);
- continue;
- }
-
- PhoneTimeSuggestion candidateSuggestion = phoneSuggestions.getFirst();
+ PhoneTimeSuggestion candidateSuggestion = mSuggestionByPhoneId.valueAt(i);
if (candidateSuggestion == null) {
// Unexpected - null suggestions should never be stored.
Slog.w(LOG_TAG, "Latest suggestion unexpectedly null for phoneId."
@@ -540,10 +506,6 @@
@VisibleForTesting
@Nullable
public synchronized PhoneTimeSuggestion getLatestPhoneSuggestion(int phoneId) {
- LinkedList<PhoneTimeSuggestion> suggestions = mSuggestionByPhoneId.get(phoneId);
- if (suggestions == null) {
- return null;
- }
- return suggestions.getFirst();
+ return mSuggestionByPhoneId.get(phoneId);
}
}
diff --git a/services/core/java/com/android/server/timezonedetector/ArrayMapWithHistory.java b/services/core/java/com/android/server/timezonedetector/ArrayMapWithHistory.java
new file mode 100644
index 0000000..3274f0e
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/ArrayMapWithHistory.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2019 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.timezonedetector;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
+
+/**
+ * A partial decorator for {@link ArrayMap} that records historic values for each mapping for
+ * debugging later with {@link #dump(IndentingPrintWriter)}.
+ *
+ * <p>This class is only intended for use in {@link TimeZoneDetectorStrategy} and
+ * {@link com.android.server.timedetector.TimeDetectorStrategy} so only provides the parts of the
+ * {@link ArrayMap} API needed. If it is ever extended to include deletion methods like
+ * {@link ArrayMap#remove(Object)} some thought would need to be given to the correct
+ * {@link ArrayMap#containsKey(Object)} behavior for the history. Like {@link ArrayMap}, it is not
+ * thread-safe.
+ *
+ * @param <K> the type of the key
+ * @param <V> the type of the value
+ */
+public final class ArrayMapWithHistory<K, V> {
+ private static final String TAG = "ArrayMapWithHistory";
+
+ /** The size the linked list against each value is allowed to grow to. */
+ private final int mMaxHistorySize;
+
+ @Nullable
+ private ArrayMap<K, ReferenceWithHistory<V>> mMap;
+
+ /**
+ * Creates an instance that records, at most, the specified number of values against each key.
+ */
+ public ArrayMapWithHistory(@IntRange(from = 1) int maxHistorySize) {
+ if (maxHistorySize < 1) {
+ throw new IllegalArgumentException("maxHistorySize < 1: " + maxHistorySize);
+ }
+ mMaxHistorySize = maxHistorySize;
+ }
+
+ /**
+ * See {@link ArrayMap#put(K, V)}.
+ */
+ @Nullable
+ public V put(@Nullable K key, @Nullable V value) {
+ if (mMap == null) {
+ mMap = new ArrayMap<>();
+ }
+
+ ReferenceWithHistory<V> valueHolder = mMap.get(key);
+ if (valueHolder == null) {
+ valueHolder = new ReferenceWithHistory<>(mMaxHistorySize);
+ mMap.put(key, valueHolder);
+ } else if (valueHolder.getHistoryCount() == 0) {
+ Log.w(TAG, "History for \"" + key + "\" was unexpectedly empty");
+ }
+
+ return valueHolder.set(value);
+ }
+
+ /**
+ * See {@link ArrayMap#get(Object)}.
+ */
+ @Nullable
+ public V get(@Nullable Object key) {
+ if (mMap == null) {
+ return null;
+ }
+
+ ReferenceWithHistory<V> valueHolder = mMap.get(key);
+ if (valueHolder == null) {
+ return null;
+ } else if (valueHolder.getHistoryCount() == 0) {
+ Log.w(TAG, "History for \"" + key + "\" was unexpectedly empty");
+ }
+ return valueHolder.get();
+ }
+
+ /**
+ * See {@link ArrayMap#size()}.
+ */
+ public int size() {
+ return mMap == null ? 0 : mMap.size();
+ }
+
+ /**
+ * See {@link ArrayMap#keyAt(int)}.
+ */
+ @Nullable
+ public K keyAt(int index) {
+ if (mMap == null) {
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
+ return mMap.keyAt(index);
+ }
+
+ /**
+ * See {@link ArrayMap#valueAt(int)}.
+ */
+ @Nullable
+ public V valueAt(int index) {
+ if (mMap == null) {
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
+
+ ReferenceWithHistory<V> valueHolder = mMap.valueAt(index);
+ if (valueHolder == null || valueHolder.getHistoryCount() == 0) {
+ Log.w(TAG, "valueAt(" + index + ") was unexpectedly null or empty");
+ return null;
+ }
+ return valueHolder.get();
+ }
+
+ /**
+ * Dumps the content of the map, including historic values, using the supplied writer.
+ */
+ public void dump(@NonNull IndentingPrintWriter ipw) {
+ if (mMap == null) {
+ ipw.println("{Empty}");
+ } else {
+ for (int i = 0; i < mMap.size(); i++) {
+ ipw.println("key idx: " + i + "=" + mMap.keyAt(i));
+ ReferenceWithHistory<V> value = mMap.valueAt(i);
+ ipw.println("val idx: " + i + "=" + value);
+ ipw.increaseIndent();
+
+ ipw.println("Historic values=[");
+ ipw.increaseIndent();
+ value.dump(ipw);
+ ipw.decreaseIndent();
+ ipw.println("]");
+
+ ipw.decreaseIndent();
+ }
+ }
+ ipw.flush();
+ }
+
+ /**
+ * Internal method intended for tests that returns the number of historic values associated with
+ * the supplied key currently. If there is no mapping for the key then {@code 0} is returned.
+ */
+ @VisibleForTesting
+ public int getHistoryCountForKeyForTests(@Nullable K key) {
+ if (mMap == null) {
+ return 0;
+ }
+
+ ReferenceWithHistory<V> valueHolder = mMap.get(key);
+ if (valueHolder == null) {
+ return 0;
+ } else if (valueHolder.getHistoryCount() == 0) {
+ Log.w(TAG, "getValuesSizeForKeyForTests(\"" + key + "\") was unexpectedly empty");
+ return 0;
+ } else {
+ return valueHolder.getHistoryCount();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ArrayMapWithHistory{"
+ + "mHistorySize=" + mMaxHistorySize
+ + ", mMap=" + mMap
+ + '}';
+ }
+}
diff --git a/services/core/java/com/android/server/timezonedetector/ReferenceWithHistory.java b/services/core/java/com/android/server/timezonedetector/ReferenceWithHistory.java
new file mode 100644
index 0000000..8bd1035
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/ReferenceWithHistory.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2019 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.timezonedetector;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.util.LinkedList;
+
+/**
+ * A class that behaves like the following definition, except it stores the history of values set
+ * that can be dumped for debugging with {@link #dump(IndentingPrintWriter)}.
+ *
+ * <pre>{@code
+ * private static class Ref<V> {
+ * private V mValue;
+ *
+ * public V get() {
+ * return mValue;
+ * }
+ *
+ * public V set(V value) {
+ * V previous = mValue;
+ * mValue = value;
+ * return previous;
+ * }
+ * }
+ * }</pre>
+ *
+ * <p>This class is not thread-safe.
+ *
+ * @param <V> the type of the value
+ */
+public final class ReferenceWithHistory<V> {
+
+ /** The size the history linked list is allowed to grow to. */
+ private final int mMaxHistorySize;
+
+ @Nullable
+ private LinkedList<V> mValues;
+
+ /**
+ * Creates an instance that records, at most, the specified number of values.
+ */
+ public ReferenceWithHistory(@IntRange(from = 1) int maxHistorySize) {
+ if (maxHistorySize < 1) {
+ throw new IllegalArgumentException("maxHistorySize < 1: " + maxHistorySize);
+ }
+ this.mMaxHistorySize = maxHistorySize;
+ }
+
+ /** Returns the current value, or {@code null} if it has never been set. */
+ @Nullable
+ public V get() {
+ return (mValues == null || mValues.isEmpty()) ? null : mValues.getFirst();
+ }
+
+ /** Sets the current value. Returns the previous value, or {@code null}. */
+ @Nullable
+ public V set(@Nullable V newValue) {
+ if (mValues == null) {
+ mValues = new LinkedList<>();
+ }
+
+ V previous = get();
+
+ mValues.addFirst(newValue);
+ if (mValues.size() > mMaxHistorySize) {
+ mValues.removeLast();
+ }
+ return previous;
+ }
+
+ /**
+ * Dumps the content of the reference, including historic values, using the supplied writer.
+ */
+ public void dump(@NonNull IndentingPrintWriter ipw) {
+ if (mValues == null) {
+ ipw.println("{Empty}");
+ } else {
+ int i = 0;
+ for (V value : mValues) {
+ ipw.println(i + ": " + value);
+ i++;
+ }
+ }
+ ipw.flush();
+ }
+
+ /**
+ * Returns the number of historic entries stored currently.
+ */
+ public int getHistoryCount() {
+ return mValues == null ? 0 : mValues.size();
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(get());
+ }
+}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
index b3013c7..b4a4399 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
@@ -27,7 +27,6 @@
import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.app.timezonedetector.PhoneTimeZoneSuggestion;
import android.content.Context;
-import android.util.ArrayMap;
import android.util.LocalLog;
import android.util.Slog;
@@ -38,8 +37,6 @@
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.LinkedList;
-import java.util.Map;
import java.util.Objects;
/**
@@ -175,14 +172,13 @@
private final LocalLog mTimeZoneChangesLog = new LocalLog(30, false /* useLocalTimestamps */);
/**
- * A mapping from phoneId to a linked list of phone time zone suggestions (the head being the
- * latest). We typically expect one or two entries in this Map: devices will have a small number
- * of telephony devices and phoneIds are assumed to be stable. The LinkedList associated with
- * the ID will not exceed {@link #KEEP_PHONE_SUGGESTION_HISTORY_SIZE} in size.
+ * A mapping from phoneId to a phone time zone suggestion. We typically expect one or two
+ * mappings: devices will have a small number of telephony devices and phoneIds are assumed to
+ * be stable.
*/
@GuardedBy("this")
- private ArrayMap<Integer, LinkedList<QualifiedPhoneTimeZoneSuggestion>> mSuggestionByPhoneId =
- new ArrayMap<>();
+ private ArrayMapWithHistory<Integer, QualifiedPhoneTimeZoneSuggestion> mSuggestionByPhoneId =
+ new ArrayMapWithHistory<>(KEEP_PHONE_SUGGESTION_HISTORY_SIZE);
/**
* Creates a new instance of {@link TimeZoneDetectorStrategy}.
@@ -226,16 +222,7 @@
new QualifiedPhoneTimeZoneSuggestion(suggestion, score);
// Store the suggestion against the correct phoneId.
- LinkedList<QualifiedPhoneTimeZoneSuggestion> suggestions =
- mSuggestionByPhoneId.get(suggestion.getPhoneId());
- if (suggestions == null) {
- suggestions = new LinkedList<>();
- mSuggestionByPhoneId.put(suggestion.getPhoneId(), suggestions);
- }
- suggestions.addFirst(scoredSuggestion);
- if (suggestions.size() > KEEP_PHONE_SUGGESTION_HISTORY_SIZE) {
- suggestions.removeLast();
- }
+ mSuggestionByPhoneId.put(suggestion.getPhoneId(), scoredSuggestion);
// Now perform auto time zone detection. The new suggestion may be used to modify the time
// zone setting.
@@ -398,13 +385,7 @@
// rate-limit so age is not a strong indicator of confidence. Instead, the callers are
// expected to withdraw suggestions they no longer have confidence in.
for (int i = 0; i < mSuggestionByPhoneId.size(); i++) {
- LinkedList<QualifiedPhoneTimeZoneSuggestion> phoneSuggestions =
- mSuggestionByPhoneId.valueAt(i);
- if (phoneSuggestions == null) {
- // Unexpected
- continue;
- }
- QualifiedPhoneTimeZoneSuggestion candidateSuggestion = phoneSuggestions.getFirst();
+ QualifiedPhoneTimeZoneSuggestion candidateSuggestion = mSuggestionByPhoneId.valueAt(i);
if (candidateSuggestion == null) {
// Unexpected
continue;
@@ -474,16 +455,7 @@
ipw.println("Phone suggestion history:");
ipw.increaseIndent(); // level 2
- for (Map.Entry<Integer, LinkedList<QualifiedPhoneTimeZoneSuggestion>> entry
- : mSuggestionByPhoneId.entrySet()) {
- ipw.println("Phone " + entry.getKey());
-
- ipw.increaseIndent(); // level 3
- for (QualifiedPhoneTimeZoneSuggestion suggestion : entry.getValue()) {
- ipw.println(suggestion);
- }
- ipw.decreaseIndent(); // level 3
- }
+ mSuggestionByPhoneId.dump(ipw);
ipw.decreaseIndent(); // level 2
ipw.decreaseIndent(); // level 1
ipw.flush();
@@ -494,12 +466,7 @@
*/
@VisibleForTesting
public synchronized QualifiedPhoneTimeZoneSuggestion getLatestPhoneSuggestion(int phoneId) {
- LinkedList<QualifiedPhoneTimeZoneSuggestion> suggestions =
- mSuggestionByPhoneId.get(phoneId);
- if (suggestions == null) {
- return null;
- }
- return suggestions.getFirst();
+ return mSuggestionByPhoneId.get(phoneId);
}
/**
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index c57ac11..b154da4 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -228,11 +228,10 @@
}
}
- public void onAppWindowTransitionLocked(WindowState windowState, int transition) {
- final int displayId = windowState.getDisplayId();
+ public void onAppWindowTransitionLocked(int displayId, int transition) {
final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
if (displayMagnifier != null) {
- displayMagnifier.onAppWindowTransitionLocked(windowState, transition);
+ displayMagnifier.onAppWindowTransitionLocked(displayId, transition);
}
// Not relevant for the window observer.
}
@@ -446,11 +445,11 @@
mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_ROTATION_CHANGED);
}
- public void onAppWindowTransitionLocked(WindowState windowState, int transition) {
+ public void onAppWindowTransitionLocked(int displayId, int transition) {
if (DEBUG_WINDOW_TRANSITIONS) {
Slog.i(LOG_TAG, "Window transition: "
+ AppTransition.appTransitionToString(transition)
- + " displayId: " + windowState.getDisplayId());
+ + " displayId: " + displayId);
}
final boolean magnifying = mMagnifedViewport.isMagnifyingLocked();
if (magnifying) {
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index c8357e29..1c010c7 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -543,9 +543,10 @@
return;
}
- if (info != null) {
- // If we are already in an existing transition, only update the activity name, but not
- // the other attributes.
+ if (info != null
+ && info.mLastLaunchedActivity.mDisplayContent == launchedActivity.mDisplayContent) {
+ // If we are already in an existing transition on the same display, only update the
+ // activity name, but not the other attributes.
if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched update launched activity");
// Coalesce multiple (trampoline) activities from a single sequence together.
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 8b73643..1503282 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1811,7 +1811,7 @@
} else if (newTask || !processRunning || (taskSwitch && !activityCreated)) {
return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
} else if (taskSwitch && allowTaskSnapshot) {
- return snapshot == null ? STARTING_WINDOW_TYPE_SPLASH_SCREEN
+ return snapshot == null ? STARTING_WINDOW_TYPE_NONE
: snapshotOrientationSameAsTask(snapshot) || fromRecents
? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
} else {
@@ -4159,7 +4159,7 @@
* transition.
*
* <p class="note><strong>Note:</strong> If the visibility of this {@link ActivityRecord} is
- * already set to {@link #visible}, we don't need to update the visibility. So {@code false} is
+ * already set to {@link #mVisible}, we don't need to update the visibility. So {@code false} is
* returned.</p>
*
* @param visible {@code true} if this {@link ActivityRecord} should become visible,
@@ -4169,16 +4169,13 @@
*/
boolean shouldApplyAnimation(boolean visible) {
// Allow for state update and animation to be applied if:
- // * token is transitioning visibility state
- // * or the token was marked as hidden and is exiting before we had a chance to play the
+ // * activity is transitioning visibility state
+ // * or the activity was marked as hidden and is exiting before we had a chance to play the
// transition animation
- // * or this is an opening app and windows are being replaced
- // * or the token is the opening app and visible while opening task behind existing one.
- final DisplayContent displayContent = getDisplayContent();
+ // * or this is an opening app and windows are being replaced (e.g. freeform window to
+ // normal window).
return isVisible() != visible || (!isVisible() && mIsExiting)
- || (visible && forAllWindows(WindowState::waitingForReplacement, true))
- || (visible && displayContent.mOpeningApps.contains(this)
- && displayContent.mAppTransition.getAppTransition() == TRANSIT_TASK_OPEN_BEHIND);
+ || (visible && forAllWindows(WindowState::waitingForReplacement, true));
}
/**
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index a741d45..62dd7bb 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -821,10 +821,7 @@
// Update bounds if applicable
boolean hasNewOverrideBounds = false;
// Use override windowing mode to prevent extra bounds changes if inheriting the mode.
- if (overrideWindowingMode == WINDOWING_MODE_PINNED) {
- // Pinned calculation already includes rotation
- hasNewOverrideBounds = calculatePinnedBoundsForConfigChange(newBounds);
- } else if (!matchParentBounds()) {
+ if ((overrideWindowingMode != WINDOWING_MODE_PINNED) && !matchParentBounds()) {
// If the parent (display) has rotated, rotate our bounds to best-fit where their
// bounds were on the pre-rotated display.
final int newRotation = getWindowConfiguration().getRotation();
@@ -882,9 +879,6 @@
null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
null /* tempOtherTaskBounds */, null /* tempOtherTaskInsetBounds */,
PRESERVE_WINDOWS, true /* deferResume */);
- } else {
- resize(new Rect(newBounds), null /* tempTaskBounds */,
- null /* tempTaskInsetBounds */, PRESERVE_WINDOWS, true /* deferResume */);
}
}
if (prevIsAlwaysOnTop != isAlwaysOnTop()) {
@@ -4089,45 +4083,27 @@
}
/**
- * Updates the passed-in {@code inOutBounds} based on the current state of the
- * pinned controller. This gets run *after* the override configuration is updated, so it's
- * safe to rely on the controller's state in here (though eventually this dependence should
- * be removed).
+ * Reset the current animation running on {@link #mBoundsAnimationTarget}.
*
- * This does NOT modify this TaskStack's configuration. However, it does, for the time-being,
- * update pinned controller state.
- *
- * @param inOutBounds the bounds to update (both input and output).
- * @return true if bounds were updated to some non-empty value.
+ * @param destinationBounds the final destination bounds
*/
- boolean calculatePinnedBoundsForConfigChange(Rect inOutBounds) {
- boolean animating = false;
- if ((mBoundsAnimatingRequested || mBoundsAnimating) && !mBoundsAnimationTarget.isEmpty()) {
- animating = true;
- getFinalAnimationBounds(mTmpRect2);
- } else {
- mTmpRect2.set(inOutBounds);
- }
- boolean updated = mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
- mTmpRect2, mTmpRect3);
- if (updated) {
- inOutBounds.set(mTmpRect3);
+ void resetCurrentBoundsAnimation(Rect destinationBounds) {
+ boolean animating = (mBoundsAnimatingRequested || mBoundsAnimating)
+ && !mBoundsAnimationTarget.isEmpty();
- // The final boundary is updated while there is an existing boundary animation. Let's
- // cancel this animation to prevent the obsolete animation overwritten updated bounds.
- if (animating && !inOutBounds.equals(mBoundsAnimationTarget)) {
- final DisplayContent displayContent = getDisplayContent();
- displayContent.mBoundsAnimationController.getHandler().post(() ->
- displayContent.mBoundsAnimationController.cancel(this));
- }
- // Once we've set the bounds based on the rotation of the old bounds in the new
- // orientation, clear the animation target bounds since they are obsolete, and
- // cancel any currently running animations
- mBoundsAnimationTarget.setEmpty();
- mBoundsAnimationSourceHintBounds.setEmpty();
- mCancelCurrentBoundsAnimation = true;
+ // The final boundary is updated while there is an existing boundary animation. Let's
+ // cancel this animation to prevent the obsolete animation overwritten updated bounds.
+ if (animating && !destinationBounds.equals(mBoundsAnimationTarget)) {
+ final BoundsAnimationController controller =
+ getDisplayContent().mBoundsAnimationController;
+ controller.getHandler().post(() -> controller.cancel(this));
}
- return updated;
+ // Once we've set the bounds based on the rotation of the old bounds in the new
+ // orientation, clear the animation target bounds since they are obsolete, and
+ // cancel any currently running animations
+ mBoundsAnimationTarget.setEmpty();
+ mBoundsAnimationSourceHintBounds.setEmpty();
+ mCancelCurrentBoundsAnimation = true;
}
/**
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 674955e..6ad439e 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -51,7 +51,6 @@
import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
-import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
@@ -1688,19 +1687,9 @@
return START_SUCCESS;
}
- // True if we are clearing top and resetting of a standard (default) launch mode
- // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
- final boolean clearTopAndResetStandardLaunchMode =
- (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
- == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
- && mLaunchMode == LAUNCH_MULTIPLE;
-
boolean clearTaskForReuse = false;
if (reusedTask != null) {
- // If mStartActivity does not have a task associated with it, associate it with the
- // reused activity's task. Do not do so if we're clearing top and resetting for a
- // standard launchMode activity.
- if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {
+ if (mStartActivity.getTask() == null) {
mStartActivity.setTaskForReuse(reusedTask);
clearTaskForReuse = true;
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 2e53cd5..60f051c 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -3302,6 +3302,23 @@
Configuration c = new Configuration(container.getRequestedOverrideConfiguration());
c.setTo(change.getConfiguration(), configMask, windowMask);
container.onRequestedOverrideConfigurationChanged(c);
+ // TODO(b/145675353): remove the following once we could apply new bounds to the
+ // pinned stack together with its children.
+ resizePinnedStackIfNeeded(container, configMask, windowMask, c);
+ }
+
+ private void resizePinnedStackIfNeeded(ConfigurationContainer container, int configMask,
+ int windowMask, Configuration config) {
+ if ((container instanceof ActivityStack)
+ && ((configMask & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0)
+ && ((windowMask & WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)) {
+ final ActivityStack stack = (ActivityStack) container;
+ if (stack.inPinnedWindowingMode()) {
+ stack.resize(config.windowConfiguration.getBounds(),
+ null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
+ PRESERVE_WINDOWS, true /* deferResume */);
+ }
+ }
}
@Override
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 6ea0650..6e09b94 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -48,6 +48,7 @@
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
import static com.android.server.wm.AppTransition.isKeyguardGoingAwayTransit;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM;
import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
@@ -69,6 +70,8 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.protolog.common.ProtoLog;
+import java.util.ArrayList;
+import java.util.LinkedList;
import java.util.function.Predicate;
@@ -180,11 +183,7 @@
final int layoutRedo;
mService.mSurfaceAnimationRunner.deferStartingAnimations();
try {
- // TODO: Apply an app transition animation on TaskStack instead of ActivityRecord when
- // appropriate.
- applyAnimations(mDisplayContent.mClosingApps, transit, false /* visible */,
- animLp, voiceInteraction);
- applyAnimations(mDisplayContent.mOpeningApps, transit, true /* visible */,
+ applyAnimations(mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps, transit,
animLp, voiceInteraction);
handleClosingApps();
handleOpeningApps();
@@ -350,9 +349,9 @@
}
/**
- * Apply an app transition animation on a set of {@link ActivityRecord}
+ * Apply animation to the set of window containers.
*
- * @param apps The list of apps to which an app transition animation applies.
+ * @param wcs The list of {@link WindowContainer}s to which an app transition animation applies.
* @param transit The current transition type.
* @param visible {@code true} if the apps becomes visible, {@code false} if the apps becomes
* invisible.
@@ -360,24 +359,150 @@
* @param voiceInteraction {@code true} if one of the apps in this transition belongs to a voice
* interaction session driving task.
*/
- private void applyAnimations(ArraySet<ActivityRecord> apps, @TransitionType int transit,
+ private void applyAnimations(ArraySet<WindowContainer> wcs, @TransitionType int transit,
boolean visible, LayoutParams animLp, boolean voiceInteraction) {
- final int appsCount = apps.size();
+ final int appsCount = wcs.size();
for (int i = 0; i < appsCount; i++) {
+ final WindowContainer wc = wcs.valueAt(i);
+ wc.applyAnimation(animLp, transit, visible, voiceInteraction);
+ }
+ }
+
+ /**
+ * Find WindowContainers to be animated from a set of opening and closing apps. We will promote
+ * animation targets to higher level in the window hierarchy if possible.
+ *
+ * @param visible {@code true} to get animation targets for opening apps, {@code false} to get
+ * animation targets for closing apps.
+ * @return {@link WindowContainer}s to be animated.
+ */
+ @VisibleForTesting
+ static ArraySet<WindowContainer> getAnimationTargets(
+ ArraySet<ActivityRecord> openingApps, ArraySet<ActivityRecord> closingApps,
+ boolean visible) {
+
+ // The candidates of animation targets, which might be able to promote to higher level.
+ final LinkedList<WindowContainer> candidates = new LinkedList<>();
+ final ArraySet<ActivityRecord> apps = visible ? openingApps : closingApps;
+ for (int i = 0; i < apps.size(); ++i) {
final ActivityRecord app = apps.valueAt(i);
- if (transit != WindowManager.TRANSIT_UNSET && app.shouldApplyAnimation(visible)) {
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Changing app %s visible=%b performLayout=%b",
+ if (app.shouldApplyAnimation(visible)) {
+ candidates.add(app);
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "Changing app %s visible=%b performLayout=%b",
app, app.isVisible(), false);
- if (!app.mUseTransferredAnimation) {
- app.applyAnimation(animLp, transit, visible, voiceInteraction);
+ }
+ }
+
+ if (!WindowManagerService.sHierarchicalAnimations) {
+ return new ArraySet<>(candidates);
+ }
+
+ final ArraySet<ActivityRecord> otherApps = visible ? closingApps : openingApps;
+ // Ancestors of closing apps while finding animation targets for opening apps, or ancestors
+ // of opening apps while finding animation targets for closing apps.
+ final ArraySet<WindowContainer> otherAncestors = new ArraySet<>();
+ for (int i = 0; i < otherApps.size(); ++i) {
+ for (WindowContainer wc = otherApps.valueAt(i); wc != null; wc = wc.getParent()) {
+ otherAncestors.add(wc);
+ }
+ }
+
+ // The final animation targets which cannot promote to higher level anymore.
+ final ArraySet<WindowContainer> targets = new ArraySet<>();
+ final ArrayList<WindowContainer> siblings = new ArrayList<>();
+ while (!candidates.isEmpty()) {
+ final WindowContainer current = candidates.removeFirst();
+ final WindowContainer parent = current.getParent();
+ boolean canPromote = true;
+
+ if (parent == null) {
+ canPromote = false;
+ } else {
+ // In case a descendant of the parent belongs to the other group, we cannot promote
+ // the animation target from "current" to the parent.
+ //
+ // Example: Imagine we're checking if we can animate a Task instead of a set of
+ // ActivityRecords. In case an activity starts a new activity within a same Task,
+ // an ActivityRecord of an existing activity belongs to the opening apps, at the
+ // same time, the other ActivityRecord of a new activity belongs to the closing
+ // apps. In this case, we cannot promote the animation target to Task level, but
+ // need to animate each individual activity.
+ //
+ // [Task] +- [ActivityRecord1] (in opening apps)
+ // +- [ActivityRecord2] (in closing apps)
+ if (otherAncestors.contains(parent)) {
+ canPromote = false;
}
- final WindowState window = app.findMainWindow();
- final AccessibilityController accessibilityController =
- app.mWmService.mAccessibilityController;
- if (window != null && accessibilityController != null) {
- accessibilityController.onAppWindowTransitionLocked(window, transit);
+
+ // Find all siblings of the current WindowContainer in "candidates", move them into
+ // a separate list "siblings", and checks if an animation target can be promoted
+ // to its parent.
+ //
+ // We can promote an animation target to its parent if and only if all visible
+ // siblings will be animating.
+ //
+ // Example: Imagine that a Task contains two visible activity record, but only one
+ // of them is included in the opening apps and the other belongs to neither opening
+ // or closing apps. This happens when an activity launches another translucent
+ // activity in the same Task. In this case, we cannot animate Task, but have to
+ // animate each activity, otherwise an activity behind the translucent activity also
+ // animates.
+ //
+ // [Task] +- [ActivityRecord1] (visible, in opening apps)
+ // +- [ActivityRecord2] (visible, not in opening apps)
+ siblings.clear();
+ for (int j = 0; j < parent.getChildCount(); ++j) {
+ final WindowContainer sibling = parent.getChildAt(j);
+ if (sibling == current || candidates.remove(sibling)) {
+ siblings.add(sibling);
+ } else if (sibling.isVisible()) {
+ canPromote = false;
+ }
}
}
+
+ if (canPromote) {
+ candidates.add(parent);
+ } else {
+ targets.addAll(siblings);
+ }
+ }
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, "getAnimationTarget in=%s, out=%s",
+ apps, targets);
+ return targets;
+ }
+
+ /**
+ * Apply an app transition animation based on a set of {@link ActivityRecord}
+ *
+ * @param openingApps The list of opening apps to which an app transition animation applies.
+ * @param closingApps The list of closing apps to which an app transition animation applies.
+ * @param transit The current transition type.
+ * @param animLp Layout parameters in which an app transition animation runs.
+ * @param voiceInteraction {@code true} if one of the apps in this transition belongs to a voice
+ * interaction session driving task.
+ */
+ private void applyAnimations(ArraySet<ActivityRecord> openingApps,
+ ArraySet<ActivityRecord> closingApps, @TransitionType int transit,
+ LayoutParams animLp, boolean voiceInteraction) {
+ if (transit == WindowManager.TRANSIT_UNSET
+ || (openingApps.isEmpty() && closingApps.isEmpty())) {
+ return;
+ }
+
+ final ArraySet<WindowContainer> openingWcs = getAnimationTargets(
+ openingApps, closingApps, true /* visible */);
+ final ArraySet<WindowContainer> closingWcs = getAnimationTargets(
+ openingApps, closingApps, false /* visible */);
+ applyAnimations(openingWcs, transit, true /* visible */, animLp, voiceInteraction);
+ applyAnimations(closingWcs, transit, false /* visible */, animLp, voiceInteraction);
+
+ final AccessibilityController accessibilityController =
+ mDisplayContent.mWmService.mAccessibilityController;
+ if (accessibilityController != null) {
+ accessibilityController.onAppWindowTransitionLocked(
+ mDisplayContent.getDisplayId(), transit);
}
}
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 5dc88b3..9b464c2 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -185,6 +185,10 @@
resume();
};
+ // If this animator is explicitly cancelled when it's in paused state, we should not
+ // attempt to resume the animation. Use this flag to avoid such behavior.
+ private boolean mIsCancelled;
+
BoundsAnimator(BoundsAnimationTarget target, @AnimationType int animationType, Rect from,
Rect to, @SchedulePipModeChangedState int schedulePipModeChangedState,
@SchedulePipModeChangedState int prevShedulePipModeChangedState,
@@ -221,6 +225,7 @@
if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget
+ " mPrevSchedulePipModeChangedState=" + mPrevSchedulePipModeChangedState
+ " mSchedulePipModeChangedState=" + mSchedulePipModeChangedState);
+ mIsCancelled = false;
mFinishAnimationAfterTransition = false;
mTmpRect.set(mFrom.left, mFrom.top, mFrom.left + mFrozenTaskWidth,
mFrom.top + mFrozenTaskHeight);
@@ -293,7 +298,7 @@
public void resume() {
if (DEBUG) Slog.d(TAG, "resume:");
mHandler.removeCallbacks(mResumeRunnable);
- super.resume();
+ if (!mIsCancelled) super.resume();
}
@Override
@@ -376,6 +381,7 @@
@Override
public void onAnimationCancel(Animator animation) {
+ mIsCancelled = true;
// Always skip the final resize when the animation is canceled
mSkipFinalResize = true;
mMoveToFullscreen = false;
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index a8e7aea..b4f75e5 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -16,38 +16,29 @@
package com.android.server.wm;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.util.TypedValue.COMPLEX_UNIT_DIP;
import static com.android.server.wm.PinnedStackControllerProto.DEFAULT_BOUNDS;
import static com.android.server.wm.PinnedStackControllerProto.MOVEMENT_BOUNDS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import android.annotation.NonNull;
import android.app.RemoteAction;
import android.content.ComponentName;
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
-import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.DisplayMetrics;
import android.util.Log;
-import android.util.Size;
import android.util.Slog;
-import android.util.TypedValue;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayInfo;
-import android.view.Gravity;
import android.view.IPinnedStackController;
import android.view.IPinnedStackListener;
-import com.android.internal.policy.PipSnapAlgorithm;
-import com.android.internal.util.Preconditions;
import com.android.server.UiThread;
import java.io.PrintWriter;
@@ -74,7 +65,6 @@
private static final String TAG = TAG_WITH_CLASS_NAME ? "PinnedStackController" : TAG_WM;
- private static final float INVALID_SNAP_FRACTION = -1f;
private final WindowManagerService mService;
private final DisplayContent mDisplayContent;
private final Handler mHandler = UiThread.getHandler();
@@ -84,7 +74,6 @@
new PinnedStackListenerDeathHandler();
private final PinnedStackControllerCallback mCallbacks = new PinnedStackControllerCallback();
- private final PipSnapAlgorithm mSnapAlgorithm;
// States that affect how the PIP can be manipulated
private boolean mIsMinimized;
@@ -97,13 +86,9 @@
// Used to calculate stack bounds across rotations
private final DisplayInfo mDisplayInfo = new DisplayInfo();
- private final Rect mStableInsets = new Rect();
// The size and position information that describes where the pinned stack will go by default.
- private int mDefaultMinSize;
- private int mDefaultStackGravity;
private float mDefaultAspectRatio;
- private Point mScreenEdgeInsets;
// The aspect ratio bounds of the PIP.
private float mMinAspectRatio;
@@ -111,10 +96,11 @@
// Temp vars for calculation
private final DisplayMetrics mTmpMetrics = new DisplayMetrics();
- private final Rect mTmpInsets = new Rect();
- private final Rect mTmpRect = new Rect();
- private final Point mTmpDisplaySize = new Point();
+ // TODO(b/141200935): remove this when we have default/movement bounds tests in SysUI.
+ // Keep record of the default and movement bounds
+ private final Rect mLastReportedDefaultBounds = new Rect();
+ private final Rect mLastReportedMovementBounds = new Rect();
/**
* The callback object passed to listeners for them to notify the controller of state changes.
@@ -125,7 +111,6 @@
public void setIsMinimized(final boolean isMinimized) {
mHandler.post(() -> {
mIsMinimized = isMinimized;
- mSnapAlgorithm.setMinimized(isMinimized);
});
}
@@ -145,6 +130,27 @@
sourceRectHint, animationDuration, true /* fromFullscreen */);
}
}
+
+ @Override
+ public void resetBoundsAnimation(Rect bounds) {
+ synchronized (mService.mGlobalLock) {
+ if (mDisplayContent.hasPinnedStack()) {
+ final ActivityStack pinnedStack = mDisplayContent.getTopStackInWindowingMode(
+ WINDOWING_MODE_PINNED);
+ if (pinnedStack != null) {
+ pinnedStack.resetCurrentBoundsAnimation(bounds);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void reportBounds(Rect defaultBounds, Rect movementBounds) {
+ synchronized (mService.mGlobalLock) {
+ mLastReportedDefaultBounds.set(defaultBounds);
+ mLastReportedMovementBounds.set(movementBounds);
+ }
+ }
}
/**
@@ -165,7 +171,6 @@
PinnedStackController(WindowManagerService service, DisplayContent displayContent) {
mService = service;
mDisplayContent = displayContent;
- mSnapAlgorithm = new PipSnapAlgorithm(service.mContext);
mDisplayInfo.copyFrom(mDisplayContent.getDisplayInfo());
reloadResources();
// Initialize the aspect ratio to the default aspect ratio. Don't do this in reload
@@ -183,21 +188,9 @@
*/
private void reloadResources() {
final Resources res = mService.mContext.getResources();
- mDefaultMinSize = res.getDimensionPixelSize(
- com.android.internal.R.dimen.default_minimal_size_pip_resizable_task);
mDefaultAspectRatio = res.getFloat(
com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio);
- final String screenEdgeInsetsDpString = res.getString(
- com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets);
- final Size screenEdgeInsetsDp = !screenEdgeInsetsDpString.isEmpty()
- ? Size.parseSize(screenEdgeInsetsDpString)
- : null;
- mDefaultStackGravity = res.getInteger(
- com.android.internal.R.integer.config_defaultPictureInPictureGravity);
mDisplayContent.getDisplay().getRealMetrics(mTmpMetrics);
- mScreenEdgeInsets = screenEdgeInsetsDp == null ? new Point()
- : new Point(dpToPx(screenEdgeInsetsDp.getWidth(), mTmpMetrics),
- dpToPx(screenEdgeInsetsDp.getHeight(), mTmpMetrics));
mMinAspectRatio = res.getFloat(
com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
mMaxAspectRatio = res.getFloat(
@@ -215,7 +208,7 @@
notifyDisplayInfoChanged(mDisplayInfo);
notifyImeVisibilityChanged(mIsImeShowing, mImeHeight);
// The movement bounds notification needs to be sent before the minimized state, since
- // SystemUI may use the bounds to retore the minimized position
+ // SystemUI may use the bounds to restore the minimized position
notifyMovementBoundsChanged(false /* fromImeAdjustment */,
false /* fromShelfAdjustment */);
notifyActionsChanged(mActions);
@@ -257,30 +250,6 @@
}
}
- /**
- * @return the default bounds to show the PIP, if a {@param snapFraction} is provided, then it
- * will apply the default bounds to the provided snap fraction.
- */
- private Rect getDefaultBounds(float snapFraction) {
- synchronized (mService.mGlobalLock) {
- final Rect insetBounds = new Rect();
- getInsetBounds(insetBounds);
-
- final Rect defaultBounds = new Rect();
- final Size size = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio,
- mDefaultMinSize, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
- if (snapFraction != INVALID_SNAP_FRACTION) {
- defaultBounds.set(0, 0, size.getWidth(), size.getHeight());
- final Rect movementBounds = getMovementBounds(defaultBounds);
- mSnapAlgorithm.applySnapFraction(defaultBounds, movementBounds, snapFraction);
- } else {
- Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds,
- 0, mIsImeShowing ? mImeHeight : 0, defaultBounds);
- }
- return defaultBounds;
- }
- }
-
private void setDisplayInfo(DisplayInfo displayInfo) {
mDisplayInfo.copyFrom(displayInfo);
notifyDisplayInfoChanged(mDisplayInfo);
@@ -300,51 +269,6 @@
}
/**
- * Updates the display info, calculating and returning the new stack and movement bounds in the
- * new orientation of the device if necessary.
- */
- boolean onTaskStackBoundsChanged(Rect targetBounds, Rect outBounds) {
- synchronized (mService.mGlobalLock) {
- final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
- if (isSameDimensionAndRotation(mDisplayInfo, displayInfo)) {
- // No dimension/rotation change, ignore
- outBounds.setEmpty();
- return false;
- } else if (targetBounds.isEmpty()) {
- // The stack is null, we are just initializing the stack, so just store the display
- // info and ignore
- setDisplayInfo(displayInfo);
- outBounds.setEmpty();
- return false;
- }
-
- mTmpRect.set(targetBounds);
- final Rect postChangeStackBounds = mTmpRect;
-
- // Calculate the snap fraction of the current stack along the old movement bounds
- final float snapFraction = getSnapFraction(postChangeStackBounds);
-
- setDisplayInfo(displayInfo);
-
- // Calculate the stack bounds in the new orientation to the same same fraction along the
- // rotated movement bounds.
- final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
- false /* adjustForIme */);
- mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
- snapFraction);
- if (mIsMinimized) {
- applyMinimizedOffset(postChangeStackBounds, postChangeMovementBounds);
- }
-
- notifyMovementBoundsChanged(false /* fromImeAdjustment */,
- false /* fromShelfAdjustment */);
-
- outBounds.set(postChangeStackBounds);
- return true;
- }
- }
-
- /**
* Sets the Ime state and height.
*/
void setAdjustedForIme(boolean adjustedForIme, int imeHeight) {
@@ -400,15 +324,6 @@
notifyPrepareAnimation(sourceRectHint, aspectRatio, stackBounds);
}
- private boolean isSameDimensionAndRotation(@NonNull DisplayInfo display1,
- @NonNull DisplayInfo display2) {
- Preconditions.checkNotNull(display1);
- Preconditions.checkNotNull(display2);
- return ((display1.rotation == display2.rotation)
- && (display1.logicalWidth == display2.logicalWidth)
- && (display1.logicalHeight == display2.logicalHeight));
- }
-
/**
* Notifies listeners that the PIP needs to be adjusted for the IME.
*/
@@ -504,86 +419,11 @@
}
}
- /**
- * @return the bounds on the screen that the PIP can be visible in.
- */
- private void getInsetBounds(Rect outRect) {
- synchronized (mService.mGlobalLock) {
- mDisplayContent.getDisplayPolicy().getStableInsetsLw(mDisplayInfo.rotation,
- mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight,
- mDisplayInfo.displayCutout, mTmpInsets);
- outRect.set(mTmpInsets.left + mScreenEdgeInsets.x, mTmpInsets.top + mScreenEdgeInsets.y,
- mDisplayInfo.logicalWidth - mTmpInsets.right - mScreenEdgeInsets.x,
- mDisplayInfo.logicalHeight - mTmpInsets.bottom - mScreenEdgeInsets.y);
- }
- }
-
- /**
- * @return the movement bounds for the given {@param stackBounds} and the current state of the
- * controller.
- */
- private Rect getMovementBounds(Rect stackBounds) {
- synchronized (mService.mGlobalLock) {
- return getMovementBounds(stackBounds, true /* adjustForIme */);
- }
- }
-
- /**
- * @return the movement bounds for the given {@param stackBounds} and the current state of the
- * controller.
- */
- private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
- synchronized (mService.mGlobalLock) {
- final Rect movementBounds = new Rect();
- getInsetBounds(movementBounds);
-
- // Apply the movement bounds adjustments based on the current state.
- // Note that shelf offset does not affect the movement bounds here
- // since it's been taken care of in system UI.
- mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
- (adjustForIme && mIsImeShowing) ? mImeHeight : 0);
- return movementBounds;
- }
- }
-
- /**
- * Applies the minimized offsets to the given stack bounds.
- */
- private void applyMinimizedOffset(Rect stackBounds, Rect movementBounds) {
- synchronized (mService.mGlobalLock) {
- mTmpDisplaySize.set(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
- mService.getStableInsetsLocked(mDisplayContent.getDisplayId(), mStableInsets);
- mSnapAlgorithm.applyMinimizedOffset(stackBounds, movementBounds, mTmpDisplaySize,
- mStableInsets);
- }
- }
-
- /**
- * @return the default snap fraction to apply instead of the default gravity when calculating
- * the default stack bounds when first entering PiP.
- */
- private float getSnapFraction(Rect stackBounds) {
- return mSnapAlgorithm.getSnapFraction(stackBounds, getMovementBounds(stackBounds));
- }
-
- /**
- * @return the pixels for a given dp value.
- */
- private int dpToPx(float dpValue, DisplayMetrics dm) {
- return (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, dpValue, dm);
- }
-
void dump(String prefix, PrintWriter pw) {
pw.println(prefix + "PinnedStackController");
- pw.print(prefix + " defaultBounds=");
- getDefaultBounds(INVALID_SNAP_FRACTION).printShortString(pw);
- pw.println();
- pw.println(prefix + " mDefaultMinSize=" + mDefaultMinSize);
- pw.println(prefix + " mDefaultStackGravity=" + mDefaultStackGravity);
+ pw.println(prefix + " mLastReportedDefaultBounds=" + mLastReportedDefaultBounds);
+ pw.println(prefix + " mLastReportedMovementBounds=" + mLastReportedMovementBounds);
pw.println(prefix + " mDefaultAspectRatio=" + mDefaultAspectRatio);
- mService.getStackBounds(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mTmpRect);
- pw.print(prefix + " movementBounds="); getMovementBounds(mTmpRect).printShortString(pw);
- pw.println();
pw.println(prefix + " mIsImeShowing=" + mIsImeShowing);
pw.println(prefix + " mImeHeight=" + mImeHeight);
pw.println(prefix + " mIsMinimized=" + mIsMinimized);
@@ -606,9 +446,8 @@
void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- getDefaultBounds(INVALID_SNAP_FRACTION).dumpDebug(proto, DEFAULT_BOUNDS);
- mService.getStackBounds(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mTmpRect);
- getMovementBounds(mTmpRect).dumpDebug(proto, MOVEMENT_BOUNDS);
+ mLastReportedDefaultBounds.dumpDebug(proto, DEFAULT_BOUNDS);
+ mLastReportedMovementBounds.dumpDebug(proto, MOVEMENT_BOUNDS);
proto.end(token);
}
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 39091a6..b255b5e 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -754,8 +754,7 @@
// Only apply the input consumer if it is enabled, it is not the target (home/recents)
// being revealed with the transition, and we are actively animating the app as a part of
// the animation
- return mInputConsumerEnabled && mTargetActivityRecord != activity
- && isAnimatingApp(activity);
+ return mInputConsumerEnabled && !isTargetApp(activity) && isAnimatingApp(activity);
}
boolean updateInputConsumerForApp(InputWindowHandle inputWindowHandle,
@@ -810,7 +809,9 @@
PooledLambda.__(ActivityRecord.class));
boolean isAnimatingApp = task.forAllActivities(f);
f.recycle();
- return isAnimatingApp;
+ if (isAnimatingApp) {
+ return true;
+ }
}
return false;
}
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 456068c..3182a72 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -281,7 +281,8 @@
*
* @return true if the state of the task is ok to proceed
*/
- private boolean prepareTaskSnapshot(Task task, float scaleFraction, int pixelFormat,
+ @VisibleForTesting
+ boolean prepareTaskSnapshot(Task task, float scaleFraction, int pixelFormat,
TaskSnapshot.Builder builder) {
if (!mService.mPolicy.isScreenOn()) {
if (DEBUG_SCREENSHOT) {
@@ -339,6 +340,7 @@
&& (!activity.fillsParent() || isWindowTranslucent);
builder.setTopActivityComponent(activity.mActivityComponent);
+ builder.setPixelFormat(pixelFormat);
builder.setIsTranslucent(isTranslucent);
builder.setOrientation(activity.getTask().getConfiguration().orientation);
builder.setWindowingMode(task.getWindowingMode());
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 10f2996..d36a5d4 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -366,8 +366,6 @@
}
boolean writeBuffer() {
- // TODO(b/116112787) TaskSnapshot needs bookkeep the ColorSpace of the
- // hardware bitmap when created.
final Bitmap bitmap = Bitmap.wrapHardwareBuffer(
mSnapshot.getSnapshot(), mSnapshot.getColorSpace());
if (bitmap == null) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5771f2c..1313eeb 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2691,18 +2691,18 @@
return mActivityRecord.getTask().getTaskStack().shouldIgnoreInput()
|| !mActivityRecord.mVisibleRequested
- || isAnimatingToRecents();
+ || isRecentsAnimationConsumingAppInput();
}
/**
- * Returns {@code true} if the window is animating to home as part of the recents animation.
+ * Returns {@code true} if the window is animating to home as part of the recents animation and
+ * it is consuming input from the app.
*/
- private boolean isAnimatingToRecents() {
+ private boolean isRecentsAnimationConsumingAppInput() {
final RecentsAnimationController recentsAnimationController =
mWmService.getRecentsAnimationController();
return recentsAnimationController != null
- && recentsAnimationController.isAnimatingTask(getTask())
- && !recentsAnimationController.isTargetApp(mActivityRecord);
+ && recentsAnimationController.shouldApplyInputConsumer(mActivityRecord);
}
@Override
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index a34b7fd..fee29db 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -52,6 +52,7 @@
"com_android_server_GraphicsStatsService.cpp",
"com_android_server_am_AppCompactor.cpp",
"com_android_server_am_LowMemDetector.cpp",
+ "com_android_server_incremental_IncrementalManagerService.cpp",
"onload.cpp",
":lib_networkStatsFactory_native",
],
@@ -145,6 +146,7 @@
"android.frameworks.schedulerservice@1.0",
"android.frameworks.sensorservice@1.0",
"android.system.suspend@1.0",
+ "service.incremental",
"suspend_control_aidl_interface-cpp",
"vintf-vibrator-cpp",
],
diff --git a/services/core/jni/com_android_server_incremental_IncrementalManagerService.cpp b/services/core/jni/com_android_server_incremental_IncrementalManagerService.cpp
new file mode 100644
index 0000000..5e255f4
--- /dev/null
+++ b/services/core/jni/com_android_server_incremental_IncrementalManagerService.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#define LOG_TAG "incremental_manager_service-jni"
+
+#include "incremental_service.h"
+#include "jni.h"
+
+#include <memory>
+#include <nativehelper/JNIHelp.h>
+
+
+namespace android {
+
+static jlong nativeStartService(JNIEnv* env, jclass klass, jobject self) {
+ return Incremental_IncrementalService_Start();
+}
+
+static void nativeSystemReady(JNIEnv* env, jclass klass, jlong self) {
+ Incremental_IncrementalService_OnSystemReady(self);
+}
+
+static const JNINativeMethod method_table[] = {
+ {"nativeStartService", "()J", (void*)nativeStartService},
+ {"nativeSystemReady", "(J)V", (void*)nativeSystemReady},
+};
+
+int register_android_server_incremental_IncrementalManagerService(JNIEnv* env) {
+ return jniRegisterNativeMethods(env,
+ "com/android/server/incremental/IncrementalManagerService",
+ method_table, std::size(method_table));
+}
+
+} // namespace android
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 165edf1..c0a6e4e 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -58,6 +58,7 @@
int register_android_server_am_LowMemDetector(JNIEnv* env);
int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(
JNIEnv* env);
+int register_android_server_incremental_IncrementalManagerService(JNIEnv* env);
};
using namespace android;
@@ -109,5 +110,6 @@
register_android_server_am_LowMemDetector(env);
register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(
env);
+ register_android_server_incremental_IncrementalManagerService(env);
return JNI_VERSION_1_4;
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 8cd803c..eda69a9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -254,6 +254,7 @@
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
+import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.Preconditions;
@@ -2105,6 +2106,10 @@
Binder.withCleanCallingIdentity(action);
}
+ final <T> T binderWithCleanCallingIdentity(@NonNull ThrowingSupplier<T> action) {
+ return Binder.withCleanCallingIdentity(action);
+ }
+
final int userHandleGetCallingUserId() {
return UserHandle.getUserId(binderGetCallingUid());
}
@@ -2369,12 +2374,7 @@
* @return
*/
DevicePolicyData getUserDataUnchecked(int userHandle) {
- long ident = mInjector.binderClearCallingIdentity();
- try {
- return getUserData(userHandle);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ return mInjector.binderWithCleanCallingIdentity(() -> getUserData(userHandle));
}
void removeUserData(int userHandle) {
@@ -2691,8 +2691,7 @@
alarmTime = now + alarmInterval;
}
- long token = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
int affectedUserHandle = parent ? getProfileParentId(userHandle) : userHandle;
AlarmManager am = mInjector.getAlarmManager();
PendingIntent pi = PendingIntent.getBroadcastAsUser(context, REQUEST_EXPIRE_PASSWORD,
@@ -2703,9 +2702,7 @@
if (alarmTime != 0) {
am.set(AlarmManager.RTC, alarmTime, pi);
}
- } finally {
- mInjector.binderRestoreCallingIdentity(token);
- }
+ });
}
ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle) {
@@ -3269,12 +3266,8 @@
private void sendChangedNotification(int userHandle) {
Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- long ident = mInjector.binderClearCallingIdentity();
- try {
- mContext.sendBroadcastAsUser(intent, new UserHandle(userHandle));
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ mInjector.binderWithCleanCallingIdentity(() ->
+ mContext.sendBroadcastAsUser(intent, new UserHandle(userHandle)));
}
private void loadSettingsLocked(DevicePolicyData policy, int userHandle) {
@@ -3842,8 +3835,7 @@
/* throwForMissingPermission= */ true);
synchronized (getLockObject()) {
checkActiveAdminPrecondition(adminReceiver, info, policy);
- long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
final ActiveAdmin existingAdmin
= getActiveAdminUncheckedLocked(adminReceiver, userHandle);
if (!refreshing && existingAdmin != null) {
@@ -3874,9 +3866,7 @@
saveSettingsLocked(userHandle);
sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED,
onEnableData, null);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
}
@@ -4058,8 +4048,7 @@
}
Preconditions.checkNotNull(adminReceiver, "ComponentName is null");
enforceShell("forceRemoveActiveAdmin");
- long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
synchronized (getLockObject()) {
if (!isAdminTestOnlyLocked(adminReceiver, userHandle)) {
throw new SecurityException("Attempt to remove non-test admin "
@@ -4079,9 +4068,7 @@
// Remove the admin skipping sending the broadcast.
removeAdminArtifacts(adminReceiver, userHandle);
Slog.i(LOG_TAG, "Admin " + adminReceiver + " removed from user " + userHandle);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
private void clearDeviceOwnerUserRestrictionLocked(UserHandle userHandle) {
@@ -4156,12 +4143,8 @@
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
}
- long ident = mInjector.binderClearCallingIdentity();
- try {
- removeActiveAdminLocked(adminReceiver, userHandle);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ mInjector.binderWithCleanCallingIdentity(() ->
+ removeActiveAdminLocked(adminReceiver, userHandle));
}
}
@@ -4187,8 +4170,7 @@
synchronized (getLockObject()) {
ActiveAdmin ap = getActiveAdminForCallerLocked(
who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
final PasswordPolicy passwordPolicy = ap.mPasswordPolicy;
if (passwordPolicy.quality != quality) {
passwordPolicy.quality = quality;
@@ -4198,9 +4180,7 @@
saveSettingsLocked(userId);
}
maybeLogPasswordComplexitySet(who, userId, parent, passwordPolicy);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_PASSWORD_QUALITY)
@@ -4387,12 +4367,8 @@
}
private boolean isSeparateProfileChallengeEnabled(int userHandle) {
- long ident = mInjector.binderClearCallingIdentity();
- try {
- return mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ return mInjector.binderWithCleanCallingIdentity(() ->
+ mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle));
}
@Override
@@ -5129,12 +5105,7 @@
}
private UserInfo getUserInfo(@UserIdInt int userId) {
- final long token = mInjector.binderClearCallingIdentity();
- try {
- return mUserManager.getUserInfo(userId);
- } finally {
- mInjector.binderRestoreCallingIdentity(token);
- }
+ return mInjector.binderWithCleanCallingIdentity(() -> mUserManager.getUserInfo(userId));
}
private boolean setPasswordPrivileged(@NonNull String password, int flags, int callingUid) {
@@ -5259,12 +5230,7 @@
}
private boolean isLockScreenSecureUnchecked(int userId) {
- long ident = mInjector.binderClearCallingIdentity();
- try {
- return mLockPatternUtils.isSecure(userId);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ return mInjector.binderWithCleanCallingIdentity(() -> mLockPatternUtils.isSecure(userId));
}
private void setDoNotAskCredentialsOnBoot() {
@@ -5316,12 +5282,10 @@
updateProfileLockTimeoutLocked(userId);
}
- final long timeMs;
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
// Update the device timeout
final int parentId = getProfileParentId(userId);
- timeMs = getMaximumTimeToLockPolicyFromAdmins(
+ final long timeMs = getMaximumTimeToLockPolicyFromAdmins(
getActiveAdminsForLockscreenPoliciesLocked(parentId, false));
final DevicePolicyData policy = getUserDataUnchecked(parentId);
@@ -5337,9 +5301,7 @@
}
getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
UserHandle.USER_SYSTEM, timeMs);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
private void updateProfileLockTimeoutLocked(@UserIdInt int userId) {
@@ -5357,13 +5319,9 @@
}
policy.mLastMaximumTimeToLock = timeMs;
- final long ident = mInjector.binderClearCallingIdentity();
- try {
- getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
- userId, policy.mLastMaximumTimeToLock);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ mInjector.binderWithCleanCallingIdentity(() ->
+ getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
+ userId, policy.mLastMaximumTimeToLock));
}
@Override
@@ -5631,24 +5589,21 @@
}
enforceCanManageCaCerts(admin, callerPackage);
- final String alias;
-
final UserHandle userHandle = mInjector.binderGetCallingUserHandle();
- final long id = mInjector.binderClearCallingIdentity();
- try {
- alias = mCertificateMonitor.installCaCert(userHandle, certBuffer);
+ final String alias = mInjector.binderWithCleanCallingIdentity(() -> {
+ String installedAlias = mCertificateMonitor.installCaCert(userHandle, certBuffer);
final boolean isDelegate = (admin == null);
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.INSTALL_CA_CERT)
.setAdmin(callerPackage)
.setBoolean(isDelegate)
.write();
- if (alias == null) {
- Log.w(LOG_TAG, "Problem installing cert");
- return false;
- }
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
+ return installedAlias;
+ });
+
+ if (alias == null) {
+ Log.w(LOG_TAG, "Problem installing cert");
+ return false;
}
synchronized (getLockObject()) {
@@ -5666,8 +5621,7 @@
enforceCanManageCaCerts(admin, callerPackage);
final int userId = mInjector.userHandleGetCallingUserId();
- final long id = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
mCertificateMonitor.uninstallCaCerts(UserHandle.of(userId), aliases);
final boolean isDelegate = (admin == null);
DevicePolicyEventLogger
@@ -5675,9 +5629,7 @@
.setAdmin(callerPackage)
.setBoolean(isDelegate)
.write();
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ });
synchronized (getLockObject()) {
if (getUserData(userId).mOwnerInstalledCaCerts.removeAll(Arrays.asList(aliases))) {
@@ -6081,8 +6033,7 @@
isDelegate = false;
}
- final long id = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
mContext.sendOrderedBroadcastAsUser(intent, caller, null, new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -6095,9 +6046,7 @@
.setAdmin(intent.getComponent())
.setBoolean(isDelegate)
.write();
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ });
}
private void sendPrivateKeyAliasResponse(final String alias, final IBinder responseBinder) {
@@ -6513,8 +6462,7 @@
enforceProfileOrDeviceOwner(admin);
final int userId = mInjector.userHandleGetCallingUserId();
- final long token = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
if (vpnPackage != null && !isPackageInstalledForUser(vpnPackage, userId)) {
Slog.w(LOG_TAG, "Non-existent VPN package specified: " + vpnPackage);
throw new ServiceSpecificException(
@@ -6542,9 +6490,7 @@
.setBoolean(lockdown)
.setInt(lockdownWhitelist != null ? lockdownWhitelist.size() : 0)
.write();
- } finally {
- mInjector.binderRestoreCallingIdentity(token);
- }
+ });
return true;
}
@@ -6553,12 +6499,8 @@
enforceProfileOrDeviceOwner(admin);
final int userId = mInjector.userHandleGetCallingUserId();
- final long token = mInjector.binderClearCallingIdentity();
- try {
- return mInjector.getConnectivityManager().getAlwaysOnVpnPackageForUser(userId);
- } finally {
- mInjector.binderRestoreCallingIdentity(token);
- }
+ return mInjector.binderWithCleanCallingIdentity(
+ () -> mInjector.getConnectivityManager().getAlwaysOnVpnPackageForUser(userId));
}
@Override
@@ -6566,12 +6508,8 @@
enforceProfileOrDeviceOwner(admin);
final int userId = mInjector.userHandleGetCallingUserId();
- final long token = mInjector.binderClearCallingIdentity();
- try {
- return mInjector.getConnectivityManager().isVpnLockdownEnabled(userId);
- } finally {
- mInjector.binderRestoreCallingIdentity(token);
- }
+ return mInjector.binderWithCleanCallingIdentity(
+ () -> mInjector.getConnectivityManager().isVpnLockdownEnabled(userId));
}
@Override
@@ -6580,12 +6518,8 @@
enforceProfileOrDeviceOwner(admin);
final int userId = mInjector.userHandleGetCallingUserId();
- final long token = mInjector.binderClearCallingIdentity();
- try {
- return mInjector.getConnectivityManager().getVpnLockdownWhitelist(userId);
- } finally {
- mInjector.binderRestoreCallingIdentity(token);
- }
+ return mInjector.binderWithCleanCallingIdentity(
+ () -> mInjector.getConnectivityManager().getVpnLockdownWhitelist(userId));
}
private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason, boolean wipeEuicc) {
@@ -6682,8 +6616,7 @@
// control over the device, wiping only the work profile. So the user restriction
// on profile removal needs to be removed first.
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
// Clear restriction as user.
mUserManager.setUserRestriction(
UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, false,
@@ -6691,9 +6624,7 @@
// Device-wide policies set by the profile owner need to be cleaned up here.
mLockPatternUtils.setDeviceOwnerInfo(null);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
}
@@ -6715,8 +6646,7 @@
String wipeReasonForUser, int userId) {
wtfIfInLock();
- long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
// First check whether the admin is allowed to wipe the device/user/profile.
final String restriction;
if (userId == UserHandle.USER_SYSTEM) {
@@ -6750,9 +6680,7 @@
} else {
forceWipeUser(userId, wipeReasonForUser, (flags & WIPE_SILENTLY) != 0);
}
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
private void sendWipeProfileNotification(String wipeReasonForUser) {
@@ -6927,8 +6855,7 @@
synchronized (getLockObject()) {
DevicePolicyData policy = getUserData(userHandle);
if (policy.mFailedPasswordAttempts != 0 || policy.mPasswordOwner >= 0) {
- long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
policy.mFailedPasswordAttempts = 0;
policy.mPasswordOwner = -1;
saveSettingsLocked(userHandle);
@@ -6937,9 +6864,7 @@
DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED,
DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
}
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
}
@@ -7038,12 +6963,7 @@
// Reset the global proxy accordingly
// Do this using system permissions, as apps cannot write to secure settings
- long origId = mInjector.binderClearCallingIdentity();
- try {
- resetGlobalProxyLocked(policy);
- } finally {
- mInjector.binderRestoreCallingIdentity(origId);
- }
+ mInjector.binderWithCleanCallingIdentity(() -> resetGlobalProxyLocked(policy));
return null;
}
}
@@ -7075,12 +6995,8 @@
@Override
public void setRecommendedGlobalProxy(ComponentName who, ProxyInfo proxyInfo) {
enforceDeviceOwner(who);
- long token = mInjector.binderClearCallingIdentity();
- try {
- mInjector.getConnectivityManager().setGlobalProxy(proxyInfo);
- } finally {
- mInjector.binderRestoreCallingIdentity(token);
- }
+ mInjector.binderWithCleanCallingIdentity(
+ () -> mInjector.getConnectivityManager().setGlobalProxy(proxyInfo));
}
private void resetGlobalProxyLocked(DevicePolicyData policy) {
@@ -7372,12 +7288,9 @@
// TODO: (b/145604635) Add upgrade case
// Turn AUTO_TIME on in settings if it is required
if (required) {
- long ident = mInjector.binderClearCallingIdentity();
- try {
- mInjector.settingsGlobalPutInt(Settings.Global.AUTO_TIME, 1 /* AUTO_TIME on */);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ mInjector.binderWithCleanCallingIdentity(
+ () -> mInjector.settingsGlobalPutInt(Settings.Global.AUTO_TIME,
+ 1 /* AUTO_TIME on */));
}
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_AUTO_TIME_REQUIRED)
@@ -7508,12 +7421,7 @@
}
}
if (removeAllUsers) {
- long identitity = mInjector.binderClearCallingIdentity();
- try {
- mUserManagerInternal.removeAllUsers();
- } finally {
- mInjector.binderRestoreCallingIdentity(identitity);
- }
+ mInjector.binderWithCleanCallingIdentity(() -> mUserManagerInternal.removeAllUsers());
}
}
@@ -8026,13 +7934,10 @@
updateDeviceOwnerLocked();
setDeviceOwnerSystemPropertyLocked();
- long ident = mInjector.binderClearCallingIdentity();
- try {
- // TODO Send to system too?
- sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED, userId);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ // TODO Send to system too?
+ mInjector.binderWithCleanCallingIdentity(
+ () -> sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED,
+ userId));
mDeviceAdminServiceController.startServiceForOwner(
admin.getPackageName(), userId, "set-device-owner");
@@ -8213,15 +8118,12 @@
}
final ActiveAdmin admin = getDeviceOwnerAdminLocked();
- long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
clearDeviceOwnerLocked(admin, deviceOwnerUserId);
removeActiveAdminLocked(deviceOwnerComponent, deviceOwnerUserId);
sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED,
deviceOwnerUserId);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
Slog.i(LOG_TAG, "Device owner removed: " + deviceOwnerComponent);
}
}
@@ -8307,8 +8209,7 @@
mOwners.writeProfileOwner(userHandle);
Slog.i(LOG_TAG, "Profile owner set: " + who + " on user " + userHandle);
- final long id = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
if (mUserManager.isManagedProfile(userHandle)) {
maybeSetDefaultRestrictionsForAdminLocked(userHandle, admin,
UserRestrictionsUtils.getDefaultEnabledForManagedProfiles());
@@ -8317,9 +8218,7 @@
}
sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_PROFILE_OWNER_CHANGED,
userHandle);
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ });
mDeviceAdminServiceController.startServiceForOwner(
who.getPackageName(), userHandle, "set-profile-owner");
return true;
@@ -8357,15 +8256,12 @@
final ActiveAdmin admin =
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
clearProfileOwnerLocked(admin, userId);
removeActiveAdminLocked(who, userId);
sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_PROFILE_OWNER_CHANGED,
userId);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
Slog.i(LOG_TAG, "Profile owner " + who + " removed from user " + userId);
}
}
@@ -8574,8 +8470,7 @@
"setProfileEnabled is called when the profile is already enabled");
return;
}
- long id = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
mUserManager.setUserEnabled(userId);
UserInfo parent = mUserManager.getProfileParent(userId);
Intent intent = new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED);
@@ -8583,9 +8478,7 @@
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
Intent.FLAG_RECEIVER_FOREGROUND);
mContext.sendBroadcastAsUser(intent, new UserHandle(parent.id));
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ });
}
}
@@ -8595,16 +8488,13 @@
enforceProfileOrDeviceOwner(who);
final int userId = UserHandle.getCallingUserId();
- final long id = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
mUserManager.setUserName(userId, profileName);
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_PROFILE_NAME)
.setAdmin(who)
.write();
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ });
}
@Override
@@ -8646,8 +8536,7 @@
@GuardedBy("getLockObject()")
ActiveAdmin getProfileOwnerOfOrganizationOwnedDeviceLocked(int userHandle) {
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
if (userInfo.isManagedProfile()) {
if (getProfileOwner(userInfo.id) != null
@@ -8657,10 +8546,8 @@
}
}
}
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
- return null;
+ return null;
+ });
}
@Override
@@ -8763,8 +8650,7 @@
* Canonical name for a given package.
*/
private String getApplicationLabel(String packageName, int userHandle) {
- long token = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
final Context userContext;
try {
UserHandle handle = new UserHandle(userHandle);
@@ -8779,9 +8665,7 @@
result = appInfo.loadUnsafeLabel(userContext.getPackageManager());
}
return result != null ? result.toString() : null;
- } finally {
- mInjector.binderRestoreCallingIdentity(token);
- }
+ });
}
/**
@@ -9072,28 +8956,23 @@
}
protected int getProfileParentId(int userHandle) {
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
UserInfo parentUser = mUserManager.getProfileParent(userHandle);
return parentUser != null ? parentUser.id : userHandle;
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
- private int getCredentialOwner(int userHandle, boolean parent) {
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ private int getCredentialOwner(final int userHandle, final boolean parent) {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
+ int effectiveUserHandle = userHandle;
if (parent) {
UserInfo parentProfile = mUserManager.getProfileParent(userHandle);
if (parentProfile != null) {
- userHandle = parentProfile.id;
+ effectiveUserHandle = parentProfile.id;
}
}
- return mUserManager.getCredentialOwnerProfile(userHandle);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ return mUserManager.getCredentialOwnerProfile(effectiveUserHandle);
+ });
}
private boolean isManagedProfile(int userHandle) {
@@ -9280,8 +9159,7 @@
DELEGATION_APP_RESTRICTIONS);
final UserHandle userHandle = mInjector.binderGetCallingUserHandle();
- final long id = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
mUserManager.setApplicationRestrictions(packageName, settings, userHandle);
final boolean isDelegate = (who == null);
DevicePolicyEventLogger
@@ -9290,9 +9168,7 @@
.setBoolean(isDelegate)
.setStrings(packageName)
.write();
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ });
}
@Override
@@ -10035,8 +9911,7 @@
enforceDeviceOwner(who);
final int callingUserId = mInjector.userHandleGetCallingUserId();
- final long id = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
String restriction = isManagedProfile(userHandle.getIdentifier())
? UserManager.DISALLOW_REMOVE_MANAGED_PROFILE
: UserManager.DISALLOW_REMOVE_USER;
@@ -10046,9 +9921,7 @@
return false;
}
return mUserManagerInternal.removeUserEvenWhenDisallowed(userHandle.getIdentifier());
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ });
}
private boolean isAdminAffectedByRestriction(
@@ -10194,8 +10067,7 @@
Preconditions.checkNotNull(who, "ComponentName is null");
enforceDeviceOwner(who);
- final long id = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
final List<UserInfo> userInfos = mInjector.getUserManager().getUsers(true
/*excludeDying*/);
final List<UserHandle> userHandles = new ArrayList<>();
@@ -10206,9 +10078,7 @@
}
}
return userHandles;
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ });
}
@Override
@@ -10217,12 +10087,8 @@
enforceProfileOrDeviceOwner(who);
final int callingUserId = mInjector.userHandleGetCallingUserId();
- final long id = mInjector.binderClearCallingIdentity();
- try {
- return mInjector.getUserManager().isUserEphemeral(callingUserId);
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ return mInjector.binderWithCleanCallingIdentity(
+ () -> mInjector.getUserManager().isUserEphemeral(callingUserId));
}
@Override
@@ -10232,15 +10098,12 @@
DELEGATION_APP_RESTRICTIONS);
final UserHandle userHandle = mInjector.binderGetCallingUserHandle();
- final long id = mInjector.binderClearCallingIdentity();
- try {
- Bundle bundle = mUserManager.getApplicationRestrictions(packageName, userHandle);
+ return mInjector.binderWithCleanCallingIdentity(() -> {
+ Bundle bundle = mUserManager.getApplicationRestrictions(packageName, userHandle);
// if no restrictions were saved, mUserManager.getApplicationRestrictions
// returns null, but DPM method should return an empty Bundle as per JavaDoc
return bundle != null ? bundle : Bundle.EMPTY;
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ });
}
@Override
@@ -10865,8 +10728,7 @@
actualContactId, isContactIdIgnored, actualDirectoryId, originalIntent);
final int callingUserId = UserHandle.getCallingUserId();
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
synchronized (getLockObject()) {
final int managedUserId = getManagedUserId(callingUserId);
if (managedUserId < 0) {
@@ -10882,9 +10744,7 @@
ContactsInternal.startQuickContactWithErrorToastForUser(
mContext, intent, new UserHandle(managedUserId));
}
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
/**
@@ -11044,8 +10904,7 @@
}
private void maybeClearLockTaskPolicyLocked() {
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
final List<UserInfo> userInfos = mUserManager.getUsers(/*excludeDying=*/ true);
for (int i = userInfos.size() - 1; i >= 0; i--) {
int userId = userInfos.get(i).id;
@@ -11066,9 +10925,7 @@
setLockTaskFeaturesLocked(userId, DevicePolicyManager.LOCK_TASK_FEATURE_NONE);
}
}
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
@Override
@@ -11141,12 +10998,8 @@
}
}
- long id = mInjector.binderClearCallingIdentity();
- try {
- mInjector.settingsGlobalPutString(setting, value);
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ mInjector.binderWithCleanCallingIdentity(
+ () -> mInjector.settingsGlobalPutString(setting, value));
}
}
@@ -11266,8 +11119,7 @@
}
return;
}
- long id = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
if (Settings.Secure.DEFAULT_INPUT_METHOD.equals(setting)) {
final String currentValue = mInjector.settingsSecureGetStringForUser(
Settings.Secure.DEFAULT_INPUT_METHOD, callingUserId);
@@ -11283,9 +11135,7 @@
saveSettingsLocked(callingUserId);
}
mInjector.settingsSecurePutStringForUser(setting, value, callingUserId);
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ });
}
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_SECURE_SETTING)
@@ -11327,12 +11177,8 @@
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
int userId = UserHandle.getCallingUserId();
- long id = mInjector.binderClearCallingIdentity();
- try {
- mUserManagerInternal.setUserIcon(userId, icon);
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ mInjector.binderWithCleanCallingIdentity(
+ () -> mUserManagerInternal.setUserIcon(userId, icon));
}
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_USER_ICON)
@@ -11731,15 +11577,12 @@
@Override
public void reportSeparateProfileChallengeChanged(@UserIdInt int userId) {
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
synchronized (getLockObject()) {
updateMaximumTimeToLockLocked(userId);
updatePasswordQualityCacheForUserGroup(userId);
}
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SEPARATE_PROFILE_CHALLENGE_CHANGED)
.setBoolean(isSeparateProfileChallengeEnabled(userId))
@@ -12031,8 +11874,7 @@
.putExtra(DeviceAdminReceiver.EXTRA_SYSTEM_UPDATE_RECEIVED_TIME,
info == null ? -1 : info.getReceivedTime());
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
synchronized (getLockObject()) {
// Broadcast to device owner first if there is one.
if (mOwners.hasDeviceOwner()) {
@@ -12062,9 +11904,7 @@
}
}
}
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
@Override
@@ -12188,8 +12028,7 @@
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, DELEGATION_PERMISSION_GRANT);
}
synchronized (getLockObject()) {
- long ident = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
int granted;
if (getTargetSdk(callerPackage, user.getIdentifier())
< android.os.Build.VERSION_CODES.Q) {
@@ -12224,9 +12063,7 @@
? DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
: DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED;
}
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
}
@@ -12466,8 +12303,7 @@
// Make sure caller has DO.
enforceDeviceOwnerOrProfileOwnerOnOrganizationOwnedDevice(admin);
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
String[] macAddresses = mInjector.getWifiManager().getFactoryMacAddresses();
if (macAddresses == null) {
return null;
@@ -12477,9 +12313,7 @@
.setAdmin(admin)
.write();
return macAddresses.length > 0 ? macAddresses[0] : null;
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
/**
@@ -12515,8 +12349,7 @@
Preconditions.checkNotNull(admin);
// Make sure caller has DO.
enforceDeviceOwner(admin);
- long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
// Make sure there are no ongoing calls on the device.
if (mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
throw new IllegalStateException("Cannot be called with ongoing call on the device");
@@ -12526,9 +12359,7 @@
.setAdmin(admin)
.write();
mInjector.powerManagerReboot(PowerManager.REBOOT_REQUESTED_BY_DEVICE_OWNER);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
@Override
@@ -12765,17 +12596,14 @@
final ActiveAdmin admin = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
final int callingUserId = mInjector.userHandleGetCallingUserId();
- final long identity = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
final List<String> excludedPkgs
= removeInvalidPkgsForMeteredDataRestriction(callingUserId, packageNames);
admin.meteredDisabledPackages = packageNames;
pushMeteredDisabledPackagesLocked(callingUserId);
saveSettingsLocked(callingUserId);
return excludedPkgs;
- } finally {
- mInjector.binderRestoreCallingIdentity(identity);
- }
+ });
}
}
@@ -12888,8 +12716,7 @@
who.flattenToString(), userId));
// First, set restriction on removing the profile.
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
// Clear restriction as user.
UserHandle parentUser = mUserManager.getProfileParent(UserHandle.of(userId));
if (!parentUser.isSystem()) {
@@ -12901,9 +12728,7 @@
mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, true,
parentUser);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
// markProfileOwnerOfOrganizationOwnedDevice will trigger writing of the profile owner
// data, no need to do it manually.
@@ -13021,8 +12846,7 @@
}
private boolean areAllUsersAffiliatedWithDeviceLocked() {
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
final List<UserInfo> userInfos = mUserManager.getUsers(/*excludeDying=*/ true);
for (int i = 0; i < userInfos.size(); i++) {
int userId = userInfos.get(i).id;
@@ -13031,11 +12855,8 @@
return false;
}
}
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
-
- return true;
+ return true;
+ });
}
@Override
@@ -13245,12 +13066,8 @@
private boolean isCurrentUserDemo() {
if (UserManager.isDeviceInDemoMode(mContext)) {
final int userId = mInjector.userHandleGetCallingUserId();
- final long callingIdentity = mInjector.binderClearCallingIdentity();
- try {
- return mUserManager.getUserInfo(userId).isDemo();
- } finally {
- mInjector.binderRestoreCallingIdentity(callingIdentity);
- }
+ return mInjector.binderWithCleanCallingIdentity(
+ () -> mUserManager.getUserInfo(userId).isDemo());
}
return false;
}
@@ -13466,8 +13283,7 @@
getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
final int callingUserId = mInjector.userHandleGetCallingUserId();
- final long callingIdentity = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
ArrayList<UserHandle> targetUsers = new ArrayList<>();
if (!isDeviceOwner(admin, callingUserId)) {
// Profile owners can only bind to the device owner.
@@ -13486,9 +13302,7 @@
}
return targetUsers;
- } finally {
- mInjector.binderRestoreCallingIdentity(callingIdentity);
- }
+ });
}
}
@@ -13529,8 +13343,7 @@
}
wtfIfInLock();
- final long token = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
final AccountManager am = AccountManager.get(mContext);
final Account accounts[] = am.getAccountsAsUser(userId);
if (accounts.length == 0) {
@@ -13568,9 +13381,7 @@
Log.e(LOG_TAG, "Found incompatible accounts");
}
return !compatible;
- } finally {
- mInjector.binderRestoreCallingIdentity(token);
- }
+ });
}
private boolean hasAccountFeatures(AccountManager am, Account account, String[] features) {
@@ -13623,8 +13434,7 @@
private void setNetworkLoggingActiveInternal(boolean active) {
synchronized (getLockObject()) {
- final long callingIdentity = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
if (active) {
mNetworkLogger = new NetworkLogger(this, mInjector.getPackageManagerInternal());
if (!mNetworkLogger.startNetworkLogging()) {
@@ -13642,9 +13452,7 @@
mNetworkLogger = null;
mInjector.getNotificationManager().cancel(SystemMessage.NOTE_NETWORK_LOGGING);
}
- } finally {
- mInjector.binderRestoreCallingIdentity(callingIdentity);
- }
+ });
}
}
@@ -13656,12 +13464,8 @@
throw new IllegalStateException("logging is not available");
}
if (mNetworkLogger != null) {
- final long ident = mInjector.binderClearCallingIdentity();
- try {
- return mNetworkLogger.forceBatchFinalization();
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ return mInjector.binderWithCleanCallingIdentity(
+ () -> mNetworkLogger.forceBatchFinalization());
}
return 0;
}
@@ -13684,15 +13488,12 @@
@GuardedBy("getLockObject()")
private void maybeResumeDeviceWideLoggingLocked() {
if (areAllUsersAffiliatedWithDeviceLocked()) {
- final long ident = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
mSecurityLogMonitor.resume();
if (mNetworkLogger != null) {
mNetworkLogger.resume();
}
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
}
@@ -13881,8 +13682,7 @@
getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
DevicePolicyData policy = getUserData(userHandle);
- long ident = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
if (policy.mPasswordTokenHandle != 0) {
mLockPatternUtils.removeEscrowToken(policy.mPasswordTokenHandle, userHandle);
}
@@ -13890,9 +13690,7 @@
userHandle, /*EscrowTokenStateChangeCallback*/ null);
saveSettingsLocked(userHandle);
return policy.mPasswordTokenHandle != 0;
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
}
@@ -13907,16 +13705,13 @@
DevicePolicyData policy = getUserData(userHandle);
if (policy.mPasswordTokenHandle != 0) {
- long ident = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
boolean result = mLockPatternUtils.removeEscrowToken(
policy.mPasswordTokenHandle, userHandle);
policy.mPasswordTokenHandle = 0;
saveSettingsLocked(userHandle);
return result;
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ });
}
}
return false;
@@ -13933,13 +13728,9 @@
DevicePolicyData policy = getUserData(userHandle);
if (policy.mPasswordTokenHandle != 0) {
- long ident = mInjector.binderClearCallingIdentity();
- try {
- return mLockPatternUtils.isEscrowTokenActive(policy.mPasswordTokenHandle,
- userHandle);
- } finally {
- mInjector.binderRestoreCallingIdentity(ident);
- }
+ return mInjector.binderWithCleanCallingIdentity(
+ () -> mLockPatternUtils.isEscrowTokenActive(policy.mPasswordTokenHandle,
+ userHandle));
}
}
return false;
@@ -14309,13 +14100,8 @@
enforceDeviceOwner(who);
int operatedId = -1;
- Uri resultUri;
- final long id = mInjector.binderClearCallingIdentity();
- try {
- resultUri = mContext.getContentResolver().insert(DPC_URI, apnSetting.toContentValues());
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ Uri resultUri = mInjector.binderWithCleanCallingIdentity(() ->
+ mContext.getContentResolver().insert(DPC_URI, apnSetting.toContentValues()));
if (resultUri != null) {
try {
operatedId = Integer.parseInt(resultUri.getLastPathSegment());
@@ -14340,14 +14126,10 @@
if (apnId < 0) {
return false;
}
- final long id = mInjector.binderClearCallingIdentity();
- try {
- return mContext.getContentResolver().update(
- Uri.withAppendedPath(DPC_URI, Integer.toString(apnId)),
- apnSetting.toContentValues(), null, null) > 0;
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ return mInjector.binderWithCleanCallingIdentity(() ->
+ mContext.getContentResolver().update(
+ Uri.withAppendedPath(DPC_URI, Integer.toString(apnId)),
+ apnSetting.toContentValues(), null, null) > 0);
}
@Override
@@ -14365,14 +14147,9 @@
if(apnId < 0) {
return false;
}
- int numDeleted = 0;
- final long id = mInjector.binderClearCallingIdentity();
- try {
- numDeleted = mContext.getContentResolver().delete(
- Uri.withAppendedPath(DPC_URI, Integer.toString(apnId)), null, null);
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ int numDeleted = mInjector.binderWithCleanCallingIdentity(
+ () -> mContext.getContentResolver().delete(
+ Uri.withAppendedPath(DPC_URI, Integer.toString(apnId)), null, null));
return numDeleted > 0;
}
@@ -14388,13 +14165,8 @@
}
private List<ApnSetting> getOverrideApnsUnchecked() {
- final Cursor cursor;
- final long id = mInjector.binderClearCallingIdentity();
- try {
- cursor = mContext.getContentResolver().query(DPC_URI, null, null, null, null);
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ final Cursor cursor = mInjector.binderWithCleanCallingIdentity(
+ () -> mContext.getContentResolver().query(DPC_URI, null, null, null, null));
if (cursor == null) {
return Collections.emptyList();
@@ -14426,13 +14198,8 @@
private void setOverrideApnsEnabledUnchecked(boolean enabled) {
ContentValues value = new ContentValues();
value.put(ENFORCE_KEY, enabled);
- final long id = mInjector.binderClearCallingIdentity();
- try {
- mContext.getContentResolver().update(
- ENFORCE_MANAGED_URI, value, null, null);
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ mInjector.binderWithCleanCallingIdentity(() -> mContext.getContentResolver().update(
+ ENFORCE_MANAGED_URI, value, null, null));
}
@Override
@@ -14443,14 +14210,9 @@
Preconditions.checkNotNull(who, "ComponentName is null in isOverrideApnEnabled");
enforceDeviceOwner(who);
- Cursor enforceCursor;
- final long id = mInjector.binderClearCallingIdentity();
- try {
- enforceCursor = mContext.getContentResolver().query(
- ENFORCE_MANAGED_URI, null, null, null, null);
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ Cursor enforceCursor = mInjector.binderWithCleanCallingIdentity(
+ () -> mContext.getContentResolver().query(
+ ENFORCE_MANAGED_URI, null, null, null, null));
if (enforceCursor == null) {
return false;
@@ -14517,13 +14279,10 @@
private void putPrivateDnsSettings(@Nullable String mode, @Nullable String host) {
// Set Private DNS settings using system permissions, as apps cannot write
// to global settings.
- long origId = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
mInjector.settingsGlobalPutString(PRIVATE_DNS_MODE, mode);
mInjector.settingsGlobalPutString(PRIVATE_DNS_SPECIFIER, host);
- } finally {
- mInjector.binderRestoreCallingIdentity(origId);
- }
+ });
}
@Override
@@ -14609,8 +14368,7 @@
.setBoolean(isDeviceAB())
.write();
enforceDeviceOwner(admin);
- final long id = mInjector.binderClearCallingIdentity();
- try {
+ mInjector.binderWithCleanCallingIdentity(() -> {
UpdateInstaller updateInstaller;
if (isDeviceAB()) {
updateInstaller = new AbUpdateInstaller(
@@ -14620,9 +14378,7 @@
mContext, updateFileDescriptor, callback, mInjector, mConstants);
}
updateInstaller.startInstallUpdate();
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
- }
+ });
}
private boolean isDeviceAB() {
@@ -14823,8 +14579,7 @@
throw new SecurityException("Input package name doesn't align with actual "
+ "calling package.");
}
- final long identity = mInjector.binderClearCallingIdentity();
- try {
+ return mInjector.binderWithCleanCallingIdentity(() -> {
final int workProfileUserId = getManagedUserId(callingUserId);
if (workProfileUserId < 0) {
return false;
@@ -14848,10 +14603,8 @@
Log.e(LOG_TAG, "View event activity not found", e);
return false;
}
- } finally {
- mInjector.binderRestoreCallingIdentity(identity);
- }
- return true;
+ return true;
+ });
}
private boolean isCallingFromPackage(String packageName, int callingUid) {
diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp
new file mode 100644
index 0000000..2661925
--- /dev/null
+++ b/services/incremental/Android.bp
@@ -0,0 +1,110 @@
+// Copyright 2019, 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.
+
+cc_defaults {
+ name: "service.incremental-proto-defaults",
+
+ cpp_std: "c++2a",
+ proto: {
+ type: "lite",
+ },
+}
+
+cc_defaults {
+ name: "service.incremental-defaults",
+ defaults: ["service.incremental-proto-defaults"],
+ local_include_dirs: ["include/"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ "-Wno-unused-parameter",
+ ],
+
+ static_libs: [
+ "libbase",
+ "libext2_uuid",
+ "libdataloader_aidl-cpp",
+ "libincremental_aidl-cpp",
+ "libincremental_manager_aidl-cpp",
+ "libnativehelper",
+ "libprotobuf-cpp-lite",
+ "service.incremental.proto",
+ "libutils",
+ "libvold_binder",
+ ],
+ shared_libs: [
+ "libandroidfw",
+ "libbinder",
+ "libincfs",
+ "liblog",
+ "libz",
+ "libziparchive",
+ ],
+}
+
+filegroup {
+ name: "service.incremental_srcs",
+ srcs: [
+ "incremental_service.c",
+ "IncrementalService.cpp",
+ "BinderIncrementalService.cpp",
+ "path.cpp",
+ "ServiceWrappers.cpp",
+ ],
+}
+
+cc_library {
+ name: "service.incremental",
+ defaults: [
+ "service.incremental-defaults",
+ "linux_bionic_supported",
+ ],
+
+ export_include_dirs: ["include/",],
+ srcs: [
+ ":service.incremental_srcs",
+ ],
+}
+
+cc_library_headers {
+ name: "service.incremental_headers",
+ export_include_dirs: ["include/",],
+}
+
+cc_library_static {
+ name: "service.incremental.proto",
+ defaults: ["service.incremental-proto-defaults"],
+ proto: {
+ export_proto_headers: true,
+ },
+
+ srcs: [
+ "Metadata.proto",
+ ],
+}
+
+cc_test {
+ name: "service.incremental_test",
+ defaults: ["service.incremental-defaults"],
+ test_suites: ["device-tests"],
+ srcs: [
+ ":service.incremental_srcs",
+ "test/IncrementalServiceTest.cpp",
+ "test/path_test.cpp",
+ ],
+ static_libs: [
+ "libgmock",
+ ]
+}
diff --git a/services/incremental/BinderIncrementalService.cpp b/services/incremental/BinderIncrementalService.cpp
new file mode 100644
index 0000000..bb26c1f
--- /dev/null
+++ b/services/incremental/BinderIncrementalService.cpp
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2019 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 "BinderIncrementalService.h"
+
+#include <binder/IResultReceiver.h>
+#include <incfs.h>
+
+#include "ServiceWrappers.h"
+#include "jni.h"
+#include "nativehelper/JNIHelp.h"
+#include "path.h"
+
+using namespace std::literals;
+using namespace android::incremental;
+
+namespace android::os::incremental {
+
+static constexpr auto kAndroidDataEnv = "ANDROID_DATA"sv;
+static constexpr auto kDataDir = "/data"sv;
+static constexpr auto kIncrementalSubDir = "incremental"sv;
+
+static std::string getIncrementalDir() {
+ const char* dataDir = getenv(kAndroidDataEnv.data());
+ if (!dataDir || !*dataDir) {
+ dataDir = kDataDir.data();
+ }
+ return path::normalize(path::join(dataDir, kIncrementalSubDir));
+}
+
+static bool incFsEnabled() {
+ // TODO(b/136132412): use vold to check /sys/fs/incfs/version (per selinux compliance)
+ return incfs::enabled();
+}
+
+static bool incFsVersionValid(const sp<IVold>& vold) {
+ int version = -1;
+ auto status = vold->incFsVersion(&version);
+ if (!status.isOk() || version <= 0) {
+ return false;
+ }
+ return true;
+}
+
+BinderIncrementalService::BinderIncrementalService(const sp<IServiceManager>& sm)
+ : mImpl(RealServiceManager(sm), getIncrementalDir()) {}
+
+BinderIncrementalService* BinderIncrementalService::start() {
+ if (!incFsEnabled()) {
+ return nullptr;
+ }
+
+ IPCThreadState::self()->disableBackgroundScheduling(true);
+ sp<IServiceManager> sm(defaultServiceManager());
+ if (!sm) {
+ return nullptr;
+ }
+
+ sp<IBinder> voldBinder(sm->getService(String16("vold")));
+ if (voldBinder == nullptr) {
+ return nullptr;
+ }
+ sp<IVold> vold = interface_cast<IVold>(voldBinder);
+ if (!incFsVersionValid(vold)) {
+ return nullptr;
+ }
+
+ sp<BinderIncrementalService> self(new BinderIncrementalService(sm));
+ status_t ret = sm->addService(String16{getServiceName()}, self);
+ if (ret != android::OK) {
+ return nullptr;
+ }
+ sp<ProcessState> ps(ProcessState::self());
+ ps->startThreadPool();
+ ps->giveThreadPoolName();
+ return self.get();
+}
+
+status_t BinderIncrementalService::dump(int fd, const Vector<String16>& args) {
+ return OK;
+}
+
+void BinderIncrementalService::onSystemReady() {
+ mImpl.onSystemReady();
+}
+
+static binder::Status ok() {
+ return binder::Status::ok();
+}
+
+binder::Status BinderIncrementalService::openStorage(const std::string& path,
+ int32_t* _aidl_return) {
+ *_aidl_return = mImpl.openStorage(path);
+ return ok();
+}
+
+binder::Status BinderIncrementalService::createStorage(
+ const std::string& path, const DataLoaderParamsParcel& params,
+ int32_t createMode, int32_t* _aidl_return) {
+ *_aidl_return =
+ mImpl.createStorage(path, const_cast<DataLoaderParamsParcel&&>(params),
+ android::incremental::IncrementalService::CreateOptions(
+ createMode));
+ return ok();
+}
+
+binder::Status BinderIncrementalService::createLinkedStorage(const std::string& path,
+ int32_t otherStorageId,
+ int32_t createMode,
+ int32_t* _aidl_return) {
+ *_aidl_return =
+ mImpl.createLinkedStorage(path, otherStorageId,
+ android::incremental::IncrementalService::CreateOptions(
+ createMode));
+ return ok();
+}
+
+binder::Status BinderIncrementalService::makeBindMount(int32_t storageId,
+ const std::string& pathUnderStorage,
+ const std::string& targetFullPath,
+ int32_t bindType, int32_t* _aidl_return) {
+ *_aidl_return = mImpl.bind(storageId, pathUnderStorage, targetFullPath,
+ android::incremental::IncrementalService::BindKind(bindType));
+ return ok();
+}
+
+binder::Status BinderIncrementalService::deleteBindMount(int32_t storageId,
+ const std::string& targetFullPath,
+ int32_t* _aidl_return) {
+ *_aidl_return = mImpl.unbind(storageId, targetFullPath);
+ return ok();
+}
+
+binder::Status BinderIncrementalService::deleteStorage(int32_t storageId) {
+ mImpl.deleteStorage(storageId);
+ return ok();
+}
+
+binder::Status BinderIncrementalService::makeDirectory(int32_t storageId,
+ const std::string& pathUnderStorage,
+ int32_t* _aidl_return) {
+ auto inode = mImpl.makeDir(storageId, pathUnderStorage);
+ *_aidl_return = inode < 0 ? inode : 0;
+ return ok();
+}
+
+binder::Status BinderIncrementalService::makeDirectories(int32_t storageId,
+ const std::string& pathUnderStorage,
+ int32_t* _aidl_return) {
+ auto inode = mImpl.makeDirs(storageId, pathUnderStorage);
+ *_aidl_return = inode < 0 ? inode : 0;
+ return ok();
+}
+
+binder::Status BinderIncrementalService::makeFile(int32_t storageId,
+ const std::string& pathUnderStorage, int64_t size,
+ const std::vector<uint8_t>& metadata,
+ int32_t* _aidl_return) {
+ auto inode = mImpl.makeFile(storageId, pathUnderStorage, size,
+ {(const char*)metadata.data(), metadata.size()}, {});
+ *_aidl_return = inode < 0 ? inode : 0;
+ return ok();
+}
+binder::Status BinderIncrementalService::makeFileFromRange(
+ int32_t storageId, const std::string& pathUnderStorage,
+ const std::string& sourcePathUnderStorage, int64_t start, int64_t end,
+ int32_t* _aidl_return) {
+ // TODO(b/136132412): implement this
+ *_aidl_return = -1;
+ return ok();
+}
+binder::Status BinderIncrementalService::makeLink(int32_t sourceStorageId,
+ const std::string& relativeSourcePath,
+ int32_t destStorageId,
+ const std::string& relativeDestPath,
+ int32_t* _aidl_return) {
+ auto sourceInode = mImpl.nodeFor(sourceStorageId, relativeSourcePath);
+ auto [targetParentInode, name] = mImpl.parentAndNameFor(destStorageId, relativeDestPath);
+ *_aidl_return = mImpl.link(sourceStorageId, sourceInode, targetParentInode, name);
+ return ok();
+}
+binder::Status BinderIncrementalService::unlink(int32_t storageId,
+ const std::string& pathUnderStorage,
+ int32_t* _aidl_return) {
+ auto [parentNode, name] = mImpl.parentAndNameFor(storageId, pathUnderStorage);
+ *_aidl_return = mImpl.unlink(storageId, parentNode, name);
+ return ok();
+}
+binder::Status BinderIncrementalService::isFileRangeLoaded(int32_t storageId,
+ const std::string& relativePath,
+ int64_t start, int64_t end,
+ bool* _aidl_return) {
+ *_aidl_return = false;
+ return ok();
+}
+binder::Status BinderIncrementalService::getFileMetadata(int32_t storageId,
+ const std::string& relativePath,
+ std::vector<uint8_t>* _aidl_return) {
+ auto inode = mImpl.nodeFor(storageId, relativePath);
+ auto metadata = mImpl.getMetadata(storageId, inode);
+ _aidl_return->assign(metadata.begin(), metadata.end());
+ return ok();
+}
+binder::Status BinderIncrementalService::startLoading(int32_t storageId, bool* _aidl_return) {
+ *_aidl_return = mImpl.startLoading(storageId);
+ return ok();
+}
+} // namespace android::os::incremental
+
+jlong Incremental_IncrementalService_Start() {
+ return (jlong)android::os::incremental::BinderIncrementalService::start();
+}
+void Incremental_IncrementalService_OnSystemReady(jlong self) {
+ if (self) {
+ ((android::os::incremental::BinderIncrementalService*)self)->onSystemReady();
+ }
+}
diff --git a/services/incremental/BinderIncrementalService.h b/services/incremental/BinderIncrementalService.h
new file mode 100644
index 0000000..37c9661d
--- /dev/null
+++ b/services/incremental/BinderIncrementalService.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <binder/BinderService.h>
+#include <binder/IServiceManager.h>
+
+#include "IncrementalService.h"
+#include "android/os/incremental/BnIncrementalManagerNative.h"
+#include "incremental_service.h"
+
+namespace android::os::incremental {
+
+class BinderIncrementalService : public BnIncrementalManagerNative,
+ public BinderService<BinderIncrementalService> {
+public:
+ BinderIncrementalService(const sp<IServiceManager> &sm);
+
+ static BinderIncrementalService *start();
+ static const char16_t *getServiceName() { return u"incremental_service"; }
+ status_t dump(int fd, const Vector<String16> &args) final;
+
+ void onSystemReady();
+ void onInvalidStorage(int mountId);
+
+ binder::Status openStorage(const std::string &path, int32_t *_aidl_return) final;
+ binder::Status createStorage(
+ const std::string &path,
+ const ::android::content::pm::DataLoaderParamsParcel ¶ms,
+ int32_t createMode, int32_t *_aidl_return) final;
+ binder::Status createLinkedStorage(const std::string &path, int32_t otherStorageId,
+ int32_t createMode, int32_t *_aidl_return) final;
+ binder::Status makeBindMount(int32_t storageId, const std::string &pathUnderStorage,
+ const std::string &targetFullPath, int32_t bindType,
+ int32_t *_aidl_return) final;
+ binder::Status deleteBindMount(int32_t storageId, const std::string &targetFullPath,
+ int32_t *_aidl_return) final;
+ binder::Status deleteStorage(int32_t storageId) final;
+ binder::Status makeDirectory(int32_t storageId, const std::string &pathUnderStorage,
+ int32_t *_aidl_return) final;
+ binder::Status makeDirectories(int32_t storageId, const std::string &pathUnderStorage,
+ int32_t *_aidl_return) final;
+ binder::Status makeFile(int32_t storageId, const std::string &pathUnderStorage, int64_t size,
+ const std::vector<uint8_t> &metadata, int32_t *_aidl_return) final;
+ binder::Status makeFileFromRange(int32_t storageId, const std::string &pathUnderStorage,
+ const std::string &sourcePathUnderStorage, int64_t start,
+ int64_t end, int32_t *_aidl_return);
+ binder::Status makeLink(int32_t sourceStorageId, const std::string &relativeSourcePath,
+ int32_t destStorageId, const std::string &relativeDestPath,
+ int32_t *_aidl_return) final;
+ binder::Status unlink(int32_t storageId, const std::string &pathUnderStorage,
+ int32_t *_aidl_return) final;
+ binder::Status isFileRangeLoaded(int32_t storageId, const std::string &relativePath,
+ int64_t start, int64_t end, bool *_aidl_return) final;
+ binder::Status getFileMetadata(int32_t storageId, const std::string &relativePath,
+ std::vector<uint8_t> *_aidl_return) final;
+ binder::Status startLoading(int32_t storageId, bool *_aidl_return) final;
+
+private:
+ android::incremental::IncrementalService mImpl;
+};
+
+} // namespace android::os::incremental
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
new file mode 100644
index 0000000..c43328f
--- /dev/null
+++ b/services/incremental/IncrementalService.cpp
@@ -0,0 +1,1040 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#define LOG_TAG "IncrementalService"
+
+#include "IncrementalService.h"
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android/content/pm/IDataLoaderStatusListener.h>
+#include <android/os/IVold.h>
+#include <androidfw/ZipFileRO.h>
+#include <androidfw/ZipUtils.h>
+#include <binder/BinderService.h>
+#include <binder/ParcelFileDescriptor.h>
+#include <binder/Status.h>
+#include <sys/stat.h>
+#include <uuid/uuid.h>
+#include <zlib.h>
+
+#include <iterator>
+#include <span>
+#include <stack>
+#include <thread>
+#include <type_traits>
+
+#include "Metadata.pb.h"
+
+using namespace std::literals;
+using namespace android::content::pm;
+
+namespace android::incremental {
+
+namespace {
+
+using IncrementalFileSystemControlParcel =
+ ::android::os::incremental::IncrementalFileSystemControlParcel;
+
+struct Constants {
+ static constexpr auto backing = "backing_store"sv;
+ static constexpr auto mount = "mount"sv;
+ static constexpr auto image = "incfs.img"sv;
+ static constexpr auto storagePrefix = "st"sv;
+ static constexpr auto mountpointMdPrefix = ".mountpoint."sv;
+ static constexpr auto infoMdName = ".info"sv;
+};
+
+static const Constants& constants() {
+ static Constants c;
+ return c;
+}
+
+template <base::LogSeverity level = base::ERROR>
+bool mkdirOrLog(std::string_view name, int mode = 0770, bool allowExisting = true) {
+ auto cstr = path::c_str(name);
+ if (::mkdir(cstr, mode)) {
+ if (errno != EEXIST) {
+ PLOG(level) << "Can't create directory '" << name << '\'';
+ return false;
+ }
+ struct stat st;
+ if (::stat(cstr, &st) || !S_ISDIR(st.st_mode)) {
+ PLOG(level) << "Path exists but is not a directory: '" << name << '\'';
+ return false;
+ }
+ }
+ return true;
+}
+
+static std::string toMountKey(std::string_view path) {
+ if (path.empty()) {
+ return "@none";
+ }
+ if (path == "/"sv) {
+ return "@root";
+ }
+ if (path::isAbsolute(path)) {
+ path.remove_prefix(1);
+ }
+ std::string res(path);
+ std::replace(res.begin(), res.end(), '/', '_');
+ std::replace(res.begin(), res.end(), '@', '_');
+ return res;
+}
+
+static std::pair<std::string, std::string> makeMountDir(std::string_view incrementalDir,
+ std::string_view path) {
+ auto mountKey = toMountKey(path);
+ const auto prefixSize = mountKey.size();
+ for (int counter = 0; counter < 1000;
+ mountKey.resize(prefixSize), base::StringAppendF(&mountKey, "%d", counter++)) {
+ auto mountRoot = path::join(incrementalDir, mountKey);
+ if (mkdirOrLog(mountRoot, 0770, false)) {
+ return {mountKey, mountRoot};
+ }
+ }
+ return {};
+}
+
+template <class ProtoMessage, class Control>
+static ProtoMessage parseFromIncfs(const IncFsWrapper* incfs, Control&& control,
+ std::string_view path) {
+ struct stat st;
+ if (::stat(path::c_str(path), &st)) {
+ return {};
+ }
+ auto md = incfs->getMetadata(control, st.st_ino);
+ ProtoMessage message;
+ return message.ParseFromArray(md.data(), md.size()) ? message : ProtoMessage{};
+}
+
+static bool isValidMountTarget(std::string_view path) {
+ return path::isAbsolute(path) && path::isEmptyDir(path).value_or(true);
+}
+
+std::string makeBindMdName() {
+ static constexpr auto uuidStringSize = 36;
+
+ uuid_t guid;
+ uuid_generate(guid);
+
+ std::string name;
+ const auto prefixSize = constants().mountpointMdPrefix.size();
+ name.reserve(prefixSize + uuidStringSize);
+
+ name = constants().mountpointMdPrefix;
+ name.resize(prefixSize + uuidStringSize);
+ uuid_unparse(guid, name.data() + prefixSize);
+
+ return name;
+}
+} // namespace
+
+IncrementalService::IncFsMount::~IncFsMount() {
+ incrementalService.mIncrementalManager->destroyDataLoader(mountId);
+ control.reset();
+ LOG(INFO) << "Unmounting and cleaning up mount " << mountId << " with root '" << root << '\'';
+ for (auto&& [target, _] : bindPoints) {
+ LOG(INFO) << "\tbind: " << target;
+ incrementalService.mVold->unmountIncFs(target);
+ }
+ LOG(INFO) << "\troot: " << root;
+ incrementalService.mVold->unmountIncFs(path::join(root, constants().mount));
+ cleanupFilesystem(root);
+}
+
+auto IncrementalService::IncFsMount::makeStorage(StorageId id) -> StorageMap::iterator {
+ metadata::Storage st;
+ st.set_id(id);
+ auto metadata = st.SerializeAsString();
+
+ std::string name;
+ for (int no = nextStorageDirNo.fetch_add(1, std::memory_order_relaxed), i = 0;
+ i < 1024 && no >= 0; no = nextStorageDirNo.fetch_add(1, std::memory_order_relaxed), ++i) {
+ name.clear();
+ base::StringAppendF(&name, "%.*s%d", int(constants().storagePrefix.size()),
+ constants().storagePrefix.data(), no);
+ if (auto node =
+ incrementalService.mIncFs->makeDir(control, name, INCFS_ROOT_INODE, metadata);
+ node >= 0) {
+ std::lock_guard l(lock);
+ return storages.insert_or_assign(id, Storage{std::move(name), node}).first;
+ }
+ }
+ nextStorageDirNo = 0;
+ return storages.end();
+}
+
+void IncrementalService::IncFsMount::cleanupFilesystem(std::string_view root) {
+ ::unlink(path::join(root, constants().backing, constants().image).c_str());
+ ::rmdir(path::join(root, constants().backing).c_str());
+ ::rmdir(path::join(root, constants().mount).c_str());
+ ::rmdir(path::c_str(root));
+}
+
+IncrementalService::IncrementalService(const ServiceManagerWrapper& sm, std::string_view rootDir)
+ : mVold(sm.getVoldService()),
+ mIncrementalManager(sm.getIncrementalManager()),
+ mIncFs(sm.getIncFs()),
+ mIncrementalDir(rootDir) {
+ if (!mVold) {
+ LOG(FATAL) << "Vold service is unavailable";
+ }
+ if (!mIncrementalManager) {
+ LOG(FATAL) << "IncrementalManager service is unavailable";
+ }
+ // TODO(b/136132412): check that root dir should already exist
+ // TODO(b/136132412): enable mount existing dirs after SELinux rules are merged
+ // mountExistingImages();
+}
+
+IncrementalService::~IncrementalService() = default;
+
+std::optional<std::future<void>> IncrementalService::onSystemReady() {
+ std::promise<void> threadFinished;
+ if (mSystemReady.exchange(true)) {
+ return {};
+ }
+
+ std::vector<IfsMountPtr> mounts;
+ {
+ std::lock_guard l(mLock);
+ mounts.reserve(mMounts.size());
+ for (auto&& [id, ifs] : mMounts) {
+ if (ifs->mountId == id) {
+ mounts.push_back(ifs);
+ }
+ }
+ }
+
+ std::thread([this, mounts = std::move(mounts)]() {
+ std::vector<IfsMountPtr> failedLoaderMounts;
+ for (auto&& ifs : mounts) {
+ if (prepareDataLoader(*ifs, nullptr)) {
+ LOG(INFO) << "Successfully started data loader for mount " << ifs->mountId;
+ } else {
+ LOG(WARNING) << "Failed to start data loader for mount " << ifs->mountId;
+ failedLoaderMounts.push_back(std::move(ifs));
+ }
+ }
+
+ while (!failedLoaderMounts.empty()) {
+ LOG(WARNING) << "Deleting failed mount " << failedLoaderMounts.back()->mountId;
+ deleteStorage(*failedLoaderMounts.back());
+ failedLoaderMounts.pop_back();
+ }
+ mPrepareDataLoaders.set_value_at_thread_exit();
+ }).detach();
+ return mPrepareDataLoaders.get_future();
+}
+
+auto IncrementalService::getStorageSlotLocked() -> MountMap::iterator {
+ for (;;) {
+ if (mNextId == kMaxStorageId) {
+ mNextId = 0;
+ }
+ auto id = ++mNextId;
+ auto [it, inserted] = mMounts.try_emplace(id, nullptr);
+ if (inserted) {
+ return it;
+ }
+ }
+}
+
+StorageId IncrementalService::createStorage(std::string_view mountPoint,
+ DataLoaderParamsParcel&& dataLoaderParams,
+ CreateOptions options) {
+ LOG(INFO) << "createStorage: " << mountPoint << " | " << int(options);
+ if (!path::isAbsolute(mountPoint)) {
+ LOG(ERROR) << "path is not absolute: " << mountPoint;
+ return kInvalidStorageId;
+ }
+
+ auto mountNorm = path::normalize(mountPoint);
+ {
+ const auto id = findStorageId(mountNorm);
+ if (id != kInvalidStorageId) {
+ if (options & CreateOptions::OpenExisting) {
+ LOG(INFO) << "Opened existing storage " << id;
+ return id;
+ }
+ LOG(ERROR) << "Directory " << mountPoint << " is already mounted at storage " << id;
+ return kInvalidStorageId;
+ }
+ }
+
+ if (!(options & CreateOptions::CreateNew)) {
+ LOG(ERROR) << "not requirested create new storage, and it doesn't exist: " << mountPoint;
+ return kInvalidStorageId;
+ }
+
+ if (!path::isEmptyDir(mountNorm)) {
+ LOG(ERROR) << "Mounting over existing non-empty directory is not supported: " << mountNorm;
+ return kInvalidStorageId;
+ }
+ auto [mountKey, mountRoot] = makeMountDir(mIncrementalDir, mountNorm);
+ if (mountRoot.empty()) {
+ LOG(ERROR) << "Bad mount point";
+ return kInvalidStorageId;
+ }
+ // Make sure the code removes all crap it may create while still failing.
+ auto firstCleanup = [](const std::string* ptr) { IncFsMount::cleanupFilesystem(*ptr); };
+ auto firstCleanupOnFailure =
+ std::unique_ptr<std::string, decltype(firstCleanup)>(&mountRoot, firstCleanup);
+
+ auto mountTarget = path::join(mountRoot, constants().mount);
+ if (!mkdirOrLog(path::join(mountRoot, constants().backing)) || !mkdirOrLog(mountTarget)) {
+ return kInvalidStorageId;
+ }
+
+ const auto image = path::join(mountRoot, constants().backing, constants().image);
+ IncFsMount::Control control;
+ {
+ std::lock_guard l(mMountOperationLock);
+ IncrementalFileSystemControlParcel controlParcel;
+ auto status = mVold->mountIncFs(image, mountTarget, incfs::truncate, &controlParcel);
+ if (!status.isOk()) {
+ LOG(ERROR) << "Vold::mountIncFs() failed: " << status.toString8();
+ return kInvalidStorageId;
+ }
+ if (!controlParcel.cmd || !controlParcel.log) {
+ LOG(ERROR) << "Vold::mountIncFs() returned invalid control parcel.";
+ return kInvalidStorageId;
+ }
+ control.cmdFd = controlParcel.cmd->release();
+ control.logFd = controlParcel.log->release();
+ }
+
+ std::unique_lock l(mLock);
+ const auto mountIt = getStorageSlotLocked();
+ const auto mountId = mountIt->first;
+ l.unlock();
+
+ auto ifs =
+ std::make_shared<IncFsMount>(std::move(mountRoot), mountId, std::move(control), *this);
+ // Now it's the |ifs|'s responsibility to clean up after itself, and the only cleanup we need
+ // is the removal of the |ifs|.
+ firstCleanupOnFailure.release();
+
+ auto secondCleanup = [this, &l](auto itPtr) {
+ if (!l.owns_lock()) {
+ l.lock();
+ }
+ mMounts.erase(*itPtr);
+ };
+ auto secondCleanupOnFailure =
+ std::unique_ptr<decltype(mountIt), decltype(secondCleanup)>(&mountIt, secondCleanup);
+
+ const auto storageIt = ifs->makeStorage(ifs->mountId);
+ if (storageIt == ifs->storages.end()) {
+ LOG(ERROR) << "Can't create default storage directory";
+ return kInvalidStorageId;
+ }
+
+ {
+ metadata::Mount m;
+ m.mutable_storage()->set_id(ifs->mountId);
+ m.mutable_loader()->set_package_name(dataLoaderParams.packageName);
+ m.mutable_loader()->set_arguments(dataLoaderParams.staticArgs);
+ const auto metadata = m.SerializeAsString();
+ m.mutable_loader()->release_arguments();
+ m.mutable_loader()->release_package_name();
+ if (auto err = mIncFs->makeFile(ifs->control, constants().infoMdName, INCFS_ROOT_INODE, 0,
+ metadata);
+ err < 0) {
+ LOG(ERROR) << "Saving mount metadata failed: " << -err;
+ return kInvalidStorageId;
+ }
+ }
+
+ const auto bk =
+ (options & CreateOptions::PermanentBind) ? BindKind::Permanent : BindKind::Temporary;
+ if (auto err = addBindMount(*ifs, storageIt->first, std::string(storageIt->second.name),
+ std::move(mountNorm), bk, l);
+ err < 0) {
+ LOG(ERROR) << "adding bind mount failed: " << -err;
+ return kInvalidStorageId;
+ }
+
+ // Done here as well, all data structures are in good state.
+ secondCleanupOnFailure.release();
+
+ if (!prepareDataLoader(*ifs, &dataLoaderParams)) {
+ LOG(ERROR) << "prepareDataLoader() failed";
+ deleteStorageLocked(*ifs, std::move(l));
+ return kInvalidStorageId;
+ }
+
+ mountIt->second = std::move(ifs);
+ l.unlock();
+ LOG(INFO) << "created storage " << mountId;
+ return mountId;
+}
+
+StorageId IncrementalService::createLinkedStorage(std::string_view mountPoint,
+ StorageId linkedStorage,
+ IncrementalService::CreateOptions options) {
+ if (!isValidMountTarget(mountPoint)) {
+ LOG(ERROR) << "Mount point is invalid or missing";
+ return kInvalidStorageId;
+ }
+
+ std::unique_lock l(mLock);
+ const auto& ifs = getIfsLocked(linkedStorage);
+ if (!ifs) {
+ LOG(ERROR) << "Ifs unavailable";
+ return kInvalidStorageId;
+ }
+
+ const auto mountIt = getStorageSlotLocked();
+ const auto storageId = mountIt->first;
+ const auto storageIt = ifs->makeStorage(storageId);
+ if (storageIt == ifs->storages.end()) {
+ LOG(ERROR) << "Can't create a new storage";
+ mMounts.erase(mountIt);
+ return kInvalidStorageId;
+ }
+
+ l.unlock();
+
+ const auto bk =
+ (options & CreateOptions::PermanentBind) ? BindKind::Permanent : BindKind::Temporary;
+ if (auto err = addBindMount(*ifs, storageIt->first, std::string(storageIt->second.name),
+ path::normalize(mountPoint), bk, l);
+ err < 0) {
+ LOG(ERROR) << "bindMount failed with error: " << err;
+ return kInvalidStorageId;
+ }
+
+ mountIt->second = ifs;
+ return storageId;
+}
+
+IncrementalService::BindPathMap::const_iterator IncrementalService::findStorageLocked(
+ std::string_view path) const {
+ auto bindPointIt = mBindsByPath.upper_bound(path);
+ if (bindPointIt == mBindsByPath.begin()) {
+ return mBindsByPath.end();
+ }
+ --bindPointIt;
+ if (!path::startsWith(path, bindPointIt->first)) {
+ return mBindsByPath.end();
+ }
+ return bindPointIt;
+}
+
+StorageId IncrementalService::findStorageId(std::string_view path) const {
+ std::lock_guard l(mLock);
+ auto it = findStorageLocked(path);
+ if (it == mBindsByPath.end()) {
+ return kInvalidStorageId;
+ }
+ return it->second->second.storage;
+}
+
+void IncrementalService::deleteStorage(StorageId storageId) {
+ const auto ifs = getIfs(storageId);
+ if (!ifs) {
+ return;
+ }
+ deleteStorage(*ifs);
+}
+
+void IncrementalService::deleteStorage(IncrementalService::IncFsMount& ifs) {
+ std::unique_lock l(ifs.lock);
+ deleteStorageLocked(ifs, std::move(l));
+}
+
+void IncrementalService::deleteStorageLocked(IncrementalService::IncFsMount& ifs,
+ std::unique_lock<std::mutex>&& ifsLock) {
+ const auto storages = std::move(ifs.storages);
+ // Don't move the bind points out: Ifs's dtor will use them to unmount everything.
+ const auto bindPoints = ifs.bindPoints;
+ ifsLock.unlock();
+
+ std::lock_guard l(mLock);
+ for (auto&& [id, _] : storages) {
+ if (id != ifs.mountId) {
+ mMounts.erase(id);
+ }
+ }
+ for (auto&& [path, _] : bindPoints) {
+ mBindsByPath.erase(path);
+ }
+ mMounts.erase(ifs.mountId);
+}
+
+StorageId IncrementalService::openStorage(std::string_view pathInMount) {
+ if (!path::isAbsolute(pathInMount)) {
+ return kInvalidStorageId;
+ }
+
+ return findStorageId(path::normalize(pathInMount));
+}
+
+Inode IncrementalService::nodeFor(StorageId storage, std::string_view subpath) const {
+ const auto ifs = getIfs(storage);
+ if (!ifs) {
+ return -1;
+ }
+ std::unique_lock l(ifs->lock);
+ auto storageIt = ifs->storages.find(storage);
+ if (storageIt == ifs->storages.end()) {
+ return -1;
+ }
+ if (subpath.empty() || subpath == "."sv) {
+ return storageIt->second.node;
+ }
+ auto path = path::join(ifs->root, constants().mount, storageIt->second.name, subpath);
+ l.unlock();
+ struct stat st;
+ if (::stat(path.c_str(), &st)) {
+ return -1;
+ }
+ return st.st_ino;
+}
+
+std::pair<Inode, std::string_view> IncrementalService::parentAndNameFor(
+ StorageId storage, std::string_view subpath) const {
+ auto name = path::basename(subpath);
+ if (name.empty()) {
+ return {-1, {}};
+ }
+ auto dir = path::dirname(subpath);
+ if (dir.empty() || dir == "/"sv) {
+ return {-1, {}};
+ }
+ auto inode = nodeFor(storage, dir);
+ return {inode, name};
+}
+
+IncrementalService::IfsMountPtr IncrementalService::getIfs(StorageId storage) const {
+ std::lock_guard l(mLock);
+ return getIfsLocked(storage);
+}
+
+const IncrementalService::IfsMountPtr& IncrementalService::getIfsLocked(StorageId storage) const {
+ auto it = mMounts.find(storage);
+ if (it == mMounts.end()) {
+ static const IfsMountPtr kEmpty = {};
+ return kEmpty;
+ }
+ return it->second;
+}
+
+int IncrementalService::bind(StorageId storage, std::string_view sourceSubdir,
+ std::string_view target, BindKind kind) {
+ if (!isValidMountTarget(target)) {
+ return -EINVAL;
+ }
+
+ const auto ifs = getIfs(storage);
+ if (!ifs) {
+ return -EINVAL;
+ }
+ std::unique_lock l(ifs->lock);
+ const auto storageInfo = ifs->storages.find(storage);
+ if (storageInfo == ifs->storages.end()) {
+ return -EINVAL;
+ }
+ auto source = path::join(storageInfo->second.name, sourceSubdir);
+ l.unlock();
+ std::unique_lock l2(mLock, std::defer_lock);
+ return addBindMount(*ifs, storage, std::move(source), path::normalize(target), kind, l2);
+}
+
+int IncrementalService::unbind(StorageId storage, std::string_view target) {
+ if (!path::isAbsolute(target)) {
+ return -EINVAL;
+ }
+
+ LOG(INFO) << "Removing bind point " << target;
+
+ // Here we should only look up by the exact target, not by a subdirectory of any existing mount,
+ // otherwise there's a chance to unmount something completely unrelated
+ const auto norm = path::normalize(target);
+ std::unique_lock l(mLock);
+ const auto storageIt = mBindsByPath.find(norm);
+ if (storageIt == mBindsByPath.end() || storageIt->second->second.storage != storage) {
+ return -EINVAL;
+ }
+ const auto bindIt = storageIt->second;
+ const auto storageId = bindIt->second.storage;
+ const auto ifs = getIfsLocked(storageId);
+ if (!ifs) {
+ LOG(ERROR) << "Internal error: storageId " << storageId << " for bound path " << target
+ << " is missing";
+ return -EFAULT;
+ }
+ mBindsByPath.erase(storageIt);
+ l.unlock();
+
+ mVold->unmountIncFs(bindIt->first);
+ std::unique_lock l2(ifs->lock);
+ if (ifs->bindPoints.size() <= 1) {
+ ifs->bindPoints.clear();
+ deleteStorageLocked(*ifs, std::move(l2));
+ } else {
+ const std::string savedFile = std::move(bindIt->second.savedFilename);
+ ifs->bindPoints.erase(bindIt);
+ l2.unlock();
+ if (!savedFile.empty()) {
+ mIncFs->unlink(ifs->control, INCFS_ROOT_INODE, savedFile);
+ }
+ }
+ return 0;
+}
+
+Inode IncrementalService::makeFile(StorageId storageId, std::string_view pathUnderStorage,
+ long size, std::string_view metadata,
+ std::string_view signature) {
+ (void)signature;
+ auto [parentInode, name] = parentAndNameFor(storageId, pathUnderStorage);
+ if (parentInode < 0) {
+ return -EINVAL;
+ }
+ if (auto ifs = getIfs(storageId)) {
+ auto inode = mIncFs->makeFile(ifs->control, name, parentInode, size, metadata);
+ if (inode < 0) {
+ return inode;
+ }
+ auto metadataBytes = std::vector<uint8_t>();
+ if (metadata.data() != nullptr && metadata.size() > 0) {
+ metadataBytes.insert(metadataBytes.end(), &metadata.data()[0],
+ &metadata.data()[metadata.size()]);
+ }
+ mIncrementalManager->newFileForDataLoader(ifs->mountId, inode, metadataBytes);
+ return inode;
+ }
+ return -EINVAL;
+}
+
+Inode IncrementalService::makeDir(StorageId storageId, std::string_view pathUnderStorage,
+ std::string_view metadata) {
+ auto [parentInode, name] = parentAndNameFor(storageId, pathUnderStorage);
+ if (parentInode < 0) {
+ return -EINVAL;
+ }
+ if (auto ifs = getIfs(storageId)) {
+ return mIncFs->makeDir(ifs->control, name, parentInode, metadata);
+ }
+ return -EINVAL;
+}
+
+Inode IncrementalService::makeDirs(StorageId storageId, std::string_view pathUnderStorage,
+ std::string_view metadata) {
+ const auto ifs = getIfs(storageId);
+ if (!ifs) {
+ return -EINVAL;
+ }
+ std::string_view parentDir(pathUnderStorage);
+ auto p = parentAndNameFor(storageId, pathUnderStorage);
+ std::stack<std::string> pathsToCreate;
+ while (p.first < 0) {
+ parentDir = path::dirname(parentDir);
+ pathsToCreate.emplace(parentDir);
+ p = parentAndNameFor(storageId, parentDir);
+ }
+ Inode inode;
+ while (!pathsToCreate.empty()) {
+ p = parentAndNameFor(storageId, pathsToCreate.top());
+ pathsToCreate.pop();
+ inode = mIncFs->makeDir(ifs->control, p.second, p.first, metadata);
+ if (inode < 0) {
+ return inode;
+ }
+ }
+ return mIncFs->makeDir(ifs->control, path::basename(pathUnderStorage), inode, metadata);
+}
+
+int IncrementalService::link(StorageId storage, Inode item, Inode newParent,
+ std::string_view newName) {
+ if (auto ifs = getIfs(storage)) {
+ return mIncFs->link(ifs->control, item, newParent, newName);
+ }
+ return -EINVAL;
+}
+
+int IncrementalService::unlink(StorageId storage, Inode parent, std::string_view name) {
+ if (auto ifs = getIfs(storage)) {
+ return mIncFs->unlink(ifs->control, parent, name);
+ }
+ return -EINVAL;
+}
+
+int IncrementalService::addBindMount(IncFsMount& ifs, StorageId storage, std::string&& sourceSubdir,
+ std::string&& target, BindKind kind,
+ std::unique_lock<std::mutex>& mainLock) {
+ if (!isValidMountTarget(target)) {
+ return -EINVAL;
+ }
+
+ std::string mdFileName;
+ if (kind != BindKind::Temporary) {
+ metadata::BindPoint bp;
+ bp.set_storage_id(storage);
+ bp.set_allocated_dest_path(&target);
+ bp.set_allocated_source_subdir(&sourceSubdir);
+ const auto metadata = bp.SerializeAsString();
+ bp.release_source_subdir();
+ bp.release_dest_path();
+ mdFileName = makeBindMdName();
+ auto node = mIncFs->makeFile(ifs.control, mdFileName, INCFS_ROOT_INODE, 0, metadata);
+ if (node < 0) {
+ return int(node);
+ }
+ }
+
+ return addBindMountWithMd(ifs, storage, std::move(mdFileName), std::move(sourceSubdir),
+ std::move(target), kind, mainLock);
+}
+
+int IncrementalService::addBindMountWithMd(IncrementalService::IncFsMount& ifs, StorageId storage,
+ std::string&& metadataName, std::string&& sourceSubdir,
+ std::string&& target, BindKind kind,
+ std::unique_lock<std::mutex>& mainLock) {
+ LOG(INFO) << "Adding bind mount: " << sourceSubdir << " -> " << target;
+ {
+ auto path = path::join(ifs.root, constants().mount, sourceSubdir);
+ std::lock_guard l(mMountOperationLock);
+ const auto status = mVold->bindMount(path, target);
+ if (!status.isOk()) {
+ LOG(ERROR) << "Calling Vold::bindMount() failed: " << status.toString8();
+ return status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC
+ ? status.serviceSpecificErrorCode() > 0 ? -status.serviceSpecificErrorCode()
+ : status.serviceSpecificErrorCode() == 0
+ ? -EFAULT
+ : status.serviceSpecificErrorCode()
+ : -EIO;
+ }
+ }
+
+ if (!mainLock.owns_lock()) {
+ mainLock.lock();
+ }
+ std::lock_guard l(ifs.lock);
+ const auto [it, _] =
+ ifs.bindPoints.insert_or_assign(target,
+ IncFsMount::Bind{storage, std::move(metadataName),
+ std::move(sourceSubdir), kind});
+ mBindsByPath[std::move(target)] = it;
+ return 0;
+}
+
+RawMetadata IncrementalService::getMetadata(StorageId storage, Inode node) const {
+ const auto ifs = getIfs(storage);
+ if (!ifs) {
+ return {};
+ }
+ return mIncFs->getMetadata(ifs->control, node);
+}
+
+std::vector<std::string> IncrementalService::listFiles(StorageId storage) const {
+ const auto ifs = getIfs(storage);
+ if (!ifs) {
+ return {};
+ }
+
+ std::unique_lock l(ifs->lock);
+ auto subdirIt = ifs->storages.find(storage);
+ if (subdirIt == ifs->storages.end()) {
+ return {};
+ }
+ auto dir = path::join(ifs->root, constants().mount, subdirIt->second.name);
+ l.unlock();
+
+ const auto prefixSize = dir.size() + 1;
+ std::vector<std::string> todoDirs{std::move(dir)};
+ std::vector<std::string> result;
+ do {
+ auto currDir = std::move(todoDirs.back());
+ todoDirs.pop_back();
+
+ auto d =
+ std::unique_ptr<DIR, decltype(&::closedir)>(::opendir(currDir.c_str()), ::closedir);
+ while (auto e = ::readdir(d.get())) {
+ if (e->d_type == DT_REG) {
+ result.emplace_back(
+ path::join(std::string_view(currDir).substr(prefixSize), e->d_name));
+ continue;
+ }
+ if (e->d_type == DT_DIR) {
+ if (e->d_name == "."sv || e->d_name == ".."sv) {
+ continue;
+ }
+ todoDirs.emplace_back(path::join(currDir, e->d_name));
+ continue;
+ }
+ }
+ } while (!todoDirs.empty());
+ return result;
+}
+
+bool IncrementalService::startLoading(StorageId storage) const {
+ const auto ifs = getIfs(storage);
+ if (!ifs) {
+ return false;
+ }
+ bool started = false;
+ std::unique_lock l(ifs->lock);
+ if (ifs->dataLoaderStatus != IDataLoaderStatusListener::DATA_LOADER_READY) {
+ if (ifs->dataLoaderReady.wait_for(l, Seconds(5)) == std::cv_status::timeout) {
+ LOG(ERROR) << "Timeout waiting for data loader to be ready";
+ return false;
+ }
+ }
+ auto status = mIncrementalManager->startDataLoader(ifs->mountId, &started);
+ if (!status.isOk()) {
+ return false;
+ }
+ return started;
+}
+
+void IncrementalService::mountExistingImages() {
+ auto d = std::unique_ptr<DIR, decltype(&::closedir)>(::opendir(mIncrementalDir.c_str()),
+ ::closedir);
+ while (auto e = ::readdir(d.get())) {
+ if (e->d_type != DT_DIR) {
+ continue;
+ }
+ if (e->d_name == "."sv || e->d_name == ".."sv) {
+ continue;
+ }
+ auto root = path::join(mIncrementalDir, e->d_name);
+ if (!mountExistingImage(root, e->d_name)) {
+ IncFsMount::cleanupFilesystem(root);
+ }
+ }
+}
+
+bool IncrementalService::mountExistingImage(std::string_view root, std::string_view key) {
+ LOG(INFO) << "Trying to mount: " << key;
+
+ auto mountTarget = path::join(root, constants().mount);
+ const auto image = path::join(root, constants().backing, constants().image);
+
+ IncFsMount::Control control;
+ IncrementalFileSystemControlParcel controlParcel;
+ auto status = mVold->mountIncFs(image, mountTarget, 0, &controlParcel);
+ if (!status.isOk()) {
+ LOG(ERROR) << "Vold::mountIncFs() failed: " << status.toString8();
+ return false;
+ }
+ if (controlParcel.cmd) {
+ control.cmdFd = controlParcel.cmd->release();
+ }
+ if (controlParcel.log) {
+ control.logFd = controlParcel.log->release();
+ }
+
+ auto ifs = std::make_shared<IncFsMount>(std::string(root), -1, std::move(control), *this);
+
+ auto m = parseFromIncfs<metadata::Mount>(mIncFs.get(), ifs->control,
+ path::join(mountTarget, constants().infoMdName));
+ if (!m.has_loader() || !m.has_storage()) {
+ LOG(ERROR) << "Bad mount metadata in mount at " << root;
+ return false;
+ }
+
+ ifs->mountId = m.storage().id();
+ mNextId = std::max(mNextId, ifs->mountId + 1);
+
+ std::vector<std::pair<std::string, metadata::BindPoint>> bindPoints;
+ auto d = std::unique_ptr<DIR, decltype(&::closedir)>(::opendir(path::c_str(mountTarget)),
+ ::closedir);
+ while (auto e = ::readdir(d.get())) {
+ if (e->d_type == DT_REG) {
+ auto name = std::string_view(e->d_name);
+ if (name.starts_with(constants().mountpointMdPrefix)) {
+ bindPoints.emplace_back(name,
+ parseFromIncfs<metadata::BindPoint>(mIncFs.get(),
+ ifs->control,
+ path::join(mountTarget,
+ name)));
+ if (bindPoints.back().second.dest_path().empty() ||
+ bindPoints.back().second.source_subdir().empty()) {
+ bindPoints.pop_back();
+ mIncFs->unlink(ifs->control, INCFS_ROOT_INODE, name);
+ }
+ }
+ } else if (e->d_type == DT_DIR) {
+ if (e->d_name == "."sv || e->d_name == ".."sv) {
+ continue;
+ }
+ auto name = std::string_view(e->d_name);
+ if (name.starts_with(constants().storagePrefix)) {
+ auto md = parseFromIncfs<metadata::Storage>(mIncFs.get(), ifs->control,
+ path::join(mountTarget, name));
+ auto [_, inserted] = mMounts.try_emplace(md.id(), ifs);
+ if (!inserted) {
+ LOG(WARNING) << "Ignoring storage with duplicate id " << md.id()
+ << " for mount " << root;
+ continue;
+ }
+ ifs->storages.insert_or_assign(md.id(),
+ IncFsMount::Storage{std::string(name),
+ Inode(e->d_ino)});
+ mNextId = std::max(mNextId, md.id() + 1);
+ }
+ }
+ }
+
+ if (ifs->storages.empty()) {
+ LOG(WARNING) << "No valid storages in mount " << root;
+ return false;
+ }
+
+ int bindCount = 0;
+ for (auto&& bp : bindPoints) {
+ std::unique_lock l(mLock, std::defer_lock);
+ bindCount += !addBindMountWithMd(*ifs, bp.second.storage_id(), std::move(bp.first),
+ std::move(*bp.second.mutable_source_subdir()),
+ std::move(*bp.second.mutable_dest_path()),
+ BindKind::Permanent, l);
+ }
+
+ if (bindCount == 0) {
+ LOG(WARNING) << "No valid bind points for mount " << root;
+ deleteStorage(*ifs);
+ return false;
+ }
+
+ DataLoaderParamsParcel dlParams;
+ dlParams.packageName = std::move(*m.mutable_loader()->mutable_package_name());
+ dlParams.staticArgs = std::move(*m.mutable_loader()->mutable_arguments());
+ if (!prepareDataLoader(*ifs, &dlParams)) {
+ deleteStorage(*ifs);
+ return false;
+ }
+
+ mMounts[ifs->mountId] = std::move(ifs);
+ return true;
+}
+
+bool IncrementalService::prepareDataLoader(IncrementalService::IncFsMount& ifs,
+ DataLoaderParamsParcel* params) {
+ if (!mSystemReady.load(std::memory_order_relaxed)) {
+ std::unique_lock l(ifs.lock);
+ if (params) {
+ if (ifs.savedDataLoaderParams) {
+ LOG(WARNING) << "Trying to pass second set of data loader parameters, ignored it";
+ } else {
+ ifs.savedDataLoaderParams = std::move(*params);
+ }
+ } else {
+ if (!ifs.savedDataLoaderParams) {
+ LOG(ERROR) << "Mount " << ifs.mountId
+ << " is broken: no data loader params (system is not ready yet)";
+ return false;
+ }
+ }
+ return true; // eventually...
+ }
+ if (base::GetBoolProperty("incremental.skip_loader", false)) {
+ LOG(INFO) << "Skipped data loader because of incremental.skip_loader property";
+ std::unique_lock l(ifs.lock);
+ ifs.savedDataLoaderParams.reset();
+ return true;
+ }
+
+ std::unique_lock l(ifs.lock);
+ if (ifs.dataLoaderStatus == IDataLoaderStatusListener::DATA_LOADER_READY) {
+ LOG(INFO) << "Skipped data loader preparation because it already exists";
+ return true;
+ }
+
+ auto* dlp = params ? params
+ : ifs.savedDataLoaderParams ? &ifs.savedDataLoaderParams.value() : nullptr;
+ if (!dlp) {
+ LOG(ERROR) << "Mount " << ifs.mountId << " is broken: no data loader params";
+ return false;
+ }
+ FileSystemControlParcel fsControlParcel;
+ fsControlParcel.incremental = std::make_unique<IncrementalFileSystemControlParcel>();
+ fsControlParcel.incremental->cmd =
+ std::make_unique<os::ParcelFileDescriptor>(base::unique_fd(::dup(ifs.control.cmdFd)));
+ fsControlParcel.incremental->log =
+ std::make_unique<os::ParcelFileDescriptor>(base::unique_fd(::dup(ifs.control.logFd)));
+ sp<IncrementalDataLoaderListener> listener = new IncrementalDataLoaderListener(*this);
+ bool created = false;
+ auto status = mIncrementalManager->prepareDataLoader(ifs.mountId, fsControlParcel, *dlp,
+ listener, &created);
+ if (!status.isOk() || !created) {
+ LOG(ERROR) << "Failed to create a data loader for mount " << ifs.mountId;
+ return false;
+ }
+ ifs.savedDataLoaderParams.reset();
+ return true;
+}
+
+binder::Status IncrementalService::IncrementalDataLoaderListener::onStatusChanged(MountId mountId,
+ int newStatus) {
+ std::unique_lock l(incrementalService.mLock);
+ const auto& ifs = incrementalService.getIfsLocked(mountId);
+ if (!ifs) {
+ LOG(WARNING) << "Received data loader status " << int(newStatus) << " for unknown mount "
+ << mountId;
+ return binder::Status::ok();
+ }
+ ifs->dataLoaderStatus = newStatus;
+ switch (newStatus) {
+ case IDataLoaderStatusListener::DATA_LOADER_NO_CONNECTION: {
+ auto now = Clock::now();
+ if (ifs->connectionLostTime.time_since_epoch().count() == 0) {
+ ifs->connectionLostTime = now;
+ break;
+ }
+ auto duration =
+ std::chrono::duration_cast<Seconds>(now - ifs->connectionLostTime).count();
+ if (duration >= 10) {
+ incrementalService.mIncrementalManager->showHealthBlockedUI(mountId);
+ }
+ break;
+ }
+ case IDataLoaderStatusListener::DATA_LOADER_READY: {
+ ifs->dataLoaderReady.notify_one();
+ break;
+ }
+ case IDataLoaderStatusListener::DATA_LOADER_NOT_READY: {
+ ifs->dataLoaderStatus = IDataLoaderStatusListener::DATA_LOADER_STOPPED;
+ incrementalService.deleteStorageLocked(*ifs, std::move(l));
+ break;
+ }
+ case IDataLoaderStatusListener::DATA_LOADER_RUNNING: {
+ break;
+ }
+ case IDataLoaderStatusListener::DATA_LOADER_CONNECTION_OK: {
+ ifs->dataLoaderStatus = IDataLoaderStatusListener::DATA_LOADER_RUNNING;
+ break;
+ }
+ case IDataLoaderStatusListener::DATA_LOADER_STOPPED: {
+ break;
+ }
+ default: {
+ LOG(WARNING) << "Unknown data loader status: " << newStatus
+ << " for mount: " << mountId;
+ break;
+ }
+ }
+
+ return binder::Status::ok();
+}
+
+} // namespace android::incremental
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
new file mode 100644
index 0000000..a03ffa0
--- /dev/null
+++ b/services/incremental/IncrementalService.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+#include <android/os/incremental/IIncrementalManager.h>
+#include <android/content/pm/DataLoaderParamsParcel.h>
+#include <binder/IServiceManager.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+#include <utils/Vector.h>
+
+#include <atomic>
+#include <chrono>
+#include <future>
+#include <limits>
+#include <map>
+#include <mutex>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "ServiceWrappers.h"
+#include "android/content/pm/BnDataLoaderStatusListener.h"
+#include "incfs.h"
+#include "path.h"
+
+using namespace android::os::incremental;
+
+namespace android::os {
+class IVold;
+}
+
+namespace android::incremental {
+
+using MountId = int;
+using StorageId = int;
+using Inode = incfs::Inode;
+using BlockIndex = incfs::BlockIndex;
+using RawMetadata = incfs::RawMetadata;
+using Clock = std::chrono::steady_clock;
+using TimePoint = std::chrono::time_point<Clock>;
+using Seconds = std::chrono::seconds;
+
+class IncrementalService {
+public:
+ explicit IncrementalService(const ServiceManagerWrapper& sm, std::string_view rootDir);
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+ ~IncrementalService();
+#pragma GCC diagnostic pop
+
+ static constexpr StorageId kInvalidStorageId = -1;
+ static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max();
+
+ enum CreateOptions {
+ TemporaryBind = 1,
+ PermanentBind = 2,
+ CreateNew = 4,
+ OpenExisting = 8,
+
+ Default = TemporaryBind | CreateNew
+ };
+
+ enum class BindKind {
+ Temporary = 0,
+ Permanent = 1,
+ };
+
+ std::optional<std::future<void>> onSystemReady();
+
+ StorageId createStorage(std::string_view mountPoint,
+ DataLoaderParamsParcel&& dataLoaderParams,
+ CreateOptions options = CreateOptions::Default);
+ StorageId createLinkedStorage(std::string_view mountPoint, StorageId linkedStorage,
+ CreateOptions options = CreateOptions::Default);
+ StorageId openStorage(std::string_view pathInMount);
+
+ Inode nodeFor(StorageId storage, std::string_view subpath) const;
+ std::pair<Inode, std::string_view> parentAndNameFor(StorageId storage,
+ std::string_view subpath) const;
+
+ int bind(StorageId storage, std::string_view subdir, std::string_view target, BindKind kind);
+ int unbind(StorageId storage, std::string_view target);
+ void deleteStorage(StorageId storage);
+
+ Inode makeFile(StorageId storage, std::string_view name, long size, std::string_view metadata,
+ std::string_view signature);
+ Inode makeDir(StorageId storage, std::string_view name, std::string_view metadata = {});
+ Inode makeDirs(StorageId storage, std::string_view name, std::string_view metadata = {});
+
+ int link(StorageId storage, Inode item, Inode newParent, std::string_view newName);
+ int unlink(StorageId storage, Inode parent, std::string_view name);
+
+ bool isRangeLoaded(StorageId storage, Inode file, std::pair<BlockIndex, BlockIndex> range) {
+ return false;
+ }
+
+ RawMetadata getMetadata(StorageId storage, Inode node) const;
+ std::string getSigngatureData(StorageId storage, Inode node) const { return {}; }
+
+ std::vector<std::string> listFiles(StorageId storage) const;
+ bool startLoading(StorageId storage) const;
+
+ class IncrementalDataLoaderListener : public android::content::pm::BnDataLoaderStatusListener {
+ public:
+ IncrementalDataLoaderListener(IncrementalService& incrementalService)
+ : incrementalService(incrementalService) {}
+ // Callbacks interface
+ binder::Status onStatusChanged(MountId mount, int newStatus) override;
+
+ private:
+ IncrementalService& incrementalService;
+ };
+
+private:
+ struct IncFsMount {
+ struct Bind {
+ StorageId storage;
+ std::string savedFilename;
+ std::string sourceDir;
+ BindKind kind;
+ };
+
+ struct Storage {
+ std::string name;
+ Inode node;
+ };
+
+ struct Control {
+ operator IncFsControl() const { return {cmdFd, logFd}; }
+ void reset() {
+ cmdFd.reset();
+ logFd.reset();
+ }
+
+ base::unique_fd cmdFd;
+ base::unique_fd logFd;
+ };
+
+ using BindMap = std::map<std::string, Bind>;
+ using StorageMap = std::unordered_map<StorageId, Storage>;
+
+ mutable std::mutex lock;
+ const std::string root;
+ Control control;
+ /*const*/ MountId mountId;
+ StorageMap storages;
+ BindMap bindPoints;
+ std::optional<DataLoaderParamsParcel> savedDataLoaderParams;
+ std::atomic<int> nextStorageDirNo{0};
+ std::atomic<int> dataLoaderStatus = -1;
+ std::condition_variable dataLoaderReady;
+ TimePoint connectionLostTime = TimePoint();
+ const IncrementalService& incrementalService;
+
+ IncFsMount(std::string root, MountId mountId, Control control,
+ const IncrementalService& incrementalService)
+ : root(std::move(root)),
+ control(std::move(control)),
+ mountId(mountId),
+ incrementalService(incrementalService) {}
+ IncFsMount(IncFsMount&&) = delete;
+ IncFsMount& operator=(IncFsMount&&) = delete;
+ ~IncFsMount();
+
+ StorageMap::iterator makeStorage(StorageId id);
+
+ static void cleanupFilesystem(std::string_view root);
+ };
+
+ using IfsMountPtr = std::shared_ptr<IncFsMount>;
+ using MountMap = std::unordered_map<MountId, IfsMountPtr>;
+ using BindPathMap = std::map<std::string, IncFsMount::BindMap::iterator, path::PathLess>;
+
+ void mountExistingImages();
+ bool mountExistingImage(std::string_view root, std::string_view key);
+
+ IfsMountPtr getIfs(StorageId storage) const;
+ const IfsMountPtr& getIfsLocked(StorageId storage) const;
+ int addBindMount(IncFsMount& ifs, StorageId storage, std::string&& sourceSubdir,
+ std::string&& target, BindKind kind, std::unique_lock<std::mutex>& mainLock);
+
+ int addBindMountWithMd(IncFsMount& ifs, StorageId storage, std::string&& metadataName,
+ std::string&& sourceSubdir, std::string&& target, BindKind kind,
+ std::unique_lock<std::mutex>& mainLock);
+
+ bool prepareDataLoader(IncFsMount& ifs, DataLoaderParamsParcel* params);
+ BindPathMap::const_iterator findStorageLocked(std::string_view path) const;
+ StorageId findStorageId(std::string_view path) const;
+
+ void deleteStorage(IncFsMount& ifs);
+ void deleteStorageLocked(IncFsMount& ifs, std::unique_lock<std::mutex>&& ifsLock);
+ MountMap::iterator getStorageSlotLocked();
+
+ // Member variables
+ // These are shared pointers for the sake of unit testing
+ std::shared_ptr<VoldServiceWrapper> mVold;
+ std::shared_ptr<IncrementalManagerWrapper> mIncrementalManager;
+ std::shared_ptr<IncFsWrapper> mIncFs;
+ const std::string mIncrementalDir;
+
+ mutable std::mutex mLock;
+ mutable std::mutex mMountOperationLock;
+ MountMap mMounts;
+ BindPathMap mBindsByPath;
+
+ std::atomic_bool mSystemReady = false;
+ StorageId mNextId = 0;
+ std::promise<void> mPrepareDataLoaders;
+};
+
+} // namespace android::incremental
diff --git a/services/incremental/Metadata.proto b/services/incremental/Metadata.proto
new file mode 100644
index 0000000..0ff3c32
--- /dev/null
+++ b/services/incremental/Metadata.proto
@@ -0,0 +1,23 @@
+syntax = "proto3";
+
+package android.incremental.metadata;
+
+message BindPoint {
+ int32 storage_id = 1;
+ string source_subdir = 2;
+ string dest_path = 3;
+}
+
+message DataLoader {
+ string package_name = 1;
+ string arguments = 2;
+}
+
+message Storage {
+ int32 id = 1;
+}
+
+message Mount {
+ Storage storage = 1;
+ DataLoader loader = 2;
+}
diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp
new file mode 100644
index 0000000..a79b26a
--- /dev/null
+++ b/services/incremental/ServiceWrappers.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 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 "ServiceWrappers.h"
+
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+#include <binder/IServiceManager.h>
+#include <utils/String16.h>
+
+#include <string>
+#include <string_view>
+
+using namespace std::literals;
+
+namespace android::os::incremental {
+
+static constexpr auto kVoldServiceName = "vold"sv;
+static constexpr auto kIncrementalManagerName = "incremental"sv;
+
+RealServiceManager::RealServiceManager(const sp<IServiceManager>& serviceManager)
+ : mServiceManager(serviceManager) {}
+
+template <class INTERFACE>
+sp<INTERFACE> RealServiceManager::getRealService(std::string_view serviceName) const {
+ sp<IBinder> binder = mServiceManager->getService(String16(serviceName.data()));
+ if (binder == 0) {
+ return 0;
+ }
+ return interface_cast<INTERFACE>(binder);
+}
+
+std::shared_ptr<VoldServiceWrapper> RealServiceManager::getVoldService() const {
+ sp<os::IVold> vold = RealServiceManager::getRealService<os::IVold>(kVoldServiceName);
+ if (vold != 0) {
+ return std::make_shared<RealVoldService>(vold);
+ }
+ return nullptr;
+}
+
+std::shared_ptr<IncrementalManagerWrapper> RealServiceManager::getIncrementalManager() const {
+ sp<IIncrementalManager> manager =
+ RealServiceManager::getRealService<IIncrementalManager>(kIncrementalManagerName);
+ if (manager != 0) {
+ return std::make_shared<RealIncrementalManager>(manager);
+ }
+ return nullptr;
+}
+
+std::shared_ptr<IncFsWrapper> RealServiceManager::getIncFs() const {
+ return std::make_shared<RealIncFs>();
+}
+
+} // namespace android::os::incremental
diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h
new file mode 100644
index 0000000..5704582
--- /dev/null
+++ b/services/incremental/ServiceWrappers.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+#include <android/content/pm/DataLoaderParamsParcel.h>
+#include <android/content/pm/FileSystemControlParcel.h>
+#include <android/content/pm/IDataLoaderStatusListener.h>
+#include <android/os/IVold.h>
+#include <android/os/incremental/IIncrementalManager.h>
+#include <binder/IServiceManager.h>
+#include <incfs.h>
+
+#include <string>
+#include <string_view>
+
+using namespace android::incfs;
+using namespace android::content::pm;
+
+namespace android::os::incremental {
+
+// --- Wrapper interfaces ---
+
+class VoldServiceWrapper {
+public:
+ virtual ~VoldServiceWrapper(){};
+ virtual binder::Status mountIncFs(const std::string& imagePath, const std::string& targetDir,
+ int32_t flags,
+ IncrementalFileSystemControlParcel* _aidl_return) const = 0;
+ virtual binder::Status unmountIncFs(const std::string& dir) const = 0;
+ virtual binder::Status bindMount(const std::string& sourceDir,
+ const std::string& targetDir) const = 0;
+};
+
+class IncrementalManagerWrapper {
+public:
+ virtual ~IncrementalManagerWrapper() {}
+ virtual binder::Status prepareDataLoader(
+ int32_t mountId, const FileSystemControlParcel& control,
+ const DataLoaderParamsParcel& params,
+ const sp<IDataLoaderStatusListener>& listener,
+ bool* _aidl_return) const = 0;
+ virtual binder::Status startDataLoader(int32_t mountId, bool* _aidl_return) const = 0;
+ virtual binder::Status destroyDataLoader(int32_t mountId) const = 0;
+ virtual binder::Status newFileForDataLoader(int32_t mountId, int64_t inode,
+ const ::std::vector<uint8_t>& metadata) const = 0;
+ virtual binder::Status showHealthBlockedUI(int32_t mountId) const = 0;
+};
+
+class IncFsWrapper {
+public:
+ virtual ~IncFsWrapper() {}
+ virtual Inode makeFile(Control control, std::string_view name, Inode parent, Size size,
+ std::string_view metadata) const = 0;
+ virtual Inode makeDir(Control control, std::string_view name, Inode parent,
+ std::string_view metadata, int mode = 0555) const = 0;
+ virtual RawMetadata getMetadata(Control control, Inode inode) const = 0;
+ virtual ErrorCode link(Control control, Inode item, Inode targetParent,
+ std::string_view name) const = 0;
+ virtual ErrorCode unlink(Control control, Inode parent, std::string_view name) const = 0;
+ virtual ErrorCode writeBlocks(Control control, const incfs_new_data_block blocks[],
+ int blocksCount) const = 0;
+};
+
+class ServiceManagerWrapper {
+public:
+ virtual ~ServiceManagerWrapper() {}
+ virtual std::shared_ptr<VoldServiceWrapper> getVoldService() const = 0;
+ virtual std::shared_ptr<IncrementalManagerWrapper> getIncrementalManager() const = 0;
+ virtual std::shared_ptr<IncFsWrapper> getIncFs() const = 0;
+};
+
+// --- Real stuff ---
+
+class RealVoldService : public VoldServiceWrapper {
+public:
+ RealVoldService(const sp<os::IVold> vold) : mInterface(vold) {}
+ ~RealVoldService() = default;
+ binder::Status mountIncFs(const std::string& imagePath, const std::string& targetDir,
+ int32_t flags,
+ IncrementalFileSystemControlParcel* _aidl_return) const override {
+ return mInterface->mountIncFs(imagePath, targetDir, flags, _aidl_return);
+ }
+ binder::Status unmountIncFs(const std::string& dir) const override {
+ return mInterface->unmountIncFs(dir);
+ }
+ binder::Status bindMount(const std::string& sourceDir,
+ const std::string& targetDir) const override {
+ return mInterface->bindMount(sourceDir, targetDir);
+ }
+
+private:
+ sp<os::IVold> mInterface;
+};
+
+class RealIncrementalManager : public IncrementalManagerWrapper {
+public:
+ RealIncrementalManager(const sp<os::incremental::IIncrementalManager> manager)
+ : mInterface(manager) {}
+ ~RealIncrementalManager() = default;
+ binder::Status prepareDataLoader(
+ int32_t mountId, const FileSystemControlParcel& control,
+ const DataLoaderParamsParcel& params,
+ const sp<IDataLoaderStatusListener>& listener,
+ bool* _aidl_return) const override {
+ return mInterface->prepareDataLoader(mountId, control, params, listener, _aidl_return);
+ }
+ binder::Status startDataLoader(int32_t mountId, bool* _aidl_return) const override {
+ return mInterface->startDataLoader(mountId, _aidl_return);
+ }
+ binder::Status destroyDataLoader(int32_t mountId) const override {
+ return mInterface->destroyDataLoader(mountId);
+ }
+ binder::Status newFileForDataLoader(int32_t mountId, int64_t inode,
+ const ::std::vector<uint8_t>& metadata) const override {
+ return mInterface->newFileForDataLoader(mountId, inode, metadata);
+ }
+ binder::Status showHealthBlockedUI(int32_t mountId) const override {
+ return mInterface->showHealthBlockedUI(mountId);
+ }
+
+private:
+ sp<os::incremental::IIncrementalManager> mInterface;
+};
+
+class RealServiceManager : public ServiceManagerWrapper {
+public:
+ RealServiceManager(const sp<IServiceManager>& serviceManager);
+ ~RealServiceManager() = default;
+ std::shared_ptr<VoldServiceWrapper> getVoldService() const override;
+ std::shared_ptr<IncrementalManagerWrapper> getIncrementalManager() const override;
+ std::shared_ptr<IncFsWrapper> getIncFs() const override;
+
+private:
+ template <class INTERFACE>
+ sp<INTERFACE> getRealService(std::string_view serviceName) const;
+ sp<android::IServiceManager> mServiceManager;
+};
+
+class RealIncFs : public IncFsWrapper {
+public:
+ RealIncFs() = default;
+ ~RealIncFs() = default;
+ Inode makeFile(Control control, std::string_view name, Inode parent, Size size,
+ std::string_view metadata) const override {
+ return incfs::makeFile(control, name, parent, size, metadata);
+ }
+ Inode makeDir(Control control, std::string_view name, Inode parent, std::string_view metadata,
+ int mode) const override {
+ return incfs::makeDir(control, name, parent, metadata, mode);
+ }
+ RawMetadata getMetadata(Control control, Inode inode) const override {
+ return incfs::getMetadata(control, inode);
+ }
+ ErrorCode link(Control control, Inode item, Inode targetParent,
+ std::string_view name) const override {
+ return incfs::link(control, item, targetParent, name);
+ }
+ ErrorCode unlink(Control control, Inode parent, std::string_view name) const override {
+ return incfs::unlink(control, parent, name);
+ }
+ ErrorCode writeBlocks(Control control, const incfs_new_data_block blocks[],
+ int blocksCount) const override {
+ return incfs::writeBlocks(control, blocks, blocksCount);
+ }
+};
+
+} // namespace android::os::incremental
diff --git a/core/java/android/net/ITetheringEventCallback.aidl b/services/incremental/include/incremental_service.h
similarity index 63%
copy from core/java/android/net/ITetheringEventCallback.aidl
copy to services/incremental/include/incremental_service.h
index d502088..7109d95 100644
--- a/core/java/android/net/ITetheringEventCallback.aidl
+++ b/services/incremental/include/incremental_service.h
@@ -14,15 +14,19 @@
* limitations under the License.
*/
-package android.net;
+#ifndef ANDROID_INCREMENTAL_SERVICE_H
+#define ANDROID_INCREMENTAL_SERVICE_H
-import android.net.Network;
+#include <sys/cdefs.h>
+#include <jni.h>
-/**
- * Callback class for receiving tethering changed events
- * @hide
- */
-oneway interface ITetheringEventCallback
-{
- void onUpstreamChanged(in Network network);
-}
+__BEGIN_DECLS
+
+#define INCREMENTAL_LIBRARY_NAME "service.incremental.so"
+
+jlong Incremental_IncrementalService_Start();
+void Incremental_IncrementalService_OnSystemReady(jlong self);
+
+__END_DECLS
+
+#endif // ANDROID_INCREMENTAL_SERVICE_H
diff --git a/core/java/android/net/ITetheringEventCallback.aidl b/services/incremental/incremental_service.c
similarity index 73%
copy from core/java/android/net/ITetheringEventCallback.aidl
copy to services/incremental/incremental_service.c
index d502088..f6ea59e 100644
--- a/core/java/android/net/ITetheringEventCallback.aidl
+++ b/services/incremental/incremental_service.c
@@ -14,15 +14,4 @@
* limitations under the License.
*/
-package android.net;
-
-import android.net.Network;
-
-/**
- * Callback class for receiving tethering changed events
- * @hide
- */
-oneway interface ITetheringEventCallback
-{
- void onUpstreamChanged(in Network network);
-}
+#include "incremental_service.h"
diff --git a/services/incremental/path.cpp b/services/incremental/path.cpp
new file mode 100644
index 0000000..c529d61
--- /dev/null
+++ b/services/incremental/path.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2019 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 "path.h"
+
+#include <android-base/strings.h>
+#include <android-base/logging.h>
+
+#include <algorithm>
+#include <iterator>
+#include <limits>
+#include <memory>
+
+#include <dirent.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+using namespace std::literals;
+
+namespace android::incremental::path {
+
+bool PathCharsLess::operator()(char l, char r) const {
+ int ll = l == '/' ? std::numeric_limits<char>::min() - 1 : l;
+ int rr = r == '/' ? std::numeric_limits<char>::min() - 1 : r;
+ return ll < rr;
+}
+
+bool PathLess::operator()(std::string_view l, std::string_view r) const {
+ return std::lexicographical_compare(std::begin(l), std::end(l), std::begin(r), std::end(r),
+ PathCharsLess());
+}
+
+void details::append_next_path(std::string& target, std::string_view path) {
+ if (path.empty()) {
+ return;
+ }
+ if (!target.empty()) {
+ target.push_back('/');
+ }
+ target += path;
+}
+
+bool isAbsolute(std::string_view path) {
+ return !path.empty() && path[0] == '/';
+}
+
+std::string normalize(std::string_view path) {
+ if (path.empty()) {
+ return {};
+ }
+ if (path.starts_with("../"sv)) {
+ return {};
+ }
+
+ std::string result;
+ if (isAbsolute(path)) {
+ path.remove_prefix(1);
+ } else {
+ char buffer[PATH_MAX];
+ if (!::getcwd(buffer, sizeof(buffer))) {
+ return {};
+ }
+ result += buffer;
+ }
+
+ size_t start = 0;
+ size_t end = 0;
+ for (; end != path.npos; start = end + 1) {
+ end = path.find('/', start);
+ // Next component, excluding the separator
+ auto part = path.substr(start, end - start);
+ if (part.empty() || part == "."sv) {
+ continue;
+ }
+ if (part == ".."sv) {
+ if (result.empty()) {
+ return {};
+ }
+ auto lastPos = result.rfind('/');
+ if (lastPos == result.npos) {
+ result.clear();
+ } else {
+ result.resize(lastPos);
+ }
+ continue;
+ }
+ result += '/';
+ result += part;
+ }
+
+ return result;
+}
+
+std::string_view basename(std::string_view path) {
+ if (path.empty()) {
+ return {};
+ }
+ if (path == "/"sv) {
+ return "/"sv;
+ }
+ auto pos = path.rfind('/');
+ while (!path.empty() && pos == path.size() - 1) {
+ path.remove_suffix(1);
+ pos = path.rfind('/');
+ }
+ if (pos == path.npos) {
+ return path.empty() ? "/"sv : path;
+ }
+ return path.substr(pos + 1);
+}
+
+std::string_view dirname(std::string_view path) {
+ if (path.empty()) {
+ return {};
+ }
+ if (path == "/"sv) {
+ return "/"sv;
+ }
+ const auto pos = path.rfind('/');
+ if (pos == 0) {
+ return "/"sv;
+ }
+ if (pos == path.npos) {
+ return "."sv;
+ }
+ return path.substr(0, pos);
+}
+
+details::CStrWrapper::CStrWrapper(std::string_view sv) {
+ if (sv[sv.size()] == '\0') {
+ mCstr = sv.data();
+ } else {
+ mCopy.emplace(sv);
+ mCstr = mCopy->c_str();
+ }
+}
+
+std::optional<bool> isEmptyDir(std::string_view dir) {
+ const auto d = std::unique_ptr<DIR, decltype(&::closedir)>{::opendir(c_str(dir)), ::closedir};
+ if (!d) {
+ if (errno == EPERM || errno == EACCES) {
+ return std::nullopt;
+ }
+ return false;
+ }
+ while (auto entry = ::readdir(d.get())) {
+ if (entry->d_type != DT_DIR) {
+ return false;
+ }
+ if (entry->d_name != "."sv && entry->d_name != ".."sv) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool startsWith(std::string_view path, std::string_view prefix) {
+ if (!base::StartsWith(path, prefix)) {
+ return false;
+ }
+ return path.size() == prefix.size() || path[prefix.size()] == '/';
+}
+
+} // namespace android::incremental::path
diff --git a/services/incremental/path.h b/services/incremental/path.h
new file mode 100644
index 0000000..a1f4b8e
--- /dev/null
+++ b/services/incremental/path.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <optional>
+#include <string>
+#include <string_view>
+
+namespace android::incremental::path {
+
+namespace details {
+
+class CStrWrapper {
+public:
+ CStrWrapper(std::string_view sv);
+
+ CStrWrapper(const CStrWrapper&) = delete;
+ void operator=(const CStrWrapper&) = delete;
+ CStrWrapper(CStrWrapper&&) = delete;
+ void operator=(CStrWrapper&&) = delete;
+
+ const char* get() const { return mCstr; }
+ operator const char*() const { return get(); }
+
+private:
+ const char* mCstr;
+ std::optional<std::string> mCopy;
+};
+
+void append_next_path(std::string& res, std::string_view c);
+
+} // namespace details
+
+//
+// An std::map<> comparator that makes all nested paths to be ordered before the parents.
+//
+
+struct PathCharsLess {
+ bool operator()(char l, char r) const;
+};
+
+struct PathLess {
+ using is_transparent = void;
+ bool operator()(std::string_view l, std::string_view r) const;
+};
+
+//
+// Returns a zero-terminated version of a passed string view
+// Only makes a copy if it wasn't zero-terminated already
+// Useful for passing string view parameters to system functions.
+//
+inline details::CStrWrapper c_str(std::string_view sv) {
+ return {sv};
+}
+
+bool isAbsolute(std::string_view path);
+std::string normalize(std::string_view path);
+std::string_view dirname(std::string_view path);
+std::string_view basename(std::string_view path);
+std::optional<bool> isEmptyDir(std::string_view dir);
+bool startsWith(std::string_view path, std::string_view prefix);
+
+template <class... Paths>
+std::string join(std::string_view first, std::string_view second, Paths&&... paths) {
+ std::string result;
+ {
+ using std::size;
+ result.reserve(first.size() + second.size() + 1 + (sizeof...(paths) + ... + size(paths)));
+ }
+ result.assign(first);
+ (details::append_next_path(result, second), ..., details::append_next_path(result, paths));
+ return result;
+}
+
+} // namespace android::incremental::path
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
new file mode 100644
index 0000000..f6b123d
--- /dev/null
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2019 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-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <binder/ParcelFileDescriptor.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <utils/Log.h>
+
+#include <future>
+
+#include "IncrementalService.h"
+#include "Metadata.pb.h"
+#include "ServiceWrappers.h"
+
+using namespace testing;
+using namespace android::incremental;
+using namespace std::literals;
+using testing::_;
+using testing::Invoke;
+using testing::NiceMock;
+
+#undef LOG_TAG
+#define LOG_TAG "IncrementalServiceTest"
+
+using namespace android::incfs;
+using namespace android::content::pm;
+
+namespace android::os::incremental {
+
+class MockVoldService : public VoldServiceWrapper {
+public:
+ MOCK_CONST_METHOD4(mountIncFs,
+ binder::Status(const std::string& imagePath, const std::string& targetDir,
+ int32_t flags,
+ IncrementalFileSystemControlParcel* _aidl_return));
+ MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
+ MOCK_CONST_METHOD2(bindMount,
+ binder::Status(const std::string& sourceDir, const std::string& argetDir));
+
+ void mountIncFsFails() {
+ ON_CALL(*this, mountIncFs(_, _, _, _))
+ .WillByDefault(
+ Return(binder::Status::fromExceptionCode(1, String8("failed to mount"))));
+ }
+ void mountIncFsInvalidControlParcel() {
+ ON_CALL(*this, mountIncFs(_, _, _, _))
+ .WillByDefault(Invoke(this, &MockVoldService::getInvalidControlParcel));
+ }
+ void mountIncFsSuccess() {
+ ON_CALL(*this, mountIncFs(_, _, _, _))
+ .WillByDefault(Invoke(this, &MockVoldService::incFsSuccess));
+ }
+ void bindMountFails() {
+ ON_CALL(*this, bindMount(_, _))
+ .WillByDefault(Return(
+ binder::Status::fromExceptionCode(1, String8("failed to bind-mount"))));
+ }
+ void bindMountSuccess() {
+ ON_CALL(*this, bindMount(_, _)).WillByDefault(Return(binder::Status::ok()));
+ }
+ binder::Status getInvalidControlParcel(const std::string& imagePath,
+ const std::string& targetDir, int32_t flags,
+ IncrementalFileSystemControlParcel* _aidl_return) {
+ _aidl_return->cmd = nullptr;
+ _aidl_return->log = nullptr;
+ return binder::Status::ok();
+ }
+ binder::Status incFsSuccess(const std::string& imagePath, const std::string& targetDir,
+ int32_t flags, IncrementalFileSystemControlParcel* _aidl_return) {
+ _aidl_return->cmd = std::make_unique<os::ParcelFileDescriptor>(std::move(cmdFd));
+ _aidl_return->log = std::make_unique<os::ParcelFileDescriptor>(std::move(logFd));
+ return binder::Status::ok();
+ }
+
+private:
+ TemporaryFile cmdFile;
+ TemporaryFile logFile;
+ base::unique_fd cmdFd;
+ base::unique_fd logFd;
+};
+
+class MockIncrementalManager : public IncrementalManagerWrapper {
+public:
+ MOCK_CONST_METHOD5(prepareDataLoader,
+ binder::Status(int32_t mountId, const FileSystemControlParcel& control,
+ const DataLoaderParamsParcel& params,
+ const sp<IDataLoaderStatusListener>& listener,
+ bool* _aidl_return));
+ MOCK_CONST_METHOD2(startDataLoader, binder::Status(int32_t mountId, bool* _aidl_return));
+ MOCK_CONST_METHOD1(destroyDataLoader, binder::Status(int32_t mountId));
+ MOCK_CONST_METHOD3(newFileForDataLoader,
+ binder::Status(int32_t mountId, int64_t inode,
+ const ::std::vector<uint8_t>& metadata));
+ MOCK_CONST_METHOD1(showHealthBlockedUI, binder::Status(int32_t mountId));
+
+ binder::Status prepareDataLoaderOk(int32_t mountId, const FileSystemControlParcel& control,
+ const DataLoaderParamsParcel& params,
+ const sp<IDataLoaderStatusListener>& listener,
+ bool* _aidl_return) {
+ mId = mountId;
+ mListener = listener;
+ *_aidl_return = true;
+ return binder::Status::ok();
+ }
+
+ binder::Status startDataLoaderOk(int32_t mountId, bool* _aidl_return) {
+ *_aidl_return = true;
+ return binder::Status::ok();
+ }
+
+ void prepareDataLoaderFails() {
+ ON_CALL(*this, prepareDataLoader(_, _, _, _, _))
+ .WillByDefault(Return(
+ (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
+ }
+ void prepareDataLoaderSuccess() {
+ ON_CALL(*this, prepareDataLoader(_, _, _, _, _))
+ .WillByDefault(Invoke(this, &MockIncrementalManager::prepareDataLoaderOk));
+ }
+ void startDataLoaderSuccess() {
+ ON_CALL(*this, startDataLoader(_, _))
+ .WillByDefault(Invoke(this, &MockIncrementalManager::startDataLoaderOk));
+ }
+ void setDataLoaderStatusNotReady() {
+ mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_NOT_READY);
+ }
+ void setDataLoaderStatusReady() {
+ mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_READY);
+ }
+
+private:
+ int mId;
+ sp<IDataLoaderStatusListener> mListener;
+};
+
+class MockIncFs : public IncFsWrapper {
+public:
+ MOCK_CONST_METHOD5(makeFile,
+ Inode(Control control, std::string_view name, Inode parent, Size size,
+ std::string_view metadata));
+ MOCK_CONST_METHOD5(makeDir,
+ Inode(Control control, std::string_view name, Inode parent,
+ std::string_view metadata, int mode));
+ MOCK_CONST_METHOD2(getMetadata, RawMetadata(Control control, Inode inode));
+ MOCK_CONST_METHOD4(link,
+ ErrorCode(Control control, Inode item, Inode targetParent,
+ std::string_view name));
+ MOCK_CONST_METHOD3(unlink, ErrorCode(Control control, Inode parent, std::string_view name));
+ MOCK_CONST_METHOD3(writeBlocks,
+ ErrorCode(Control control, const incfs_new_data_block blocks[],
+ int blocksCount));
+
+ void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
+ void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
+ RawMetadata getMountInfoMetadata(Control control, Inode inode) {
+ metadata::Mount m;
+ m.mutable_storage()->set_id(100);
+ m.mutable_loader()->set_package_name("com.test");
+ m.mutable_loader()->set_arguments("com.uri");
+ const auto metadata = m.SerializeAsString();
+ m.mutable_loader()->release_arguments();
+ m.mutable_loader()->release_package_name();
+ return std::vector<char>(metadata.begin(), metadata.end());
+ }
+ RawMetadata getStorageMetadata(Control control, Inode inode) {
+ metadata::Storage st;
+ st.set_id(100);
+ auto metadata = st.SerializeAsString();
+ return std::vector<char>(metadata.begin(), metadata.end());
+ }
+ RawMetadata getBindPointMetadata(Control control, Inode inode) {
+ metadata::BindPoint bp;
+ std::string destPath = "dest";
+ std::string srcPath = "src";
+ bp.set_storage_id(100);
+ bp.set_allocated_dest_path(&destPath);
+ bp.set_allocated_source_subdir(&srcPath);
+ const auto metadata = bp.SerializeAsString();
+ bp.release_source_subdir();
+ bp.release_dest_path();
+ return std::vector<char>(metadata.begin(), metadata.end());
+ }
+};
+
+class MockServiceManager : public ServiceManagerWrapper {
+public:
+ MockServiceManager(std::shared_ptr<MockVoldService> vold,
+ std::shared_ptr<MockIncrementalManager> manager,
+ std::shared_ptr<MockIncFs> incfs)
+ : mVold(vold), mIncrementalManager(manager), mIncFs(incfs) {}
+ std::shared_ptr<VoldServiceWrapper> getVoldService() const override { return mVold; }
+ std::shared_ptr<IncrementalManagerWrapper> getIncrementalManager() const override {
+ return mIncrementalManager;
+ }
+ std::shared_ptr<IncFsWrapper> getIncFs() const override { return mIncFs; }
+
+private:
+ std::shared_ptr<MockVoldService> mVold;
+ std::shared_ptr<MockIncrementalManager> mIncrementalManager;
+ std::shared_ptr<MockIncFs> mIncFs;
+};
+
+// --- IncrementalServiceTest ---
+
+static Inode inode(std::string_view path) {
+ struct stat st;
+ if (::stat(path::c_str(path), &st)) {
+ return -1;
+ }
+ return st.st_ino;
+}
+
+class IncrementalServiceTest : public testing::Test {
+public:
+ void SetUp() override {
+ mVold = std::make_shared<NiceMock<MockVoldService>>();
+ mIncrementalManager = std::make_shared<NiceMock<MockIncrementalManager>>();
+ mIncFs = std::make_shared<NiceMock<MockIncFs>>();
+ MockServiceManager serviceManager = MockServiceManager(mVold, mIncrementalManager, mIncFs);
+ mIncrementalService = std::make_unique<IncrementalService>(serviceManager, mRootDir.path);
+ mDataLoaderParcel.packageName = "com.test";
+ mDataLoaderParcel.staticArgs = "uri";
+ mIncrementalService->onSystemReady();
+ }
+
+ void setUpExistingMountDir(const std::string& rootDir) {
+ const auto dir = rootDir + "/dir1";
+ const auto mountDir = dir + "/mount";
+ const auto backingDir = dir + "/backing_store";
+ const auto storageDir = mountDir + "/st0";
+ ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
+ ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
+ ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
+ ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
+ const auto mountInfoFile = rootDir + "/dir1/mount/.info";
+ const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
+ ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
+ ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
+ ASSERT_GE(inode(mountInfoFile), 0);
+ ASSERT_GE(inode(mountPointsFile), 0);
+ ON_CALL(*mIncFs, getMetadata(_, inode(mountInfoFile)))
+ .WillByDefault(Invoke(mIncFs.get(), &MockIncFs::getMountInfoMetadata));
+ ON_CALL(*mIncFs, getMetadata(_, inode(mountPointsFile)))
+ .WillByDefault(Invoke(mIncFs.get(), &MockIncFs::getBindPointMetadata));
+ ON_CALL(*mIncFs, getMetadata(_, inode(rootDir + "/dir1/mount/st0")))
+ .WillByDefault(Invoke(mIncFs.get(), &MockIncFs::getStorageMetadata));
+ }
+
+protected:
+ std::shared_ptr<NiceMock<MockVoldService>> mVold;
+ std::shared_ptr<NiceMock<MockIncFs>> mIncFs;
+ std::shared_ptr<NiceMock<MockIncrementalManager>> mIncrementalManager;
+ std::unique_ptr<IncrementalService> mIncrementalService;
+ TemporaryDir mRootDir;
+ DataLoaderParamsParcel mDataLoaderParcel;
+};
+
+/*
+TEST_F(IncrementalServiceTest, testBootMountExistingImagesSuccess) {
+ TemporaryDir tempDir;
+ setUpExistingMountDir(tempDir.path);
+ mVold->mountIncFsSuccess();
+ mVold->bindMountSuccess();
+ mIncrementalManager->prepareDataLoaderSuccess();
+ ON_CALL(*mIncrementalManager, destroyDataLoader(_)).WillByDefault(Return(binder::Status::ok()));
+
+ EXPECT_CALL(*mVold, mountIncFs(_, _, _, _)).Times(1);
+ EXPECT_CALL(*mIncrementalManager, prepareDataLoader(_, _, _, _, _)).Times(1);
+
+ MockServiceManager serviceManager = MockServiceManager(mVold, mIncrementalManager, mIncFs);
+ std::unique_ptr<IncrementalService> incrementalService =
+ std::make_unique<IncrementalService>(serviceManager, tempDir.path);
+ auto finished = incrementalService->onSystemReady();
+ if (finished) {
+ finished->wait();
+ }
+}
+*/
+
+TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
+ mVold->mountIncFsFails();
+ EXPECT_CALL(*mIncrementalManager, prepareDataLoader(_, _, _, _, _)).Times(0);
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_LT(storageId, 0);
+}
+
+TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
+ mVold->mountIncFsInvalidControlParcel();
+ EXPECT_CALL(*mIncrementalManager, prepareDataLoader(_, _, _, _, _)).Times(0);
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_LT(storageId, 0);
+}
+
+TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileFails();
+ EXPECT_CALL(*mIncrementalManager, prepareDataLoader(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
+ EXPECT_CALL(*mVold, unmountIncFs(_));
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_LT(storageId, 0);
+}
+
+TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileSuccess();
+ mVold->bindMountFails();
+ EXPECT_CALL(*mIncrementalManager, prepareDataLoader(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
+ EXPECT_CALL(*mVold, unmountIncFs(_));
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_LT(storageId, 0);
+}
+
+TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileSuccess();
+ mVold->bindMountSuccess();
+ mIncrementalManager->prepareDataLoaderFails();
+ EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
+ EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_LT(storageId, 0);
+}
+
+TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileSuccess();
+ mVold->bindMountSuccess();
+ mIncrementalManager->prepareDataLoaderSuccess();
+ EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
+ EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_GE(storageId, 0);
+ mIncrementalService->deleteStorage(storageId);
+}
+
+TEST_F(IncrementalServiceTest, testOnStatusNotReady) {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileSuccess();
+ mVold->bindMountSuccess();
+ mIncrementalManager->prepareDataLoaderSuccess();
+ EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
+ EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_GE(storageId, 0);
+ mIncrementalManager->setDataLoaderStatusNotReady();
+}
+
+TEST_F(IncrementalServiceTest, testStartDataLoaderSuccess) {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileSuccess();
+ mVold->bindMountSuccess();
+ mIncrementalManager->prepareDataLoaderSuccess();
+ mIncrementalManager->startDataLoaderSuccess();
+ EXPECT_CALL(*mIncrementalManager, destroyDataLoader(_));
+ EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_GE(storageId, 0);
+ mIncrementalManager->setDataLoaderStatusReady();
+ ASSERT_TRUE(mIncrementalService->startLoading(storageId));
+}
+
+TEST_F(IncrementalServiceTest, testMakeDirectory) {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileSuccess();
+ mVold->bindMountSuccess();
+ mIncrementalManager->prepareDataLoaderSuccess();
+ mIncrementalManager->startDataLoaderSuccess();
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew);
+ std::string_view dir_path("test");
+ EXPECT_CALL(*mIncFs, makeDir(_, dir_path, _, _, _));
+ int fileIno = mIncrementalService->makeDir(storageId, dir_path, "");
+ ASSERT_GE(fileIno, 0);
+}
+
+TEST_F(IncrementalServiceTest, testMakeDirectoryNoParent) {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileSuccess();
+ mVold->bindMountSuccess();
+ mIncrementalManager->prepareDataLoaderSuccess();
+ mIncrementalManager->startDataLoaderSuccess();
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew);
+ std::string_view first("first");
+ std::string_view second("second");
+ std::string dir_path = std::string(first) + "/" + std::string(second);
+ EXPECT_CALL(*mIncFs, makeDir(_, first, _, _, _)).Times(0);
+ EXPECT_CALL(*mIncFs, makeDir(_, second, _, _, _)).Times(0);
+ int fileIno = mIncrementalService->makeDir(storageId, dir_path, "");
+ ASSERT_LT(fileIno, 0);
+}
+
+TEST_F(IncrementalServiceTest, testMakeDirectories) {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileSuccess();
+ mVold->bindMountSuccess();
+ mIncrementalManager->prepareDataLoaderSuccess();
+ mIncrementalManager->startDataLoaderSuccess();
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew);
+ std::string_view first("first");
+ std::string_view second("second");
+ std::string_view third("third");
+ InSequence seq;
+ EXPECT_CALL(*mIncFs, makeDir(_, first, _, _, _));
+ EXPECT_CALL(*mIncFs, makeDir(_, second, _, _, _));
+ EXPECT_CALL(*mIncFs, makeDir(_, third, _, _, _));
+ std::string dir_path =
+ std::string(first) + "/" + std::string(second) + "/" + std::string(third);
+ int fileIno = mIncrementalService->makeDirs(storageId, dir_path, "");
+ ASSERT_GE(fileIno, 0);
+}
+} // namespace android::os::incremental
diff --git a/services/incremental/test/path_test.cpp b/services/incremental/test/path_test.cpp
new file mode 100644
index 0000000..cbe479e1
--- /dev/null
+++ b/services/incremental/test/path_test.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 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 "../path.h"
+
+#include <gtest/gtest.h>
+
+using namespace std::literals;
+
+namespace android::incremental::path {
+
+TEST(Path, Normalize) {
+ EXPECT_STREQ("", normalize("").c_str());
+ EXPECT_STREQ("/data/app/com.snapchat.android-evzhnJDgPOq8VcxwEkSY5g==/base.apk",
+ normalize("/data/app/com.snapchat.android-evzhnJDgPOq8VcxwEkSY5g==/base.apk")
+ .c_str());
+ EXPECT_STREQ("/a/b", normalize("/a/c/../b").c_str());
+}
+
+TEST(Path, Comparator) {
+ EXPECT_TRUE(PathLess()("/a", "/aa"));
+ EXPECT_TRUE(PathLess()("/a/b", "/aa/b"));
+ EXPECT_TRUE(PathLess()("/a", "/a/b"));
+ EXPECT_TRUE(PathLess()("/a/b"sv, "/a\0"sv));
+ EXPECT_TRUE(!PathLess()("/aa/b", "/a/b"));
+ EXPECT_TRUE(!PathLess()("/a/b", "/a/b"));
+ EXPECT_TRUE(!PathLess()("/a/b", "/a"));
+}
+
+} // namespace android::incremental::path
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index f05bbe2..50ae376 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -16,6 +16,7 @@
package com.android.server;
+import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
@@ -42,8 +43,8 @@
import android.database.sqlite.SQLiteGlobal;
import android.hardware.display.DisplayManagerInternal;
import android.net.ConnectivityModuleConnector;
+import android.net.ITetheringConnector;
import android.net.NetworkStackClient;
-import android.net.TetheringManager;
import android.os.BaseBundle;
import android.os.Binder;
import android.os.Build;
@@ -2267,8 +2268,14 @@
t.traceBegin("StartTethering");
try {
- // Tethering must start after ConnectivityService and NetworkStack.
- TetheringManager.getInstance().start();
+ // TODO: hide implementation details, b/146312721.
+ ConnectivityModuleConnector.getInstance().startModuleService(
+ ITetheringConnector.class.getName(),
+ PERMISSION_MAINLINE_NETWORK_STACK, service -> {
+ ServiceManager.addService(Context.TETHERING_SERVICE, service,
+ false /* allowIsolated */,
+ DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
+ });
} catch (Throwable e) {
reportWtf("starting Tethering", e);
}
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 3babb0b..9c7cfc1 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -10,14 +10,12 @@
srcs: [
":net-module-utils-srcs",
":services.net-sources",
- ":tethering-manager",
],
static_libs: [
"dnsresolver_aidl_interface-V2-java",
"netd_aidl_interface-unstable-java",
"netlink-client",
"networkstack-client",
- "tethering-client",
],
}
@@ -25,8 +23,6 @@
name: "services-tethering-shared-srcs",
srcs: [
":framework-annotations",
- "java/android/net/ConnectivityModuleConnector.java",
- "java/android/net/NetworkStackClient.java",
"java/android/net/util/NetdService.java",
"java/android/net/util/NetworkConstants.java",
],
diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
index 1e27007..f0758dd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
@@ -44,7 +44,6 @@
import android.app.IActivityManager;
import android.app.IUidObserver;
import android.app.usage.UsageStatsManager;
-import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -82,6 +81,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
@@ -690,11 +690,11 @@
entries.add(new OpEntry(
AppOpsManager.OP_ACCESS_NOTIFICATIONS,
AppOpsManager.MODE_IGNORED,
- new Pair[0]));
+ Collections.emptyMap()));
entries.add(new OpEntry(
AppStateTracker.TARGET_OP,
AppOpsManager.MODE_IGNORED,
- new Pair[0]));
+ Collections.emptyMap()));
ops.add(new PackageOps(PACKAGE_1, UID_1, entries));
@@ -703,7 +703,7 @@
entries.add(new OpEntry(
AppStateTracker.TARGET_OP,
AppOpsManager.MODE_IGNORED,
- new Pair[0]));
+ Collections.emptyMap()));
ops.add(new PackageOps(PACKAGE_2, UID_2, entries));
@@ -712,7 +712,7 @@
entries.add(new OpEntry(
AppStateTracker.TARGET_OP,
AppOpsManager.MODE_ALLOWED,
- new Pair[0]));
+ Collections.emptyMap()));
ops.add(new PackageOps(PACKAGE_1, UID_10_1, entries));
@@ -721,11 +721,11 @@
entries.add(new OpEntry(
AppStateTracker.TARGET_OP,
AppOpsManager.MODE_IGNORED,
- new Pair[0]));
+ Collections.emptyMap()));
entries.add(new OpEntry(
AppOpsManager.OP_ACCESS_NOTIFICATIONS,
AppOpsManager.MODE_IGNORED,
- new Pair[0]));
+ Collections.emptyMap()));
ops.add(new PackageOps(PACKAGE_3, UID_10_3, entries));
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index 45de451..9251031 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -61,6 +61,7 @@
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import android.app.ActivityManagerInternal;
@@ -70,7 +71,11 @@
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
+import android.hardware.TriggerEvent;
+import android.hardware.TriggerEventListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.net.ConnectivityManager;
@@ -131,6 +136,8 @@
@Mock
private PowerManagerInternal mPowerManagerInternal;
@Mock
+ private Sensor mMotionSensor;
+ @Mock
private SensorManager mSensorManager;
class InjectorForTest extends DeviceIdleController.Injector {
@@ -203,6 +210,11 @@
}
@Override
+ Sensor getMotionSensor() {
+ return mMotionSensor;
+ }
+
+ @Override
PowerManager getPowerManager() {
return mPowerManager;
}
@@ -1787,22 +1799,36 @@
}
@Test
- public void testStationaryDetection_QuickDozeOn() {
+ public void testStationaryDetection_QuickDozeOn_NoMotion() {
+ // Short timeout for testing.
+ mConstants.MOTION_INACTIVE_TIMEOUT = 6000L;
+ doReturn(Sensor.REPORTING_MODE_ONE_SHOT).when(mMotionSensor).getReportingMode();
+ doReturn(true).when(mSensorManager)
+ .requestTriggerSensor(eq(mDeviceIdleController.mMotionListener), eq(mMotionSensor));
setAlarmSoon(false);
enterDeepState(STATE_QUICK_DOZE_DELAY);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_IDLE);
// Quick doze progression through states, so time should have increased appropriately.
mInjector.nowElapsed += mConstants.QUICK_DOZE_DELAY_TIMEOUT;
- final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListener = ArgumentCaptor
+ final ArgumentCaptor<AlarmManager.OnAlarmListener> motionAlarmListener = ArgumentCaptor
.forClass(AlarmManager.OnAlarmListener.class);
+ final ArgumentCaptor<AlarmManager.OnAlarmListener> motionRegistrationAlarmListener =
+ ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class);
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), eq("DeviceIdleController.motion"),
- alarmListener.capture(), any());
+ motionAlarmListener.capture(), any());
+ doNothing().when(mAlarmManager).set(anyInt(), anyLong(),
+ eq("DeviceIdleController.motion_registration"),
+ motionRegistrationAlarmListener.capture(), any());
StationaryListenerForTest stationaryListener = new StationaryListenerForTest();
+ spyOn(stationaryListener);
+ InOrder inOrder = inOrder(stationaryListener);
stationaryListener.motionExpected = true;
mDeviceIdleController.registerStationaryListener(stationaryListener);
+ inOrder.verify(stationaryListener, timeout(1000L).times(1))
+ .onDeviceStationaryChanged(eq(false));
assertFalse(stationaryListener.isStationary);
// Go to IDLE_MAINTENANCE
@@ -1814,13 +1840,17 @@
mDeviceIdleController.stepIdleStateLocked("testing");
// Now enough time has passed.
- mInjector.nowElapsed += mConstants.MOTION_INACTIVE_TIMEOUT / 2;
+ mInjector.nowElapsed += mConstants.MOTION_INACTIVE_TIMEOUT;
stationaryListener.motionExpected = false;
- alarmListener.getValue().onAlarm();
+ motionAlarmListener.getValue().onAlarm();
+ inOrder.verify(stationaryListener, timeout(1000L).times(1))
+ .onDeviceStationaryChanged(eq(true));
assertTrue(stationaryListener.isStationary);
stationaryListener.motionExpected = true;
- mDeviceIdleController.mMotionListener.onSensorChanged(null);
+ mDeviceIdleController.mMotionListener.onTrigger(null);
+ inOrder.verify(stationaryListener, timeout(1000L).times(1))
+ .onDeviceStationaryChanged(eq(false));
assertFalse(stationaryListener.isStationary);
// Since we're in quick doze, the device shouldn't stop idling.
@@ -1829,18 +1859,116 @@
// Go to IDLE_MAINTENANCE
mDeviceIdleController.stepIdleStateLocked("testing");
+ motionRegistrationAlarmListener.getValue().onAlarm();
mInjector.nowElapsed += mConstants.MOTION_INACTIVE_TIMEOUT / 2;
// Back to IDLE
+ stationaryListener.motionExpected = false;
mDeviceIdleController.stepIdleStateLocked("testing");
+ verify(mSensorManager,
+ timeout(mConstants.MOTION_INACTIVE_TIMEOUT).times(2))
+ .requestTriggerSensor(eq(mDeviceIdleController.mMotionListener), eq(mMotionSensor));
// Now enough time has passed.
- mInjector.nowElapsed += mConstants.MOTION_INACTIVE_TIMEOUT / 2;
- stationaryListener.motionExpected = false;
- alarmListener.getValue().onAlarm();
+ mInjector.nowElapsed += mConstants.MOTION_INACTIVE_TIMEOUT;
+ motionAlarmListener.getValue().onAlarm();
+ inOrder.verify(stationaryListener,
+ timeout(mConstants.MOTION_INACTIVE_TIMEOUT).times(1))
+ .onDeviceStationaryChanged(eq(true));
assertTrue(stationaryListener.isStationary);
}
+ @Test
+ public void testStationaryDetection_QuickDozeOn_OneShot() {
+ // Short timeout for testing.
+ mConstants.MOTION_INACTIVE_TIMEOUT = 6000L;
+ doReturn(Sensor.REPORTING_MODE_ONE_SHOT).when(mMotionSensor).getReportingMode();
+ setAlarmSoon(false);
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ mDeviceIdleController.stepIdleStateLocked("testing");
+ verifyStateConditions(STATE_IDLE);
+ // Quick doze progression through states, so time should have increased appropriately.
+ mInjector.nowElapsed += mConstants.QUICK_DOZE_DELAY_TIMEOUT;
+ final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListener = ArgumentCaptor
+ .forClass(AlarmManager.OnAlarmListener.class);
+ doNothing().when(mAlarmManager)
+ .set(anyInt(), anyLong(), eq("DeviceIdleController.motion"), any(), any());
+ doNothing().when(mAlarmManager).set(anyInt(), anyLong(),
+ eq("DeviceIdleController.motion_registration"),
+ alarmListener.capture(), any());
+ ArgumentCaptor<TriggerEventListener> listenerCaptor =
+ ArgumentCaptor.forClass(TriggerEventListener.class);
+
+ StationaryListenerForTest stationaryListener = new StationaryListenerForTest();
+ spyOn(stationaryListener);
+ InOrder inOrder = inOrder(stationaryListener, mSensorManager);
+
+ stationaryListener.motionExpected = true;
+ mDeviceIdleController.registerStationaryListener(stationaryListener);
+ inOrder.verify(stationaryListener, timeout(1000L).times(1))
+ .onDeviceStationaryChanged(eq(false));
+ assertFalse(stationaryListener.isStationary);
+ inOrder.verify(mSensorManager)
+ .requestTriggerSensor(listenerCaptor.capture(), eq(mMotionSensor));
+ final TriggerEventListener listener = listenerCaptor.getValue();
+
+ // Trigger motion
+ listener.onTrigger(mock(TriggerEvent.class));
+ inOrder.verify(stationaryListener, timeout(1000L).times(1))
+ .onDeviceStationaryChanged(eq(false));
+
+ // Make sure the listener is re-registered.
+ alarmListener.getValue().onAlarm();
+ inOrder.verify(mSensorManager).requestTriggerSensor(eq(listener), eq(mMotionSensor));
+ }
+
+ @Test
+ public void testStationaryDetection_QuickDozeOn_MultiShot() {
+ // Short timeout for testing.
+ mConstants.MOTION_INACTIVE_TIMEOUT = 6000L;
+ doReturn(Sensor.REPORTING_MODE_CONTINUOUS).when(mMotionSensor).getReportingMode();
+ setAlarmSoon(false);
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ mDeviceIdleController.stepIdleStateLocked("testing");
+ verifyStateConditions(STATE_IDLE);
+ // Quick doze progression through states, so time should have increased appropriately.
+ mInjector.nowElapsed += mConstants.QUICK_DOZE_DELAY_TIMEOUT;
+ final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListener = ArgumentCaptor
+ .forClass(AlarmManager.OnAlarmListener.class);
+ doNothing().when(mAlarmManager)
+ .set(anyInt(), anyLong(), eq("DeviceIdleController.motion"), any(), any());
+ doNothing().when(mAlarmManager).set(anyInt(), anyLong(),
+ eq("DeviceIdleController.motion_registration"),
+ alarmListener.capture(), any());
+ ArgumentCaptor<SensorEventListener> listenerCaptor =
+ ArgumentCaptor.forClass(SensorEventListener.class);
+
+ StationaryListenerForTest stationaryListener = new StationaryListenerForTest();
+ spyOn(stationaryListener);
+ InOrder inOrder = inOrder(stationaryListener, mSensorManager);
+
+ stationaryListener.motionExpected = true;
+ mDeviceIdleController.registerStationaryListener(stationaryListener);
+ inOrder.verify(stationaryListener, timeout(1000L).times(1))
+ .onDeviceStationaryChanged(eq(false));
+ assertFalse(stationaryListener.isStationary);
+ inOrder.verify(mSensorManager)
+ .registerListener(listenerCaptor.capture(), eq(mMotionSensor),
+ eq(SensorManager.SENSOR_DELAY_NORMAL));
+ final SensorEventListener listener = listenerCaptor.getValue();
+
+ // Trigger motion
+ listener.onSensorChanged(mock(SensorEvent.class));
+ inOrder.verify(stationaryListener, timeout(1000L).times(1))
+ .onDeviceStationaryChanged(eq(false));
+
+ // Make sure the listener is re-registered.
+ alarmListener.getValue().onAlarm();
+ inOrder.verify(mSensorManager)
+ .registerListener(eq(listener), eq(mMotionSensor),
+ eq(SensorManager.SENSOR_DELAY_NORMAL));
+ }
+
private void enterDeepState(int state) {
switch (state) {
case STATE_ACTIVE:
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
index fa209a7a..529339e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -20,6 +20,7 @@
import static android.app.AppOpsManager.MODE_ERRORED;
import static android.app.AppOpsManager.MODE_FOREGROUND;
import static android.app.AppOpsManager.OP_COARSE_LOCATION;
+import static android.app.AppOpsManager.OP_FLAGS_ALL;
import static android.app.AppOpsManager.OP_READ_SMS;
import static android.app.AppOpsManager.OP_WIFI_SCAN;
import static android.app.AppOpsManager.OP_WRITE_SMS;
@@ -465,11 +466,11 @@
assertWithMessage("Unexpected mode").that(mode).isEqualTo(opEntry.getMode());
if (minMillis > 0) {
assertWithMessage("Unexpected timestamp")
- .that(opEntry.getTime()).isAtLeast(minMillis);
+ .that(opEntry.getLastAccessTime(OP_FLAGS_ALL)).isAtLeast(minMillis);
}
if (minRejectMillis > 0) {
- assertWithMessage("Unexpected rejection timestamp")
- .that(opEntry.getRejectTime()).isAtLeast(minRejectMillis);
+ assertWithMessage("Unexpected rejection timestamp").that(
+ opEntry.getLastRejectTime(OP_FLAGS_ALL)).isAtLeast(minRejectMillis);
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleBinarySerializerTest.java b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleBinarySerializerTest.java
index 901277d..2304bc6 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleBinarySerializerTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleBinarySerializerTest.java
@@ -47,13 +47,18 @@
import org.junit.runners.JUnit4;
import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
import java.util.Optional;
@RunWith(JUnit4.class)
public class RuleBinarySerializerTest {
+ private static final String SAMPLE_INSTALLER_NAME = "com.test.installer";
+ private static final String SAMPLE_INSTALLER_CERT = "installer_cert";
+
private static final String COMPOUND_FORMULA_START_BITS =
getBits(COMPOUND_FORMULA_START, SEPARATOR_BITS);
private static final String COMPOUND_FORMULA_END_BITS =
@@ -67,6 +72,9 @@
private static final String PACKAGE_NAME = getBits(AtomicFormula.PACKAGE_NAME, KEY_BITS);
private static final String APP_CERTIFICATE = getBits(AtomicFormula.APP_CERTIFICATE, KEY_BITS);
+ private static final String INSTALLER_NAME = getBits(AtomicFormula.INSTALLER_NAME, KEY_BITS);
+ private static final String INSTALLER_CERTIFICATE =
+ getBits(AtomicFormula.INSTALLER_CERTIFICATE, KEY_BITS);
private static final String VERSION_CODE = getBits(AtomicFormula.VERSION_CODE, KEY_BITS);
private static final String PRE_INSTALLED = getBits(AtomicFormula.PRE_INSTALLED, KEY_BITS);
@@ -83,17 +91,28 @@
getBytes(getBits(DEFAULT_FORMAT_VERSION, FORMAT_VERSION_BITS));
@Test
- public void testBinaryString_serializeEmptyRule() throws Exception {
- Rule rule = null;
+ public void testBinaryString_serializeNullRules() {
RuleSerializer binarySerializer = new RuleBinarySerializer();
assertExpectException(
RuleSerializeException.class,
- /* expectedExceptionMessageRegex= */ "Null rule can not be serialized",
+ /* expectedExceptionMessageRegex= */
+ "Index buckets cannot be created for null rule list.",
() ->
- binarySerializer.serialize(
- Collections.singletonList(rule),
- /* formatVersion= */ Optional.empty()));
+ binarySerializer.serialize(null, /* formatVersion= */ Optional.empty()));
+ }
+
+ @Test
+ public void testBinaryString_emptyRules() throws Exception {
+ ByteArrayOutputStream expectedArrayOutputStream = new ByteArrayOutputStream();
+ expectedArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+ binarySerializer.serialize(
+ Collections.emptyList(), /* formatVersion= */ Optional.empty(), outputStream);
+
+ assertThat(outputStream.toByteArray()).isEqualTo(expectedArrayOutputStream.toByteArray());
}
@Test
@@ -381,7 +400,7 @@
assertExpectException(
RuleSerializeException.class,
- /* expectedExceptionMessageRegex= */ "Invalid formula type",
+ /* expectedExceptionMessageRegex= */ "Malformed rule identified.",
() ->
binarySerializer.serialize(
Collections.singletonList(rule),
@@ -402,6 +421,165 @@
assertThat(actualRules).isEqualTo(expectedRules);
}
+ @Test
+ public void testBinaryString_serializeComplexCompoundFormula_indexingOrderValid()
+ throws Exception {
+ String packageNameA = "aaa";
+ String packageNameB = "bbb";
+ String packageNameC = "ccc";
+ String appCert1 = "cert1";
+ String appCert2 = "cert2";
+ String appCert3 = "cert3";
+ Rule installerRule =
+ new Rule(
+ new CompoundFormula(
+ CompoundFormula.AND,
+ Arrays.asList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.INSTALLER_NAME,
+ SAMPLE_INSTALLER_NAME,
+ /* isHashedValue= */ false),
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.INSTALLER_CERTIFICATE,
+ SAMPLE_INSTALLER_CERT,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+
+ RuleSerializer binarySerializer = new RuleBinarySerializer();
+ List<Rule> ruleList = new ArrayList();
+ ruleList.add(getRuleWithAppCertificateAndSampleInstallerName(appCert3));
+ ruleList.add(getRuleWithAppCertificateAndSampleInstallerName(appCert2));
+ ruleList.add(getRuleWithAppCertificateAndSampleInstallerName(appCert1));
+ ruleList.add(getRuleWithPackageNameAndSampleInstallerName(packageNameB));
+ ruleList.add(getRuleWithPackageNameAndSampleInstallerName(packageNameC));
+ ruleList.add(getRuleWithPackageNameAndSampleInstallerName(packageNameA));
+ ruleList.add(installerRule);
+ byte[] actualRules =
+ binarySerializer.serialize(ruleList, /* formatVersion= */ Optional.empty());
+
+
+ // Note that ordering is important here and the test verifies that the rules are written
+ // in this sorted order.
+ ByteArrayOutputStream expectedArrayOutputStream = new ByteArrayOutputStream();
+ expectedArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
+ expectedArrayOutputStream.write(
+ getBytes(getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(
+ packageNameA)));
+ expectedArrayOutputStream.write(
+ getBytes(getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(
+ packageNameB)));
+ expectedArrayOutputStream.write(
+ getBytes(getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(
+ packageNameC)));
+ expectedArrayOutputStream.write(
+ getBytes(getSerializedCompoundRuleWithCertificateNameAndSampleInstallerName(
+ appCert1)));
+ expectedArrayOutputStream.write(
+ getBytes(getSerializedCompoundRuleWithCertificateNameAndSampleInstallerName(
+ appCert2)));
+ expectedArrayOutputStream.write(
+ getBytes(getSerializedCompoundRuleWithCertificateNameAndSampleInstallerName(
+ appCert3)));
+ String expectedBitsForInstallerRule =
+ START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + AND
+ + ATOMIC_FORMULA_START_BITS
+ + INSTALLER_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(SAMPLE_INSTALLER_NAME.length(), VALUE_SIZE_BITS)
+ + getValueBits(SAMPLE_INSTALLER_NAME)
+ + ATOMIC_FORMULA_START_BITS
+ + INSTALLER_CERTIFICATE
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(SAMPLE_INSTALLER_CERT.length(), VALUE_SIZE_BITS)
+ + getValueBits(SAMPLE_INSTALLER_CERT)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ expectedArrayOutputStream.write(getBytes(expectedBitsForInstallerRule));
+
+ assertThat(actualRules).isEqualTo(expectedArrayOutputStream.toByteArray());
+ }
+
+ private Rule getRuleWithPackageNameAndSampleInstallerName(String packageName) {
+ return new Rule(
+ new CompoundFormula(
+ CompoundFormula.AND,
+ Arrays.asList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false),
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.INSTALLER_NAME,
+ SAMPLE_INSTALLER_NAME,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+ }
+
+ private String getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(
+ String packageName) {
+ return START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + AND
+ + ATOMIC_FORMULA_START_BITS
+ + PACKAGE_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(packageName.length(), VALUE_SIZE_BITS)
+ + getValueBits(packageName)
+ + ATOMIC_FORMULA_START_BITS
+ + INSTALLER_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(SAMPLE_INSTALLER_NAME.length(), VALUE_SIZE_BITS)
+ + getValueBits(SAMPLE_INSTALLER_NAME)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ }
+
+ private Rule getRuleWithAppCertificateAndSampleInstallerName(String certificate) {
+ return new Rule(
+ new CompoundFormula(
+ CompoundFormula.AND,
+ Arrays.asList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.APP_CERTIFICATE,
+ certificate,
+ /* isHashedValue= */ false),
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.INSTALLER_NAME,
+ SAMPLE_INSTALLER_NAME,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+ }
+
+ private String getSerializedCompoundRuleWithCertificateNameAndSampleInstallerName(
+ String appCertificate) {
+ return START_BIT
+ + COMPOUND_FORMULA_START_BITS
+ + AND
+ + ATOMIC_FORMULA_START_BITS
+ + APP_CERTIFICATE
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(appCertificate.length(), VALUE_SIZE_BITS)
+ + getValueBits(appCertificate)
+ + ATOMIC_FORMULA_START_BITS
+ + INSTALLER_NAME
+ + EQ
+ + IS_NOT_HASHED
+ + getBits(SAMPLE_INSTALLER_NAME.length(), VALUE_SIZE_BITS)
+ + getValueBits(SAMPLE_INSTALLER_NAME)
+ + COMPOUND_FORMULA_END_BITS
+ + DENY
+ + END_BIT;
+ }
+
private static Formula getInvalidFormula() {
return new Formula() {
@Override
diff --git a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifierTest.java b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifierTest.java
index 90ec19e..94e11c6 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifierTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifierTest.java
@@ -129,7 +129,7 @@
assertExpectException(
IllegalArgumentException.class,
- /* expectedExceptionMessageRegex= */ "Invalid formula tag type.",
+ /* expectedExceptionMessageRegex= */ "Malformed rule identified.",
() -> splitRulesIntoIndexBuckets(ruleList));
}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/ArrayMapWithHistoryTest.java b/services/tests/servicestests/src/com/android/server/timedetector/ArrayMapWithHistoryTest.java
new file mode 100644
index 0000000..b6eea46
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timedetector/ArrayMapWithHistoryTest.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2019 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.timedetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.util.ArrayMap;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.timezonedetector.ArrayMapWithHistory;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.StringWriter;
+import java.util.concurrent.Callable;
+
+@RunWith(AndroidJUnit4.class)
+public class ArrayMapWithHistoryTest {
+
+ @Test
+ public void testValueHistoryBehavior() {
+ // Create a map that will retain 2 values per key.
+ ArrayMapWithHistory<String, String> historyMap = new ArrayMapWithHistory<>(2 /* history */);
+ ArrayMap<String, String> arrayMap = new ArrayMap<>();
+
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", null));
+
+ assertEquals(0, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertToStringAndDumpNotNull(historyMap);
+
+ putAndCompareReturnValue(historyMap, arrayMap, "K1", "V1");
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", "V1"));
+ compareKeyAtAndValueAtForIndex(0, historyMap, arrayMap);
+
+ assertEquals(1, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertToStringAndDumpNotNull(historyMap);
+
+ // put() a new value for the same key.
+ putAndCompareReturnValue(historyMap, arrayMap, "K1", "V2");
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", "V2"));
+ compareKeyAtAndValueAtForIndex(0, historyMap, arrayMap);
+
+ assertEquals(2, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertToStringAndDumpNotNull(historyMap);
+
+ // put() a new value for the same key. We should have hit the limit of "2 values retained
+ // per key".
+ putAndCompareReturnValue(historyMap, arrayMap, "K1", "V3");
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", "V3"));
+ compareKeyAtAndValueAtForIndex(0, historyMap, arrayMap);
+
+ assertEquals(2, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertToStringAndDumpNotNull(historyMap);
+ }
+
+ @Test
+ public void testMapBehavior() throws Exception {
+ ArrayMapWithHistory<String, String> historyMap = new ArrayMapWithHistory<>(2);
+ ArrayMap<String, String> arrayMap = new ArrayMap<>();
+
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", null), entry("K2", null));
+ assertIndexAccessThrowsException(0, historyMap, arrayMap);
+
+ assertEquals(0, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertEquals(0, historyMap.getHistoryCountForKeyForTests("K2"));
+
+ putAndCompareReturnValue(historyMap, arrayMap, "K1", "V1");
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", "V1"), entry("K2", null));
+ compareKeyAtAndValueAtForIndex(0, historyMap, arrayMap);
+ // TODO Restore after http://b/146563025 is fixed and ArrayMap behaves properly in tests.
+ // assertIndexAccessThrowsException(1, historyMap, arrayMap);
+
+ assertEquals(1, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertToStringAndDumpNotNull(historyMap);
+
+ putAndCompareReturnValue(historyMap, arrayMap, "K2", "V2");
+ compareGetAndSizeForKeys(historyMap, arrayMap, entry("K1", "V1"), entry("K2", "V2"));
+ compareKeyAtAndValueAtForIndex(0, historyMap, arrayMap);
+ compareKeyAtAndValueAtForIndex(1, historyMap, arrayMap);
+ // TODO Restore after http://b/146563025 is fixed and ArrayMap behaves properly in tests.
+ // assertIndexAccessThrowsException(2, historyMap, arrayMap);
+
+ assertEquals(1, historyMap.getHistoryCountForKeyForTests("K1"));
+ assertEquals(1, historyMap.getHistoryCountForKeyForTests("K2"));
+ assertToStringAndDumpNotNull(historyMap);
+ }
+
+ private static String dumpHistoryMap(ArrayMapWithHistory<?, ?> historyMap) {
+ StringWriter stringWriter = new StringWriter();
+ try (IndentingPrintWriter ipw = new IndentingPrintWriter(stringWriter, " ")) {
+ historyMap.dump(ipw);
+ return stringWriter.toString();
+ }
+ }
+
+ private static <K, V> void putAndCompareReturnValue(ArrayMapWithHistory<K, V> historyMap,
+ ArrayMap<K, V> arrayMap, K key, V value) {
+ assertEquals(arrayMap.put(key, value), historyMap.put(key, value));
+ }
+
+ private static class Entry<K, V> {
+ public final K key;
+ public final V value;
+
+ Entry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+ }
+
+ private static <K, V> Entry<K, V> entry(K key, V value) {
+ return new Entry<>(key, value);
+ }
+
+ @SafeVarargs
+ private static <K, V> void compareGetAndSizeForKeys(ArrayMapWithHistory<K, V> historyMap,
+ ArrayMap<K, V> arrayMap, Entry<K, V>... expectedEntries) {
+ for (Entry<K, V> expectedEntry : expectedEntries) {
+ assertEquals(arrayMap.get(expectedEntry.key), historyMap.get(expectedEntry.key));
+ assertEquals(expectedEntry.value, historyMap.get(expectedEntry.key));
+ }
+ assertEquals(arrayMap.size(), historyMap.size());
+ }
+
+ private static void compareKeyAtAndValueAtForIndex(
+ int index, ArrayMapWithHistory<?, ?> historyMap, ArrayMap<?, ?> arrayMap) {
+ assertEquals(arrayMap.keyAt(index), historyMap.keyAt(index));
+ assertEquals(arrayMap.valueAt(index), historyMap.valueAt(index));
+ }
+
+ private static void assertIndexAccessThrowsException(
+ int index, ArrayMapWithHistory<?, ?> historyMap, ArrayMap<?, ?> arrayMap)
+ throws Exception {
+ assertThrowsArrayIndexOutOfBoundsException(
+ "ArrayMap.keyAt(" + index + ")", () -> arrayMap.keyAt(index));
+ assertThrowsArrayIndexOutOfBoundsException(
+ "ArrayMapWithHistory.keyAt(" + index + ")", () -> historyMap.keyAt(index));
+ assertThrowsArrayIndexOutOfBoundsException(
+ "ArrayMap.keyAt(" + index + ")", () -> arrayMap.valueAt(index));
+ assertThrowsArrayIndexOutOfBoundsException(
+ "ArrayMapWithHistory.keyAt(" + index + ")", () -> historyMap.valueAt(index));
+ }
+
+ private static void assertThrowsArrayIndexOutOfBoundsException(
+ String description, Callable<?> callable) throws Exception {
+ try {
+ callable.call();
+ fail("Expected exception for " + description);
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ // This is fine.
+ } catch (Exception e) {
+ // Any other exception is just rethrown.
+ throw e;
+ }
+ }
+
+ private static void assertToStringAndDumpNotNull(ArrayMapWithHistory<?, ?> historyMap) {
+ assertNotNull(historyMap.toString());
+ assertNotNull(dumpHistoryMap(historyMap));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/ReferenceWithHistoryTest.java b/services/tests/servicestests/src/com/android/server/timedetector/ReferenceWithHistoryTest.java
new file mode 100644
index 0000000..ce72499
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timedetector/ReferenceWithHistoryTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2019 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.timedetector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.timezonedetector.ReferenceWithHistory;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.StringWriter;
+
+@RunWith(AndroidJUnit4.class)
+public class ReferenceWithHistoryTest {
+
+ @Test
+ public void testBasicReferenceBehavior() {
+ // Create a reference that will retain 2 history values.
+ ReferenceWithHistory<String> referenceWithHistory =
+ new ReferenceWithHistory<>(2 /* history */);
+ TestRef<String> reference = new TestRef<>();
+
+ // Check unset behavior.
+ compareGet(referenceWithHistory, reference, null);
+ assertNotNull(dumpReferenceWithHistory(referenceWithHistory));
+ compareToString(referenceWithHistory, reference, "null");
+
+ // Try setting null.
+ setAndCompareReturnValue(referenceWithHistory, reference, null);
+ compareGet(referenceWithHistory, reference, null);
+ assertNotNull(dumpReferenceWithHistory(referenceWithHistory));
+ compareToString(referenceWithHistory, reference, "null");
+
+ // Try setting a non-null value.
+ setAndCompareReturnValue(referenceWithHistory, reference, "Foo");
+ compareGet(referenceWithHistory, reference, "Foo");
+ assertNotNull(dumpReferenceWithHistory(referenceWithHistory));
+ compareToString(referenceWithHistory, reference, "Foo");
+
+ // Try setting null again.
+ setAndCompareReturnValue(referenceWithHistory, reference, "Foo");
+ compareGet(referenceWithHistory, reference, "Foo");
+ assertNotNull(dumpReferenceWithHistory(referenceWithHistory));
+ compareToString(referenceWithHistory, reference, "Foo");
+
+ // Try a non-null value again.
+ setAndCompareReturnValue(referenceWithHistory, reference, "Bar");
+ compareGet(referenceWithHistory, reference, "Bar");
+ assertNotNull(dumpReferenceWithHistory(referenceWithHistory));
+ compareToString(referenceWithHistory, reference, "Bar");
+ }
+
+ @Test
+ public void testValueHistoryBehavior() {
+ // Create a reference that will retain 2 history values.
+ ReferenceWithHistory<String> referenceWithHistory =
+ new ReferenceWithHistory<>(2 /* history */);
+ TestRef<String> reference = new TestRef<>();
+
+ // Assert behavior before anything is set.
+ assertEquals(0, referenceWithHistory.getHistoryCount());
+
+ // Set a value (1).
+ setAndCompareReturnValue(referenceWithHistory, reference, "V1");
+ assertEquals(1, referenceWithHistory.getHistoryCount());
+
+ // Set a value (2).
+ setAndCompareReturnValue(referenceWithHistory, reference, "V2");
+ assertEquals(2, referenceWithHistory.getHistoryCount());
+
+ // Set a value (3).
+ // We should have hit the limit of "2 history values retained per key".
+ setAndCompareReturnValue(referenceWithHistory, reference, "V3");
+ assertEquals(2, referenceWithHistory.getHistoryCount());
+ }
+
+ /**
+ * A simple class that has the same behavior as ReferenceWithHistory without the history. Used
+ * in tests for comparison.
+ */
+ private static class TestRef<V> {
+ private V mValue;
+
+ public V get() {
+ return mValue;
+ }
+
+ public V set(V value) {
+ V previous = mValue;
+ mValue = value;
+ return previous;
+ }
+
+ public String toString() {
+ return String.valueOf(mValue);
+ }
+ }
+
+ private static void compareGet(
+ ReferenceWithHistory<?> referenceWithHistory, TestRef<?> reference, Object value) {
+ assertEquals(reference.get(), referenceWithHistory.get());
+ assertEquals(value, reference.get());
+ }
+
+ private static <T> void setAndCompareReturnValue(
+ ReferenceWithHistory<T> referenceWithHistory, TestRef<T> reference, T newValue) {
+ assertEquals(reference.set(newValue), referenceWithHistory.set(newValue));
+ }
+
+ private static void compareToString(
+ ReferenceWithHistory<?> referenceWithHistory, TestRef<?> reference, String expected) {
+ assertEquals(reference.toString(), referenceWithHistory.toString());
+ assertEquals(expected, referenceWithHistory.toString());
+ }
+
+ private static String dumpReferenceWithHistory(ReferenceWithHistory<?> referenceWithHistory) {
+ StringWriter stringWriter = new StringWriter();
+ try (IndentingPrintWriter ipw = new IndentingPrintWriter(stringWriter, " ")) {
+ referenceWithHistory.dump(ipw);
+ return stringWriter.toString();
+ }
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 12074dc3..3eee031 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -44,6 +44,7 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
import java.util.Arrays;
@@ -57,6 +58,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
private ActivityMetricsLogger mActivityMetricsLogger;
private ActivityMetricsLogger.LaunchingState mLaunchingState;
@@ -116,11 +118,18 @@
return argThat(new ActivityRecordMatcher(record));
}
- static <T> T verifyAsync(T mock) {
+ private <T> T verifyAsync(T mock) {
+ // With WindowTestRunner, all test methods are inside WM lock, so we have to unblock any
+ // messages that are waiting for the lock.
+ waitHandlerIdle(mService.mH);
// AMLO callbacks happen on a separate thread than AML calls, so we need to use a timeout.
return verify(mock, timeout(TimeUnit.SECONDS.toMillis(5)));
}
+ private void verifyOnActivityLaunchFinished(ActivityRecord activity) {
+ verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(activity), anyLong());
+ }
+
private void onIntentStarted(Intent intent) {
notifyActivityLaunching(intent);
@@ -159,7 +168,7 @@
notifyTransitionStarting(mTopActivity);
notifyWindowsDrawn(mTopActivity);
- verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(mTopActivity), anyLong());
+ verifyOnActivityLaunchFinished(mTopActivity);
verifyNoMoreInteractions(mLaunchObserver);
}
@@ -210,7 +219,7 @@
notifyWindowsDrawn(mTopActivity);
verifyAsync(mLaunchObserver).onReportFullyDrawn(eqProto(mTopActivity), anyLong());
- verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(mTopActivity), anyLong());
+ verifyOnActivityLaunchFinished(mTopActivity);
verifyNoMoreInteractions(mLaunchObserver);
}
@@ -267,7 +276,7 @@
notifyWindowsDrawn(mTopActivity);
- verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(mTopActivity), anyLong());
+ verifyOnActivityLaunchFinished(mTopActivity);
verifyNoMoreInteractions(mLaunchObserver);
}
@@ -322,16 +331,40 @@
assertWithMessage("Different callers should get 2 indepedent launching states")
.that(previousState).isNotEqualTo(mLaunchingState);
-
- notifyTransitionStarting(otherActivity);
- notifyWindowsDrawn(otherActivity);
-
- verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(otherActivity), anyLong());
+ transitToDrawnAndVerifyOnLaunchFinished(otherActivity);
// The first transition should still be valid.
- notifyTransitionStarting(mTopActivity);
- notifyWindowsDrawn(mTopActivity);
+ transitToDrawnAndVerifyOnLaunchFinished(mTopActivity);
+ }
- verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(mTopActivity), anyLong());
+ @Test
+ public void testConsecutiveLaunchOnDifferentDisplay() {
+ onActivityLaunched(mTopActivity);
+
+ final ActivityStack stack = new StackBuilder(mRootActivityContainer)
+ .setDisplay(addNewDisplayContentAt(DisplayContent.POSITION_BOTTOM))
+ .setCreateActivity(false)
+ .build();
+ final ActivityRecord activityOnNewDisplay = new ActivityBuilder(mService)
+ .setStack(stack)
+ .setCreateTask(true)
+ .setProcessName("new")
+ .build();
+
+ // Before TopActivity is drawn, it launches another activity on a different display.
+ mActivityMetricsLogger.notifyActivityLaunching(activityOnNewDisplay.intent,
+ mTopActivity /* caller */);
+ notifyActivityLaunched(START_SUCCESS, activityOnNewDisplay);
+
+ // There should be 2 events instead of coalescing as one event.
+ transitToDrawnAndVerifyOnLaunchFinished(mTopActivity);
+ transitToDrawnAndVerifyOnLaunchFinished(activityOnNewDisplay);
+ }
+
+ private void transitToDrawnAndVerifyOnLaunchFinished(ActivityRecord activity) {
+ notifyTransitionStarting(activity);
+ notifyWindowsDrawn(activity);
+
+ verifyOnActivityLaunchFinished(activity);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index d415f25..1311889 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -19,6 +19,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_TASK_CHANGE_WINDOWING_MODE;
import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
@@ -29,6 +30,7 @@
import static org.junit.Assert.assertTrue;
import android.platform.test.annotations.Presubmit;
+import android.util.ArraySet;
import android.view.WindowManager;
import androidx.test.filters.FlakyTest;
@@ -116,4 +118,358 @@
assertTrue(mAppTransitionController.isTransitWithinTask(TRANSIT_ACTIVITY_OPEN, task));
assertFalse(mAppTransitionController.isTransitWithinTask(TRANSIT_TASK_OPEN, task));
}
+
+ @Test
+ public void testGetAnimationTargets_noHierarchicalAnimations() {
+ WindowManagerService.sHierarchicalAnimations = false;
+
+ // [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (opening, invisible)
+ // +- [TaskStack2] - [Task2] - [ActivityRecord2] (closing, visible)
+ final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+ final ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(stack1);
+ activity1.setVisible(false);
+ activity1.mVisibleRequested = true;
+
+ final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent);
+ final ActivityRecord activity2 = WindowTestUtils.createTestActivityRecord(stack2);
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity2);
+
+ // Don't promote when the flag is disabled.
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{activity1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{activity2}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
+ @Test
+ public void testGetAnimationTargets_visibilityAlreadyUpdated() {
+ // [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (opening, visible)
+ // +- [TaskStack2] - [Task2] - [ActivityRecord2] (closing, invisible)
+ final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+ final ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(stack1);
+
+ final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent);
+ final ActivityRecord activity2 = WindowTestUtils.createTestActivityRecord(stack2);
+ activity2.setVisible(false);
+ activity2.mVisibleRequested = false;
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity2);
+
+ // No animation, since visibility of the opening and closing apps are already updated
+ // outside of AppTransition framework.
+ WindowManagerService.sHierarchicalAnimations = false;
+ assertEquals(
+ new ArraySet<>(),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(
+ new ArraySet<>(),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+
+ WindowManagerService.sHierarchicalAnimations = true;
+ assertEquals(
+ new ArraySet<>(),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(
+ new ArraySet<>(),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
+ @Test
+ public void testGetAnimationTargets_exitingBeforeTransition() {
+ final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
+ final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(stack);
+ activity.setVisible(false);
+ activity.mIsExiting = true;
+
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity);
+
+ // Animate closing apps even if it's not visible when it is exiting before we had a chance
+ // to play the transition animation.
+ WindowManagerService.sHierarchicalAnimations = false;
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{activity}),
+ AppTransitionController.getAnimationTargets(
+ new ArraySet<>(), closing, false /* visible */));
+
+ WindowManagerService.sHierarchicalAnimations = true;
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{stack}),
+ AppTransitionController.getAnimationTargets(
+ new ArraySet<>(), closing, false /* visible */));
+ }
+
+ @Test
+ public void testGetAnimationTargets_windowsAreBeingReplaced() {
+ // [DisplayContent] -+- [TaskStack1] - [Task1] - [ActivityRecord1] (opening, visible)
+ // +- [AppWindow1] (being-replaced)
+ // +- [TaskStack2] - [Task2] - [ActivityRecord2] (closing, invisible)
+ // +- [AppWindow2] (being-replaced)
+ final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+ final ActivityRecord activity1 = WindowTestUtils.createTestActivityRecord(stack1);
+ final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
+ TYPE_BASE_APPLICATION);
+ attrs.setTitle("AppWindow1");
+ final WindowTestUtils.TestWindowState appWindow1 = createWindowState(attrs, activity1);
+ appWindow1.mWillReplaceWindow = true;
+ activity1.addWindow(appWindow1);
+
+ final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent);
+ final ActivityRecord activity2 = WindowTestUtils.createTestActivityRecord(stack2);
+ activity2.setVisible(false);
+ activity2.mVisibleRequested = false;
+ attrs.setTitle("AppWindow2");
+ final WindowTestUtils.TestWindowState appWindow2 = createWindowState(attrs, activity2);
+ appWindow2.mWillReplaceWindow = true;
+ activity2.addWindow(appWindow2);
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity2);
+
+ // Animate opening apps even if it's already visible in case its windows are being replaced.
+ // Don't animate closing apps if it's already invisible even though its windows are being
+ // replaced.
+ WindowManagerService.sHierarchicalAnimations = false;
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{activity1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+
+ WindowManagerService.sHierarchicalAnimations = true;
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{stack1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
+ @Test
+ public void testGetAnimationTargets_openingClosingInDifferentTask() {
+ WindowManagerService.sHierarchicalAnimations = true;
+
+ // [DisplayContent] -+- [TaskStack1] - [Task1] -+- [ActivityRecord1] (opening, invisible)
+ // | +- [ActivityRecord2] (invisible)
+ // |
+ // +- [TaskStack2] - [Task2] -+- [ActivityRecord3] (closing, visible)
+ // +- [ActivityRecord4] (invisible)
+ final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+ final Task task1 = createTaskInStack(stack1, 0 /* userId */);
+ final ActivityRecord activity1 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task1);
+ activity1.setVisible(false);
+ activity1.mVisibleRequested = true;
+ final ActivityRecord activity2 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task1);
+ activity2.setVisible(false);
+ activity2.mVisibleRequested = false;
+
+ final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent);
+ final Task task2 = createTaskInStack(stack2, 0 /* userId */);
+ final ActivityRecord activity3 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task2);
+ final ActivityRecord activity4 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task2);
+ activity4.setVisible(false);
+ activity4.mVisibleRequested = false;
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity3);
+
+ // Promote animation targets to TaskStack level. Invisible ActivityRecords don't affect
+ // promotion decision.
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{stack1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{stack2}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
+ @Test
+ public void testGetAnimationTargets_openingClosingInSameTask() {
+ WindowManagerService.sHierarchicalAnimations = true;
+
+ // [DisplayContent] - [TaskStack] - [Task] -+- [ActivityRecord1] (opening, invisible)
+ // +- [ActivityRecord2] (closing, visible)
+ final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
+ final Task task = createTaskInStack(stack, 0 /* userId */);
+ final ActivityRecord activity1 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task);
+ activity1.setVisible(false);
+ activity1.mVisibleRequested = true;
+ final ActivityRecord activity2 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task);
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity2);
+
+ // Don't promote an animation target to Task level, since the same task contains both
+ // opening and closing app.
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{activity1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{activity2}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
+ @Test
+ public void testGetAnimationTargets_animateOnlyTranslucentApp() {
+ WindowManagerService.sHierarchicalAnimations = true;
+
+ // [DisplayContent] -+- [TaskStack1] - [Task1] -+- [ActivityRecord1] (opening, invisible)
+ // | +- [ActivityRecord2] (visible)
+ // |
+ // +- [TaskStack2] - [Task2] -+- [ActivityRecord3] (closing, visible)
+ // +- [ActivityRecord4] (visible)
+
+ final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+ final Task task1 = createTaskInStack(stack1, 0 /* userId */);
+ final ActivityRecord activity1 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task1);
+ activity1.setVisible(false);
+ activity1.mVisibleRequested = true;
+ activity1.setOccludesParent(false);
+
+ final ActivityRecord activity2 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task1);
+
+ final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent);
+ final Task task2 = createTaskInStack(stack2, 0 /* userId */);
+ final ActivityRecord activity3 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task2);
+ activity3.setOccludesParent(false);
+ final ActivityRecord activity4 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task2);
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity3);
+
+ // Don't promote an animation target to Task level, since opening (closing) app is
+ // translucent and is displayed over other non-animating app.
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{activity1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{activity3}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
+ @Test
+ public void testGetAnimationTargets_animateTranslucentAndOpaqueApps() {
+ WindowManagerService.sHierarchicalAnimations = true;
+
+ // [DisplayContent] -+- [TaskStack1] - [Task1] -+- [ActivityRecord1] (opening, invisible)
+ // | +- [ActivityRecord2] (opening, invisible)
+ // |
+ // +- [TaskStack2] - [Task2] -+- [ActivityRecord3] (closing, visible)
+ // +- [ActivityRecord4] (closing, visible)
+
+ final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+ final Task task1 = createTaskInStack(stack1, 0 /* userId */);
+ final ActivityRecord activity1 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task1);
+ activity1.setVisible(false);
+ activity1.mVisibleRequested = true;
+ activity1.setOccludesParent(false);
+
+ final ActivityRecord activity2 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task1);
+ activity2.setVisible(false);
+ activity2.mVisibleRequested = true;
+
+ final ActivityStack stack2 = createTaskStackOnDisplay(mDisplayContent);
+ final Task task2 = createTaskInStack(stack2, 0 /* userId */);
+ final ActivityRecord activity3 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task2);
+ activity3.setOccludesParent(false);
+ final ActivityRecord activity4 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task2);
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ opening.add(activity2);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity3);
+ closing.add(activity4);
+
+ // Promote animation targets to TaskStack level even though opening (closing) app is
+ // translucent as long as all visible siblings animate at the same time.
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{stack1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{stack2}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
+
+ @Test
+ public void testGetAnimationTargets_stackContainsMultipleTasks() {
+ WindowManagerService.sHierarchicalAnimations = true;
+
+ // [DisplayContent] - [TaskStack] -+- [Task1] - [ActivityRecord1] (opening, invisible)
+ // +- [Task2] - [ActivityRecord2] (closing, visible)
+ final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
+ final Task task1 = createTaskInStack(stack, 0 /* userId */);
+ final ActivityRecord activity1 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task1);
+ activity1.setVisible(false);
+ activity1.mVisibleRequested = true;
+ final Task task2 = createTaskInStack(stack, 0 /* userId */);
+ final ActivityRecord activity2 = WindowTestUtils.createActivityRecordInTask(
+ mDisplayContent, task2);
+
+ final ArraySet<ActivityRecord> opening = new ArraySet<>();
+ opening.add(activity1);
+ final ArraySet<ActivityRecord> closing = new ArraySet<>();
+ closing.add(activity2);
+
+ // Promote animation targets up to Task level, not beyond.
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{task1}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, true /* visible */));
+ assertEquals(
+ new ArraySet<>(new WindowContainer[]{task2}),
+ AppTransitionController.getAnimationTargets(
+ opening, closing, false /* visible */));
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index e17e0d8..8fe0cdb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -19,10 +19,13 @@
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_APP_THEME;
import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_REAL;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
@@ -175,4 +178,22 @@
}
}
}
+
+ @Test
+ public void testPrepareTaskSnapshot() {
+ mAppWindow.mWinAnimator.mLastAlpha = 1f;
+ spyOn(mAppWindow.mWinAnimator);
+ doReturn(true).when(mAppWindow.mWinAnimator).getShown();
+ doReturn(true).when(mAppWindow.mActivityRecord).isSurfaceShowing();
+
+ final ActivityManager.TaskSnapshot.Builder builder =
+ new ActivityManager.TaskSnapshot.Builder();
+ final float scaleFraction = 0.8f;
+ mWm.mTaskSnapshotController.prepareTaskSnapshot(mAppWindow.mActivityRecord.getTask(),
+ scaleFraction, PixelFormat.UNKNOWN, builder);
+
+ assertEquals(scaleFraction, builder.getScaleFraction(), 0 /* delta */);
+ // The pixel format should be selected automatically.
+ assertNotEquals(PixelFormat.UNKNOWN, builder.getPixelFormat());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 0018c63..6d23b2e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -596,7 +596,7 @@
// Mock active recents animation
RecentsAnimationController recentsController = mock(RecentsAnimationController.class);
- when(recentsController.isAnimatingTask(win0.mActivityRecord.getTask())).thenReturn(true);
+ when(recentsController.shouldApplyInputConsumer(win0.mActivityRecord)).thenReturn(true);
mWm.setRecentsAnimationController(recentsController);
assertTrue(win0.cantReceiveTouchInput());
}
diff --git a/telephony/common/com/android/internal/telephony/SmsNumberUtils.java b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
index 367aad1..06c08f5 100644
--- a/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
+++ b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
@@ -20,8 +20,8 @@
import android.database.Cursor;
import android.database.SQLException;
import android.os.Binder;
-import android.os.Build;
import android.os.PersistableBundle;
+import android.os.SystemProperties;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
import android.telephony.Rlog;
@@ -43,7 +43,7 @@
*/
public class SmsNumberUtils {
private static final String TAG = "SmsNumberUtils";
- private static final boolean DBG = Build.IS_DEBUGGABLE;
+ private static final boolean DBG = SystemProperties.getInt("ro.debuggable", 0) == 1;
private static final String PLUS_SIGN = "+";
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7381acb..813b9fa 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1855,6 +1855,14 @@
*/
public static final String KEY_CDMA_ROAMING_MODE_INT = "cdma_roaming_mode_int";
+ /**
+ * Determines whether 1X voice calls is supported for some CDMA carriers.
+ * Default value is true.
+ * @hide
+ */
+ @SystemApi
+ public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL =
+ "support_cdma_1x_voice_calls_bool";
/**
* Boolean indicating if support is provided for directly dialing FDN number from FDN list.
@@ -3048,16 +3056,18 @@
"data_switch_validation_timeout_long";
/**
- * GPS configs. See android.hardware.gnss@1.0 IGnssConfiguration.
- * @hide
+ * GPS configs. See the GNSS HAL documentation for more details.
*/
public static final class Gps {
+ private Gps() {}
+
/** Prefix of all Gps.KEY_* constants. */
public static final String KEY_PREFIX = "gps.";
/**
* Location information during (and after) an emergency call is only provided over control
* plane signaling from the network.
+ * @hide
*/
public static final int SUPL_EMERGENCY_MODE_TYPE_CP_ONLY = 0;
@@ -3065,6 +3075,7 @@
* Location information during (and after) an emergency call is provided over the data
* plane and serviced by the framework GNSS service, but if it fails, the carrier also
* supports control plane backup signaling.
+ * @hide
*/
public static final int SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK = 1;
@@ -3072,6 +3083,7 @@
* Location information during (and after) an emergency call is provided over the data plane
* and serviced by the framework GNSS service only. There is no backup signalling over the
* control plane if it fails.
+ * @hide
*/
public static final int SUPL_EMERGENCY_MODE_TYPE_DP_ONLY = 2;
@@ -3088,10 +3100,14 @@
/**
* SUPL server host for SET Initiated & non-ES Network-Initiated SUPL requests.
* Default to supl.google.com
+ * @hide
*/
public static final String KEY_SUPL_HOST_STRING = KEY_PREFIX + "supl_host";
- /** SUPL server port. Default to 7275. */
+ /**
+ * SUPL server port. Default to 7275.
+ * @hide
+ */
public static final String KEY_SUPL_PORT_STRING = KEY_PREFIX + "supl_port";
/**
@@ -3099,6 +3115,7 @@
* with bits 0:7 representing a service indicator field, bits 8:15
* representing the minor version and bits 16:23 representing the
* major version. Default to 0x20000.
+ * @hide
*/
public static final String KEY_SUPL_VER_STRING = KEY_PREFIX + "supl_ver";
@@ -3106,6 +3123,7 @@
* SUPL_MODE configuration bit mask
* 1 - Mobile Station Based. This is default.
* 2 - Mobile Station Assisted.
+ * @hide
*/
public static final String KEY_SUPL_MODE_STRING = KEY_PREFIX + "supl_mode";
@@ -3114,6 +3132,7 @@
* (e.g. E911), and SUPL non-ES requests to only outside of non user emergency sessions.
* 0 - no.
* 1 - yes. This is default.
+ * @hide
*/
public static final String KEY_SUPL_ES_STRING = KEY_PREFIX + "supl_es";
@@ -3122,6 +3141,7 @@
* 0 - Radio Resource Location Protocol in user plane and control plane. This is default.
* 1 - Enable LTE Positioning Protocol in user plane.
* 2 - Enable LTE Positioning Protocol in control plane.
+ * @hide
*/
public static final String KEY_LPP_PROFILE_STRING = KEY_PREFIX + "lpp_profile";
@@ -3129,6 +3149,7 @@
* Determine whether to use emergency PDN for emergency SUPL.
* 0 - no.
* 1 - yes. This is default.
+ * @hide
*/
public static final String KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING =
KEY_PREFIX + "use_emergency_pdn_for_emergency_supl";
@@ -3139,6 +3160,7 @@
* 1 - Use A-GLONASS in Radio Resource Control(RRC) control-plane.
* 2 - Use A-GLONASS in Radio Resource Location user-plane.
* 4 - Use A-GLONASS in LTE Positioning Protocol User plane.
+ * @hide
*/
public static final String KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING =
KEY_PREFIX + "a_glonass_pos_protocol_select";
@@ -3150,11 +3172,13 @@
* "1" - Lock Mobile Originated GPS functionalities.
* "2" - Lock Network initiated GPS functionalities.
* "3" - Lock both. This is default.
+ * @hide
*/
public static final String KEY_GPS_LOCK_STRING = KEY_PREFIX + "gps_lock";
/**
* Control Plane / SUPL NI emergency extension time in seconds. Default to "0".
+ * @hide
*/
public static final String KEY_ES_EXTENSION_SEC_STRING = KEY_PREFIX + "es_extension_sec";
@@ -3163,6 +3187,7 @@
* the non-framework entities requesting location directly from GNSS without involving
* the framework, as managed by IGnssVisibilityControl.hal. For example,
* "com.example.mdt com.example.ims".
+ * @hide
*/
public static final String KEY_NFW_PROXY_APPS_STRING = KEY_PREFIX + "nfw_proxy_apps";
@@ -3178,6 +3203,7 @@
* {@link #SUPL_EMERGENCY_MODE_TYPE_CP_ONLY}.
* <p>
* The default value for this configuration is {@link #SUPL_EMERGENCY_MODE_TYPE_CP_ONLY}.
+ * @hide
*/
public static final String KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT = KEY_PREFIX
+ "es_supl_control_plane_support_int";
@@ -3189,6 +3215,7 @@
* <p>
* A string array of PLMNs that do not support a control-plane mechanism for getting a
* user's location for SUPL ES.
+ * @hide
*/
public static final String KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY =
KEY_PREFIX + "es_supl_data_plane_only_roaming_plmn_string_array";
@@ -3603,6 +3630,7 @@
sDefaults.putBoolean(KEY_FORCE_IMEI_BOOL, false);
sDefaults.putInt(
KEY_CDMA_ROAMING_MODE_INT, TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT);
+ sDefaults.putBoolean(KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL, true);
sDefaults.putString(KEY_RCS_CONFIG_SERVER_URL_STRING, "");
// Carrier Signalling Receivers
diff --git a/telephony/java/android/telephony/CbGeoUtils.java b/telephony/java/android/telephony/CbGeoUtils.java
index 7314edd..84be4e8 100644
--- a/telephony/java/android/telephony/CbGeoUtils.java
+++ b/telephony/java/android/telephony/CbGeoUtils.java
@@ -26,7 +26,6 @@
import java.util.List;
import java.util.stream.Collectors;
-
/**
* This utils class is used for geo-fencing of CellBroadcast messages and is used by the cell
* broadcast module.
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index d7d85c2..3f065f8 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -65,6 +65,13 @@
static final boolean DBG = false;
static final boolean VDBG = false; // STOPSHIP if true
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "STATE_",
+ value = {STATE_IN_SERVICE, STATE_OUT_OF_SERVICE, STATE_EMERGENCY_ONLY,
+ STATE_POWER_OFF})
+ public @interface RegState {}
+
/**
* Normal operation condition, the phone is registered
* with an operator either in home network or in roaming.
@@ -83,6 +90,7 @@
/**
* The phone is registered and locked. Only emergency numbers are allowed. {@more}
*/
+ //TODO: This state is not used anymore. It should be deprecated in a future release.
public static final int STATE_EMERGENCY_ONLY =
TelephonyProtoEnums.SERVICE_STATE_EMERGENCY_ONLY; // 2
@@ -501,13 +509,15 @@
}
/**
- * Get current data service state
+ * Get current data registration state.
*
* @see #STATE_IN_SERVICE
* @see #STATE_OUT_OF_SERVICE
* @see #STATE_EMERGENCY_ONLY
* @see #STATE_POWER_OFF
*
+ * @return current data registration state {@link RegState}
+ *
* @hide
*/
@UnsupportedAppUsage
@@ -516,6 +526,23 @@
}
/**
+ * Get current data registration state.
+ *
+ * @see #STATE_IN_SERVICE
+ * @see #STATE_OUT_OF_SERVICE
+ * @see #STATE_EMERGENCY_ONLY
+ * @see #STATE_POWER_OFF
+ *
+ * @return current data registration state {@link RegState}
+ *
+ * @hide
+ */
+ @SystemApi
+ public @RegState int getDataRegistrationState() {
+ return getDataRegState();
+ }
+
+ /**
* Get the current duplex mode
*
* @see #DUPLEX_MODE_UNKNOWN
@@ -1408,7 +1435,15 @@
return getRilDataRadioTechnology();
}
- /** @hide */
+ /**
+ * Transform RIL radio technology {@link RilRadioTechnology} value to Network
+ * type {@link NetworkType}.
+ *
+ * @param rat The RIL radio technology {@link RilRadioTechnology}.
+ * @return The network type {@link NetworkType}.
+ *
+ * @hide
+ */
public static int rilRadioTechnologyToNetworkType(@RilRadioTechnology int rat) {
switch(rat) {
case RIL_RADIO_TECHNOLOGY_GPRS:
@@ -1490,7 +1525,15 @@
}
}
- /** @hide */
+ /**
+ * Transform network type {@link NetworkType} value to RIL radio technology
+ * {@link RilRadioTechnology}.
+ *
+ * @param networkType The network type {@link NetworkType}.
+ * @return The RIL radio technology {@link RilRadioTechnology}.
+ *
+ * @hide
+ */
public static int networkTypeToRilRadioTechnology(int networkType) {
switch(networkType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
@@ -1691,7 +1734,14 @@
return bearerBitmask;
}
- /** @hide */
+ /**
+ * Convert network type bitmask to bearer bitmask.
+ *
+ * @param networkTypeBitmask The network type bitmask value
+ * @return The bearer bitmask value.
+ *
+ * @hide
+ */
public static int convertNetworkTypeBitmaskToBearerBitmask(int networkTypeBitmask) {
if (networkTypeBitmask == 0) {
return 0;
@@ -1705,7 +1755,14 @@
return bearerBitmask;
}
- /** @hide */
+ /**
+ * Convert bearer bitmask to network type bitmask.
+ *
+ * @param bearerBitmask The bearer bitmask value.
+ * @return The network type bitmask value.
+ *
+ * @hide
+ */
public static int convertBearerBitmaskToNetworkTypeBitmask(int bearerBitmask) {
if (bearerBitmask == 0) {
return 0;
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 740622d..f08e1ec 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -912,9 +912,9 @@
* <p>
* Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
* changed.
- *
* @hide
*/
+ @SystemApi
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS)
public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED
diff --git a/telephony/java/android/telephony/TelephonyFrameworkInitializer.java b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
index 407ad19..0d2a8bc 100644
--- a/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
+++ b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
@@ -23,6 +23,7 @@
import android.os.TelephonyServiceManager;
import android.telephony.euicc.EuiccCardManager;
import android.telephony.euicc.EuiccManager;
+import android.telephony.ims.ImsManager;
import com.android.internal.util.Preconditions;
@@ -88,6 +89,11 @@
EuiccCardManager.class,
context -> new EuiccCardManager(context)
);
+ SystemServiceRegistry.registerContextAwareService(
+ Context.TELEPHONY_IMS_SERVICE,
+ ImsManager.class,
+ context -> new ImsManager(context)
+ );
}
/** @hide */
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index b0ff5dc..87e5391 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -32,6 +32,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.util.TelephonyUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -833,7 +834,7 @@
}
int startSize = extras.size();
- Bundle filtered = extras.filterValues();
+ Bundle filtered = TelephonyUtils.filterValues(extras);
int endSize = filtered.size();
if (startSize != endSize) {
Log.i(TAG, "maybeCleanseExtras: " + (startSize - endSize) + " extra values were "
diff --git a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
index dcea9bb..d672642 100644
--- a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
+++ b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
@@ -18,11 +18,11 @@
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
-import android.os.Build;
import android.telephony.Rlog;
import android.util.SparseIntArray;
import com.android.internal.telephony.cdma.sms.UserData;
+import com.android.internal.telephony.util.TelephonyUtils;
import com.android.internal.telephony.util.XmlUtils;
import dalvik.annotation.compat.UnsupportedAppUsage;
@@ -30,7 +30,7 @@
public class Sms7BitEncodingTranslator {
private static final String TAG = "Sms7BitEncodingTranslator";
@UnsupportedAppUsage
- private static final boolean DBG = Build.IS_DEBUGGABLE ;
+ private static final boolean DBG = TelephonyUtils.IS_DEBUGGABLE;
private static boolean mIs7BitTranslationTableLoaded = false;
private static SparseIntArray mTranslationTable = null;
@UnsupportedAppUsage
diff --git a/telephony/java/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/java/com/android/internal/telephony/util/TelephonyUtils.java
index 306b9ee..2abcc76 100644
--- a/telephony/java/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/java/com/android/internal/telephony/util/TelephonyUtils.java
@@ -22,6 +22,8 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
+import android.os.Bundle;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SystemProperties;
@@ -108,4 +110,31 @@
Binder.restoreCallingIdentity(callingIdentity);
}
}
+
+ /**
+ * Filter values in bundle to only basic types.
+ */
+ public static Bundle filterValues(Bundle bundle) {
+ Bundle ret = new Bundle(bundle);
+ for (String key : bundle.keySet()) {
+ Object value = bundle.get(key);
+ if ((value instanceof Integer) || (value instanceof Long)
+ || (value instanceof Double) || (value instanceof String)
+ || (value instanceof int[]) || (value instanceof long[])
+ || (value instanceof double[]) || (value instanceof String[])
+ || (value instanceof PersistableBundle) || (value == null)
+ || (value instanceof Boolean) || (value instanceof boolean[])) {
+ continue;
+ }
+ if (value instanceof Bundle) {
+ ret.putBundle(key, filterValues((Bundle) value));
+ continue;
+ }
+ if (value.getClass().getName().startsWith("android.")) {
+ continue;
+ }
+ ret.remove(key);
+ }
+ return ret;
+ }
}
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index 25028fb..c4801aa 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -32,7 +32,6 @@
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.net.NetworkRequest
import android.net.TestNetworkStackClient
-import android.net.TetheringManager
import android.net.metrics.IpConnectivityLog
import android.os.ConditionVariable
import android.os.IBinder
@@ -169,7 +168,6 @@
val deps = spy(ConnectivityService.Dependencies())
doReturn(networkStackClient).`when`(deps).networkStack
doReturn(metricsLogger).`when`(deps).metricsLogger
- doReturn(mock(TetheringManager::class.java)).`when`(deps).getTetheringManager()
doReturn(mock(ProxyTracker::class.java)).`when`(deps).makeProxyTracker(any(), any())
doReturn(mock(MockableSystemProperties::class.java)).`when`(deps).systemProperties
doReturn(TestNetIdManager()).`when`(deps).makeNetIdManager()
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index a24426b..b2d363e 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -164,7 +164,6 @@
import android.net.ResolverParamsParcel;
import android.net.RouteInfo;
import android.net.SocketKeepalive;
-import android.net.TetheringManager;
import android.net.UidRange;
import android.net.metrics.IpConnectivityLog;
import android.net.shared.NetworkMonitorUtils;
@@ -1133,7 +1132,6 @@
doReturn(new TestNetIdManager()).when(deps).makeNetIdManager();
doReturn(mNetworkStack).when(deps).getNetworkStack();
doReturn(systemProperties).when(deps).getSystemProperties();
- doReturn(mock(TetheringManager.class)).when(deps).getTetheringManager();
doReturn(mock(ProxyTracker.class)).when(deps).makeProxyTracker(any(), any());
doReturn(mMetricsService).when(deps).getMetricsLogger();
doReturn(true).when(deps).queryUserAccess(anyInt(), anyInt());
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
index 67ba895..c49c370 100644
--- a/tools/aapt2/Resource.h
+++ b/tools/aapt2/Resource.h
@@ -147,10 +147,11 @@
ResourceId(uint32_t res_id); // NOLINT(google-explicit-constructor)
ResourceId(uint8_t p, uint8_t t, uint16_t e);
- bool is_valid() const;
+ // Returns true if the ID is a valid ID that is not dynamic (package ID cannot be 0)
+ bool is_valid_static() const;
// Returns true if the ID is a valid ID or dynamic ID (package ID can be 0).
- bool is_valid_dynamic() const;
+ bool is_valid() const;
uint8_t package_id() const;
uint8_t type_id() const;
@@ -233,11 +234,11 @@
inline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e)
: id((p << 24) | (t << 16) | e) {}
-inline bool ResourceId::is_valid() const {
+inline bool ResourceId::is_valid_static() const {
return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0;
}
-inline bool ResourceId::is_valid_dynamic() const {
+inline bool ResourceId::is_valid() const {
return (id & 0x00ff0000u) != 0;
}
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 1773b5a..e0a9a31e 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -398,7 +398,7 @@
// Check for package names appearing twice with two different package ids
ResourceTablePackage* package = FindOrCreatePackage(name.package);
- if (res_id.is_valid_dynamic() && package->id && package->id.value() != res_id.package_id()) {
+ if (res_id.is_valid() && package->id && package->id.value() != res_id.package_id()) {
diag->Error(DiagMessage(source)
<< "trying to add resource '" << name << "' with ID " << res_id
<< " but package '" << package->name << "' already has ID "
@@ -407,9 +407,9 @@
}
// Whether or not to error on duplicate resources
- bool check_id = validate_resources_ && res_id.is_valid_dynamic();
+ bool check_id = validate_resources_ && res_id.is_valid();
// Whether or not to create a duplicate resource if the id does not match
- bool use_id = !validate_resources_ && res_id.is_valid_dynamic();
+ bool use_id = !validate_resources_ && res_id.is_valid();
ResourceTableType* type = package->FindOrCreateType(name.type, use_id ? res_id.type_id()
: Maybe<uint8_t>());
@@ -463,7 +463,7 @@
}
}
- if (res_id.is_valid_dynamic()) {
+ if (res_id.is_valid()) {
package->id = res_id.package_id();
type->id = res_id.type_id();
entry->id = res_id.entry_id();
@@ -504,7 +504,7 @@
// Check for package names appearing twice with two different package ids
ResourceTablePackage* package = FindOrCreatePackage(name.package);
- if (res_id.is_valid_dynamic() && package->id && package->id.value() != res_id.package_id()) {
+ if (res_id.is_valid() && package->id && package->id.value() != res_id.package_id()) {
diag->Error(DiagMessage(source)
<< "trying to add resource '" << name << "' with ID " << res_id
<< " but package '" << package->name << "' already has ID "
@@ -513,9 +513,9 @@
}
// Whether or not to error on duplicate resources
- bool check_id = validate_resources_ && res_id.is_valid_dynamic();
+ bool check_id = validate_resources_ && res_id.is_valid();
// Whether or not to create a duplicate resource if the id does not match
- bool use_id = !validate_resources_ && res_id.is_valid_dynamic();
+ bool use_id = !validate_resources_ && res_id.is_valid();
ResourceTableType* type = package->FindOrCreateType(name.type, use_id ? res_id.type_id()
: Maybe<uint8_t>());
@@ -541,7 +541,7 @@
return false;
}
- if (res_id.is_valid_dynamic()) {
+ if (res_id.is_valid()) {
package->id = res_id.package_id();
type->id = res_id.type_id();
entry->id = res_id.entry_id();
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 03009aa..3623b11 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -516,7 +516,7 @@
if (android::ResTable::stringToInt(str16.data(), str16.size(), &value)) {
if (value.dataType == android::Res_value::TYPE_INT_HEX) {
ResourceId id(value.data);
- if (id.is_valid_dynamic()) {
+ if (id.is_valid()) {
return id;
}
}
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
index 34b46c5..4f0fa8a 100644
--- a/tools/aapt2/ResourceValues.cpp
+++ b/tools/aapt2/ResourceValues.cpp
@@ -117,7 +117,7 @@
bool Reference::Flatten(android::Res_value* out_value) const {
const ResourceId resid = id.value_or_default(ResourceId(0));
- const bool dynamic = resid.is_valid_dynamic() && is_dynamic;
+ const bool dynamic = resid.is_valid() && is_dynamic;
if (reference_type == Reference::Type::kResource) {
if (dynamic) {
@@ -159,7 +159,7 @@
*out << name.value();
}
- if (id && id.value().is_valid_dynamic()) {
+ if (id && id.value().is_valid()) {
if (name) {
*out << " ";
}
@@ -196,7 +196,7 @@
printer->Print("/");
printer->Print(name.entry);
}
- } else if (ref.id && ref.id.value().is_valid_dynamic()) {
+ } else if (ref.id && ref.id.value().is_valid()) {
printer->Print(ref.id.value().to_string());
}
}
diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp
index bc09f19..83e20b5 100644
--- a/tools/aapt2/process/SymbolTable.cpp
+++ b/tools/aapt2/process/SymbolTable.cpp
@@ -340,7 +340,7 @@
}
res_id = asset_manager_.GetResourceId(real_name.to_string());
- if (res_id.is_valid() && asset_manager_.GetResourceFlags(res_id.id, &type_spec_flags)) {
+ if (res_id.is_valid_static() && asset_manager_.GetResourceFlags(res_id.id, &type_spec_flags)) {
found = true;
return false;
}
@@ -379,7 +379,7 @@
std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindById(
ResourceId id) {
- if (!id.is_valid()) {
+ if (!id.is_valid_static()) {
// Exit early and avoid the error logs from AssetManager.
return {};
}
diff --git a/wifi/Android.bp b/wifi/Android.bp
index 08115ec..fb1f866 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -32,7 +32,6 @@
// framework-wifi.jar. This is not a good idea, should move WifiNetworkScoreCache
// to a separate package.
"java/android/net/wifi/WifiNetworkScoreCache.java",
- "java/android/net/wifi/WifiCondManager.java",
"java/android/net/wifi/wificond/*.java",
":libwificond_ipc_aidl",
],
diff --git a/wifi/java/android/net/wifi/SoftApInfo.java b/wifi/java/android/net/wifi/SoftApInfo.java
index 375a977..24ed8ef 100644
--- a/wifi/java/android/net/wifi/SoftApInfo.java
+++ b/wifi/java/android/net/wifi/SoftApInfo.java
@@ -16,15 +16,12 @@
package android.net.wifi;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
@@ -85,26 +82,12 @@
*/
public static final int CHANNEL_WIDTH_160MHZ = 6;
- /**
- * @hide
- */
- @IntDef(prefix = { "CHANNEL_WIDTH_" }, value = {
- CHANNEL_WIDTH_INVALID,
- CHANNEL_WIDTH_20MHZ_NOHT,
- CHANNEL_WIDTH_20MHZ,
- CHANNEL_WIDTH_40MHZ,
- CHANNEL_WIDTH_80MHZ,
- CHANNEL_WIDTH_80MHZ_PLUS_MHZ,
- CHANNEL_WIDTH_160MHZ,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Bandwidth {}
/** The frequency which AP resides on. */
private int mFrequency = 0;
- @Bandwidth
+ @WifiAnnotations.Bandwidth
private int mBandwidth = CHANNEL_WIDTH_INVALID;
/**
@@ -127,9 +110,9 @@
*
* @return One of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ},
* {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ},
- * {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link #CHANNEL_WIDTH_UNKNOWN}.
+ * {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link #CHANNEL_WIDTH_INVALID}.
*/
- @Bandwidth
+ @WifiAnnotations.Bandwidth
public int getBandwidth() {
return mBandwidth;
}
@@ -138,7 +121,7 @@
* Set AP Channel bandwidth.
* @hide
*/
- public void setBandwidth(@Bandwidth int bandwidth) {
+ public void setBandwidth(@WifiAnnotations.Bandwidth int bandwidth) {
mBandwidth = bandwidth;
}
diff --git a/wifi/java/android/net/wifi/WifiAnnotations.java b/wifi/java/android/net/wifi/WifiAnnotations.java
index 4a7dee1..9223d28 100644
--- a/wifi/java/android/net/wifi/WifiAnnotations.java
+++ b/wifi/java/android/net/wifi/WifiAnnotations.java
@@ -48,4 +48,16 @@
WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY,
WifiScanner.WIFI_BAND_6_GHZ})
public @interface WifiBandBasic {}
+
+ @IntDef(prefix = { "CHANNEL_WIDTH_" }, value = {
+ SoftApInfo.CHANNEL_WIDTH_INVALID,
+ SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT,
+ SoftApInfo.CHANNEL_WIDTH_20MHZ,
+ SoftApInfo.CHANNEL_WIDTH_40MHZ,
+ SoftApInfo.CHANNEL_WIDTH_80MHZ,
+ SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ,
+ SoftApInfo.CHANNEL_WIDTH_160MHZ,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Bandwidth {}
}
diff --git a/wifi/java/android/net/wifi/aware/Characteristics.java b/wifi/java/android/net/wifi/aware/Characteristics.java
index e2cf4dc..d5fd48e 100644
--- a/wifi/java/android/net/wifi/aware/Characteristics.java
+++ b/wifi/java/android/net/wifi/aware/Characteristics.java
@@ -16,10 +16,14 @@
package android.net.wifi.aware;
+import android.annotation.IntDef;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* The characteristics of the Wi-Fi Aware implementation.
*/
@@ -31,6 +35,8 @@
"key_max_service_specific_info_length";
/** @hide */
public static final String KEY_MAX_MATCH_FILTER_LENGTH = "key_max_match_filter_length";
+ /** @hide */
+ public static final String KEY_SUPPORTED_CIPHER_SUITES = "key_supported_cipher_suites";
private Bundle mCharacteristics = new Bundle();
@@ -71,12 +77,41 @@
* {@link PublishConfig.Builder#setMatchFilter(java.util.List)} and
* {@link SubscribeConfig.Builder#setMatchFilter(java.util.List)}.
*
- * @return A positive integer, maximum legngth of byte array for Aware discovery match filter.
+ * @return A positive integer, maximum length of byte array for Aware discovery match filter.
*/
public int getMaxMatchFilterLength() {
return mCharacteristics.getInt(KEY_MAX_MATCH_FILTER_LENGTH);
}
+ /** @hide */
+ @IntDef(flag = true, prefix = { "WIFI_AWARE_CIPHER_SUITE_" }, value = {
+ WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
+ WIFI_AWARE_CIPHER_SUITE_NCS_SK_256,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface WifiAwareCipherSuites {}
+
+ /**
+ * Wi-Fi Aware supported ciphier suite representing NCS SK 128: 128 bit shared-key.
+ */
+ public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_128 = 1 << 0;
+
+ /**
+ * Wi-Fi Aware supported ciphier suite representing NCS SK 256: 256 bit shared-key.
+ */
+ public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_256 = 1 << 1;
+
+ /**
+ * Returns the set of cipher suites supported by the device for use in Wi-Fi Aware data-paths.
+ * The device automatically picks the strongest cipher suite when initiating a data-path setup.
+ *
+ * @return A set of flags from {@link #WIFI_AWARE_CIPHER_SUITE_NCS_SK_128}, or
+ * {@link #WIFI_AWARE_CIPHER_SUITE_NCS_SK_256}.
+ */
+ public @WifiAwareCipherSuites int getSupportedCipherSuites() {
+ return mCharacteristics.getInt(KEY_SUPPORTED_CIPHER_SUITES);
+ }
+
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeBundle(mCharacteristics);
diff --git a/wifi/java/android/net/wifi/wificond/NativeScanResult.java b/wifi/java/android/net/wifi/wificond/NativeScanResult.java
index ff8e935..6ed1708 100644
--- a/wifi/java/android/net/wifi/wificond/NativeScanResult.java
+++ b/wifi/java/android/net/wifi/wificond/NativeScanResult.java
@@ -16,46 +16,163 @@
package android.net.wifi.wificond;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
/**
- * ScanResult from wificond
+ * Raw scan result data from the wificond daemon.
*
* @hide
*/
-public class NativeScanResult implements Parcelable {
+@SystemApi
+public final class NativeScanResult implements Parcelable {
private static final int CAPABILITY_SIZE = 16;
+ /** @hide */
+ @VisibleForTesting
public byte[] ssid;
+ /** @hide */
+ @VisibleForTesting
public byte[] bssid;
+ /** @hide */
+ @VisibleForTesting
public byte[] infoElement;
+ /** @hide */
+ @VisibleForTesting
public int frequency;
+ /** @hide */
+ @VisibleForTesting
public int signalMbm;
+ /** @hide */
+ @VisibleForTesting
public long tsf;
+ /** @hide */
+ @VisibleForTesting
public BitSet capability;
+ /** @hide */
+ @VisibleForTesting
public boolean associated;
+ /** @hide */
+ @VisibleForTesting
public List<RadioChainInfo> radioChainInfos;
- /** public constructor */
- public NativeScanResult() { }
-
- /** copy constructor */
- public NativeScanResult(NativeScanResult source) {
- ssid = source.ssid.clone();
- bssid = source.bssid.clone();
- infoElement = source.infoElement.clone();
- frequency = source.frequency;
- signalMbm = source.signalMbm;
- tsf = source.tsf;
- capability = (BitSet) source.capability.clone();
- associated = source.associated;
+ /**
+ * Returns the SSID raw byte array of the AP represented by this scan result.
+ *
+ * @return A byte array.
+ */
+ @NonNull public byte[] getSsid() {
+ return ssid;
}
+ /**
+ * Returns raw bytes representing the MAC address (BSSID) of the AP represented by this scan
+ * result.
+ *
+ * @return a byte array, possibly null or containing the incorrect number of bytes for a MAC
+ * address.
+ */
+ @NonNull public byte[] getBssid() {
+ return bssid;
+ }
+
+ /**
+ * Returns the raw bytes of the information element advertised by the AP represented by this
+ * scan result.
+ *
+ * @return A byte array, possibly null or containing an invalid TLV configuration.
+ */
+ @NonNull public byte[] getInformationElements() {
+ return infoElement;
+ }
+
+ /**
+ * Returns the frequency (in MHz) on which the AP represented by this scan result was observed.
+ *
+ * @return The frequency in MHz.
+ */
+ public int getFrequencyMhz() {
+ return frequency;
+ }
+
+ /**
+ * Return the signal strength of probe response/beacon in (100 * dBm).
+ *
+ * @return Signal strenght in (100 * dBm).
+ */
+ public int getSignalMbm() {
+ return signalMbm;
+ }
+
+ /**
+ * Return the TSF (Timing Synchronization Function) of the received probe response/beacon.
+ * @return
+ */
+ public long getTsf() {
+ return tsf;
+ }
+
+ /**
+ * Return a boolean indicating whether or not we're associated to the AP represented by this
+ * scan result.
+ *
+ * @return A boolean indicating association.
+ */
+ public boolean isAssociated() {
+ return associated;
+ }
+
+ /**
+ * Returns the capabilities of the AP repseresented by this scan result as advertised in the
+ * received probe response or beacon.
+ *
+ * This is a bit mask describing the capabilities of a BSS. See IEEE Std 802.11: 8.4.1.4:
+ * Bit 0 - ESS
+ * Bit 1 - IBSS
+ * Bit 2 - CF Pollable
+ * Bit 3 - CF-Poll Request
+ * Bit 4 - Privacy
+ * Bit 5 - Short Preamble
+ * Bit 6 - PBCC
+ * Bit 7 - Channel Agility
+ * Bit 8 - Spectrum Mgmt
+ * Bit 9 - QoS
+ * Bit 10 - Short Slot Time
+ * Bit 11 - APSD
+ * Bit 12 - Radio Measurement
+ * Bit 13 - DSSS-OFDM
+ * Bit 14 - Delayed Block Ack
+ * Bit 15 - Immediate Block Ack
+ *
+ * @return a bit mask of capabilities.
+ */
+ @NonNull public BitSet getCapabilities() {
+ return capability;
+ }
+
+ /**
+ * Returns details of the signal received on each radio chain for the AP represented by this
+ * scan result in a list of {@link RadioChainInfo} elements.
+ *
+ * @return A list of {@link RadioChainInfo} - possibly empty in case of error.
+ */
+ @NonNull public List<RadioChainInfo> getRadioChainInfos() {
+ return radioChainInfos;
+ }
+
+ /**
+ * @hide
+ */
+ public NativeScanResult() { }
+
/** implement Parcelable interface */
@Override
public int describeContents() {
@@ -64,7 +181,7 @@
/** implement Parcelable interface */
@Override
- public void writeToParcel(Parcel out, int flags) {
+ public void writeToParcel(@NonNull Parcel out, int flags) {
out.writeByteArray(ssid);
out.writeByteArray(bssid);
out.writeByteArray(infoElement);
@@ -83,14 +200,23 @@
}
/** implement Parcelable interface */
- public static final Parcelable.Creator<NativeScanResult> CREATOR =
+ @NonNull public static final Parcelable.Creator<NativeScanResult> CREATOR =
new Parcelable.Creator<NativeScanResult>() {
@Override
public NativeScanResult createFromParcel(Parcel in) {
NativeScanResult result = new NativeScanResult();
result.ssid = in.createByteArray();
+ if (result.ssid == null) {
+ result.ssid = new byte[0];
+ }
result.bssid = in.createByteArray();
+ if (result.bssid == null) {
+ result.bssid = new byte[0];
+ }
result.infoElement = in.createByteArray();
+ if (result.infoElement == null) {
+ result.infoElement = new byte[0];
+ }
result.frequency = in.readInt();
result.signalMbm = in.readInt();
result.tsf = in.readLong();
diff --git a/wifi/java/android/net/wifi/wificond/NativeWifiClient.java b/wifi/java/android/net/wifi/wificond/NativeWifiClient.java
index 4994ebd..554f929 100644
--- a/wifi/java/android/net/wifi/wificond/NativeWifiClient.java
+++ b/wifi/java/android/net/wifi/wificond/NativeWifiClient.java
@@ -16,21 +16,32 @@
package android.net.wifi.wificond;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Arrays;
/**
- * NativeWifiClient for wificond
+ * Structure providing information about clients (STAs) associated with a SoftAp.
*
* @hide
*/
-public class NativeWifiClient implements Parcelable {
- public byte[] macAddress;
+@SystemApi
+public final class NativeWifiClient implements Parcelable {
+ /**
+ * The raw bytes of the MAC address of the client (STA) represented by this object.
+ */
+ @NonNull public final byte[] macAddress;
- /** public constructor */
- public NativeWifiClient() { }
+ /**
+ * public constructor
+ * @hide
+ */
+ public NativeWifiClient(@NonNull byte[] macAddress) {
+ this.macAddress = macAddress;
+ }
/** override comparator */
@Override
@@ -60,18 +71,20 @@
* |flag| is ignored.
*/
@Override
- public void writeToParcel(Parcel out, int flags) {
+ public void writeToParcel(@NonNull Parcel out, int flags) {
out.writeByteArray(macAddress);
}
/** implement Parcelable interface */
- public static final Parcelable.Creator<NativeWifiClient> CREATOR =
+ @NonNull public static final Parcelable.Creator<NativeWifiClient> CREATOR =
new Parcelable.Creator<NativeWifiClient>() {
@Override
public NativeWifiClient createFromParcel(Parcel in) {
- NativeWifiClient result = new NativeWifiClient();
- result.macAddress = in.createByteArray();
- return result;
+ byte[] macAddress = in.createByteArray();
+ if (macAddress == null) {
+ macAddress = new byte[0];
+ }
+ return new NativeWifiClient(macAddress);
}
@Override
diff --git a/wifi/java/android/net/wifi/wificond/PnoNetwork.java b/wifi/java/android/net/wifi/wificond/PnoNetwork.java
index f923fd3..ca0b1cf 100644
--- a/wifi/java/android/net/wifi/wificond/PnoNetwork.java
+++ b/wifi/java/android/net/wifi/wificond/PnoNetwork.java
@@ -16,6 +16,8 @@
package android.net.wifi.wificond;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -23,17 +25,85 @@
import java.util.Objects;
/**
- * PnoNetwork for wificond
+ * Configuration for a PNO (preferred network offload) network used in {@link PnoSettings}. A PNO
+ * network allows configuration of a specific network to search for.
*
* @hide
*/
-public class PnoNetwork implements Parcelable {
+@SystemApi
+public final class PnoNetwork implements Parcelable {
+ private boolean mIsHidden;
+ private byte[] mSsid;
+ private int[] mFrequencies;
- public boolean isHidden;
- public byte[] ssid;
- public int[] frequencies;
+ /**
+ * Indicates whether the PNO network configuration is for a hidden SSID - i.e. a network which
+ * does not broadcast its SSID and must be queried explicitly.
+ *
+ * @return True if the configuration is for a hidden network, false otherwise.
+ */
+ public boolean isHidden() {
+ return mIsHidden;
+ }
- /** public constructor */
+ /**
+ * Configure whether the PNO network configuration is for a hidden SSID - i.e. a network which
+ * does not broadcast its SSID and must be queried explicitly.
+ *
+ * @param isHidden True if the configuration is for a hidden network, false otherwise.
+ */
+ public void setHidden(boolean isHidden) {
+ mIsHidden = isHidden;
+ }
+
+ /**
+ * Get the raw bytes for the SSID of the PNO network being scanned for.
+ *
+ * @return A byte array.
+ */
+ @NonNull public byte[] getSsid() {
+ return mSsid;
+ }
+
+ /**
+ * Set the raw bytes for the SSID of the PNO network being scanned for.
+ *
+ * @param ssid A byte array.
+ */
+ public void setSsid(@NonNull byte[] ssid) {
+ if (ssid == null) {
+ throw new IllegalArgumentException("null argument");
+ }
+ this.mSsid = ssid;
+ }
+
+ /**
+ * Get the frequencies (in MHz) on which to PNO scan for the current network is being searched
+ * for. A null return (i.e. no frequencies configured) indicates that the network is search for
+ * on all supported frequencies.
+ *
+ * @return A array of frequencies (in MHz), a null indicates no configured frequencies.
+ */
+ @NonNull public int[] getFrequenciesMhz() {
+ return mFrequencies;
+ }
+
+ /**
+ * Set the frequencies (in MHz) on which to PNO scan for the current network is being searched
+ * for. A null configuration (i.e. no frequencies configured) indicates that the network is
+ * search for on all supported frequencies.
+ *
+ * @param frequenciesMhz an array of frequencies (in MHz), null indicating no configured
+ * frequencies.
+ */
+ public void setFrequenciesMhz(@NonNull int[] frequenciesMhz) {
+ if (frequenciesMhz == null) {
+ throw new IllegalArgumentException("null argument");
+ }
+ this.mFrequencies = frequenciesMhz;
+ }
+
+ /** Construct an uninitialized PnoNetwork object */
public PnoNetwork() { }
/** override comparator */
@@ -44,18 +114,18 @@
return false;
}
PnoNetwork network = (PnoNetwork) rhs;
- return Arrays.equals(ssid, network.ssid)
- && Arrays.equals(frequencies, network.frequencies)
- && isHidden == network.isHidden;
+ return Arrays.equals(mSsid, network.mSsid)
+ && Arrays.equals(mFrequencies, network.mFrequencies)
+ && mIsHidden == network.mIsHidden;
}
/** override hash code */
@Override
public int hashCode() {
return Objects.hash(
- isHidden,
- Arrays.hashCode(ssid),
- Arrays.hashCode(frequencies));
+ mIsHidden,
+ Arrays.hashCode(mSsid),
+ Arrays.hashCode(mFrequencies));
}
/** implement Parcelable interface */
@@ -69,21 +139,27 @@
* |flag| is ignored.
*/
@Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(isHidden ? 1 : 0);
- out.writeByteArray(ssid);
- out.writeIntArray(frequencies);
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeInt(mIsHidden ? 1 : 0);
+ out.writeByteArray(mSsid);
+ out.writeIntArray(mFrequencies);
}
/** implement Parcelable interface */
- public static final Parcelable.Creator<PnoNetwork> CREATOR =
+ @NonNull public static final Parcelable.Creator<PnoNetwork> CREATOR =
new Parcelable.Creator<PnoNetwork>() {
@Override
public PnoNetwork createFromParcel(Parcel in) {
PnoNetwork result = new PnoNetwork();
- result.isHidden = in.readInt() != 0 ? true : false;
- result.ssid = in.createByteArray();
- result.frequencies = in.createIntArray();
+ result.mIsHidden = in.readInt() != 0 ? true : false;
+ result.mSsid = in.createByteArray();
+ if (result.mSsid == null) {
+ result.mSsid = new byte[0];
+ }
+ result.mFrequencies = in.createIntArray();
+ if (result.mFrequencies == null) {
+ result.mFrequencies = new int[0];
+ }
return result;
}
diff --git a/wifi/java/android/net/wifi/wificond/PnoSettings.java b/wifi/java/android/net/wifi/wificond/PnoSettings.java
index 96cf24f..57c9ca5 100644
--- a/wifi/java/android/net/wifi/wificond/PnoSettings.java
+++ b/wifi/java/android/net/wifi/wificond/PnoSettings.java
@@ -16,27 +16,130 @@
package android.net.wifi.wificond;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
/**
- * PnoSettings for wificond
+ * Configuration for a PNO (preferred network offload). A mechanism by which scans are offloaded
+ * from the host device to the Wi-Fi chip.
*
* @hide
*/
-public class PnoSettings implements Parcelable {
- public int intervalMs;
- public int min2gRssi;
- public int min5gRssi;
- public int min6gRssi;
- public ArrayList<PnoNetwork> pnoNetworks;
+@SystemApi
+public final class PnoSettings implements Parcelable {
+ private int mIntervalMs;
+ private int mMin2gRssi;
+ private int mMin5gRssi;
+ private int mMin6gRssi;
+ private List<PnoNetwork> mPnoNetworks;
- /** public constructor */
+ /** Construct an uninitialized PnoSettings object */
public PnoSettings() { }
+ /**
+ * Get the requested PNO scan interval in milliseconds.
+ *
+ * @return An interval in milliseconds.
+ */
+ public int getIntervalMillis() {
+ return mIntervalMs;
+ }
+
+ /**
+ * Set the requested PNO scan interval in milliseconds.
+ *
+ * @param intervalMs An interval in milliseconds.
+ */
+ public void setIntervalMillis(int intervalMs) {
+ this.mIntervalMs = intervalMs;
+ }
+
+ /**
+ * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the
+ * 2.4GHz band.
+ *
+ * @return An RSSI value in dBm.
+ */
+ public int getMin2gRssiDbm() {
+ return mMin2gRssi;
+ }
+
+ /**
+ * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in
+ * the 2.4GHz band.
+ *
+ * @param min2gRssiDbm An RSSI value in dBm.
+ */
+ public void setMin2gRssiDbm(int min2gRssiDbm) {
+ this.mMin2gRssi = min2gRssiDbm;
+ }
+
+ /**
+ * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the
+ * 5GHz band.
+ *
+ * @return An RSSI value in dBm.
+ */
+ public int getMin5gRssiDbm() {
+ return mMin5gRssi;
+ }
+
+ /**
+ * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in
+ * the 5GHz band.
+ *
+ * @param min5gRssiDbm An RSSI value in dBm.
+ */
+ public void setMin5gRssiDbm(int min5gRssiDbm) {
+ this.mMin5gRssi = min5gRssiDbm;
+ }
+
+ /**
+ * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the
+ * 6GHz band.
+ *
+ * @return An RSSI value in dBm.
+ */
+ public int getMin6gRssiDbm() {
+ return mMin6gRssi;
+ }
+
+ /**
+ * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in
+ * the 6GHz band.
+ *
+ * @param min6gRssiDbm An RSSI value in dBm.
+ */
+ public void setMin6gRssiDbm(int min6gRssiDbm) {
+ this.mMin6gRssi = min6gRssiDbm;
+ }
+
+ /**
+ * Return the configured list of specific networks to search for in a PNO scan.
+ *
+ * @return A list of {@link PnoNetwork} objects, possibly empty if non configured.
+ */
+ @NonNull public List<PnoNetwork> getPnoNetworks() {
+ return mPnoNetworks;
+ }
+
+ /**
+ * Set the list of specified networks to scan for in a PNO scan. The networks (APs) are
+ * specified using {@link PnoNetwork}s. An empty list indicates that all networks are scanned
+ * for.
+ *
+ * @param pnoNetworks A (possibly empty) list of {@link PnoNetwork} objects.
+ */
+ public void setPnoNetworks(@NonNull List<PnoNetwork> pnoNetworks) {
+ this.mPnoNetworks = pnoNetworks;
+ }
+
/** override comparator */
@Override
public boolean equals(Object rhs) {
@@ -48,17 +151,17 @@
if (settings == null) {
return false;
}
- return intervalMs == settings.intervalMs
- && min2gRssi == settings.min2gRssi
- && min5gRssi == settings.min5gRssi
- && min6gRssi == settings.min6gRssi
- && pnoNetworks.equals(settings.pnoNetworks);
+ return mIntervalMs == settings.mIntervalMs
+ && mMin2gRssi == settings.mMin2gRssi
+ && mMin5gRssi == settings.mMin5gRssi
+ && mMin6gRssi == settings.mMin6gRssi
+ && mPnoNetworks.equals(settings.mPnoNetworks);
}
/** override hash code */
@Override
public int hashCode() {
- return Objects.hash(intervalMs, min2gRssi, min5gRssi, min6gRssi, pnoNetworks);
+ return Objects.hash(mIntervalMs, mMin2gRssi, mMin5gRssi, mMin6gRssi, mPnoNetworks);
}
/** implement Parcelable interface */
@@ -72,27 +175,27 @@
* |flag| is ignored.
**/
@Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(intervalMs);
- out.writeInt(min2gRssi);
- out.writeInt(min5gRssi);
- out.writeInt(min6gRssi);
- out.writeTypedList(pnoNetworks);
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeInt(mIntervalMs);
+ out.writeInt(mMin2gRssi);
+ out.writeInt(mMin5gRssi);
+ out.writeInt(mMin6gRssi);
+ out.writeTypedList(mPnoNetworks);
}
/** implement Parcelable interface */
- public static final Parcelable.Creator<PnoSettings> CREATOR =
+ @NonNull public static final Parcelable.Creator<PnoSettings> CREATOR =
new Parcelable.Creator<PnoSettings>() {
@Override
public PnoSettings createFromParcel(Parcel in) {
PnoSettings result = new PnoSettings();
- result.intervalMs = in.readInt();
- result.min2gRssi = in.readInt();
- result.min5gRssi = in.readInt();
- result.min6gRssi = in.readInt();
+ result.mIntervalMs = in.readInt();
+ result.mMin2gRssi = in.readInt();
+ result.mMin5gRssi = in.readInt();
+ result.mMin6gRssi = in.readInt();
- result.pnoNetworks = new ArrayList<PnoNetwork>();
- in.readTypedList(result.pnoNetworks, PnoNetwork.CREATOR);
+ result.mPnoNetworks = new ArrayList<>();
+ in.readTypedList(result.mPnoNetworks, PnoNetwork.CREATOR);
return result;
}
diff --git a/wifi/java/android/net/wifi/wificond/RadioChainInfo.java b/wifi/java/android/net/wifi/wificond/RadioChainInfo.java
index 2b03450..64102dd 100644
--- a/wifi/java/android/net/wifi/wificond/RadioChainInfo.java
+++ b/wifi/java/android/net/wifi/wificond/RadioChainInfo.java
@@ -16,26 +16,52 @@
package android.net.wifi.wificond;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.Objects;
/**
- * RadioChainInfo for wificond
+ * A class representing the radio chains of the Wi-Fi modems. Use to provide raw information about
+ * signals received on different radio chains.
*
* @hide
*/
-public class RadioChainInfo implements Parcelable {
+@SystemApi
+public final class RadioChainInfo implements Parcelable {
private static final String TAG = "RadioChainInfo";
+ /** @hide */
+ @VisibleForTesting
public int chainId;
+ /** @hide */
+ @VisibleForTesting
public int level;
+ /**
+ * Return an identifier for this radio chain. This is an arbitrary ID which is consistent for
+ * the same device.
+ *
+ * @return The radio chain ID.
+ */
+ public int getChainId() {
+ return chainId;
+ }
- /** public constructor */
- public RadioChainInfo() { }
+ /**
+ * Returns the detected signal level on this radio chain in dBm (aka RSSI).
+ *
+ * @return A signal level in dBm.
+ */
+ public int getLevelDbm() {
+ return level;
+ }
+ /** @hide */
public RadioChainInfo(int chainId, int level) {
this.chainId = chainId;
this.level = level;
@@ -73,23 +99,20 @@
* |flags| is ignored.
*/
@Override
- public void writeToParcel(Parcel out, int flags) {
+ public void writeToParcel(@NonNull Parcel out, int flags) {
out.writeInt(chainId);
out.writeInt(level);
}
/** implement Parcelable interface */
- public static final Parcelable.Creator<RadioChainInfo> CREATOR =
+ @NonNull public static final Parcelable.Creator<RadioChainInfo> CREATOR =
new Parcelable.Creator<RadioChainInfo>() {
/**
* Caller is responsible for providing a valid parcel.
*/
@Override
public RadioChainInfo createFromParcel(Parcel in) {
- RadioChainInfo result = new RadioChainInfo();
- result.chainId = in.readInt();
- result.level = in.readInt();
- return result;
+ return new RadioChainInfo(in.readInt(), in.readInt());
}
@Override
diff --git a/wifi/java/android/net/wifi/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java
similarity index 61%
rename from wifi/java/android/net/wifi/WifiCondManager.java
rename to wifi/java/android/net/wifi/wificond/WifiCondManager.java
index c05ba34..94f1212 100644
--- a/wifi/java/android/net/wifi/WifiCondManager.java
+++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java
@@ -14,18 +14,27 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.net.wifi.wificond;
+import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
import android.app.AlarmManager;
import android.content.Context;
-import android.net.wifi.wificond.ChannelSettings;
-import android.net.wifi.wificond.HiddenNetwork;
-import android.net.wifi.wificond.NativeScanResult;
-import android.net.wifi.wificond.NativeWifiClient;
-import android.net.wifi.wificond.PnoSettings;
-import android.net.wifi.wificond.SingleScanSettings;
+import android.net.wifi.IApInterface;
+import android.net.wifi.IApInterfaceEventCallback;
+import android.net.wifi.IClientInterface;
+import android.net.wifi.IPnoScanEvent;
+import android.net.wifi.IScanEvent;
+import android.net.wifi.ISendMgmtFrameEvent;
+import android.net.wifi.IWifiScannerImpl;
+import android.net.wifi.IWificond;
+import android.net.wifi.SoftApInfo;
+import android.net.wifi.WifiAnnotations;
+import android.net.wifi.WifiScanner;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -44,37 +53,48 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
/**
- * This class provides methods for WifiNative to send control commands to wificond.
- * NOTE: This class should only be used from WifiNative.
+ * This class encapsulates the interface the wificond daemon presents to the Wi-Fi framework. The
+ * interface is only for use by the Wi-Fi framework and access is protected by SELinux permissions.
+ *
* @hide
*/
-public class WifiCondManager implements IBinder.DeathRecipient {
+@SystemApi
+@SystemService(Context.WIFI_COND_SERVICE)
+public class WifiCondManager {
private static final String TAG = "WifiCondManager";
private boolean mVerboseLoggingEnabled = false;
/**
- * The {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}
+ * The {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}
* timeout, in milliseconds, after which
* {@link SendMgmtFrameCallback#onFailure(int)} will be called with reason
* {@link #SEND_MGMT_FRAME_ERROR_TIMEOUT}.
*/
- public static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000;
+ private static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000;
private static final String TIMEOUT_ALARM_TAG = TAG + " Send Management Frame Timeout";
+ /** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"SCAN_TYPE_"},
value = {SCAN_TYPE_SINGLE_SCAN,
SCAN_TYPE_PNO_SCAN})
public @interface ScanResultType {}
- /** Get scan results for a single scan */
+ /**
+ * Specifies a scan type: single scan initiated by the framework. Can be used in
+ * {@link #getScanResults(String, int)} to specify the type of scan result to fetch.
+ */
public static final int SCAN_TYPE_SINGLE_SCAN = 0;
- /** Get scan results for Pno Scan */
+ /**
+ * Specifies a scan type: PNO scan. Can be used in {@link #getScanResults(String, int)} to
+ * specify the type of scan result to fetch.
+ */
public static final int SCAN_TYPE_PNO_SCAN = 1;
private AlarmManager mAlarmManager;
@@ -95,11 +115,12 @@
private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false);
/**
- * Interface for a callback to be used to handle scan results.
+ * Interface used when waiting for scans to be completed (with results).
*/
public interface ScanEventCallback {
/**
- * Called when scan results are available.
+ * Called when scan results are available. Scans results should then be obtained from
+ * {@link #getScanResults(String, int)}.
*/
void onScanResultReady();
@@ -110,11 +131,14 @@
}
/**
- * Interface for a callback to provide information about PNO scan request.
+ * Interface for a callback to provide information about PNO scan request requested with
+ * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. Note that the
+ * callback are for the status of the request - not the scan itself. The results of the scan
+ * are returned with {@link ScanEventCallback}.
*/
public interface PnoScanRequestCallback {
/**
- * Called when the PNO scan is requested.
+ * Called when a PNO scan request has been successfully submitted.
*/
void onPnoRequestSucceeded();
@@ -125,73 +149,116 @@
}
private class ScanEventHandler extends IScanEvent.Stub {
+ private Executor mExecutor;
private ScanEventCallback mCallback;
- ScanEventHandler(@NonNull ScanEventCallback callback) {
+ ScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) {
+ mExecutor = executor;
mCallback = callback;
}
@Override
public void OnScanResultReady() {
Log.d(TAG, "Scan result ready event");
- mCallback.onScanResultReady();
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mCallback.onScanResultReady());
}
@Override
public void OnScanFailed() {
Log.d(TAG, "Scan failed event");
- mCallback.onScanFailed();
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mCallback.onScanFailed());
}
}
/**
- * Result of a signal poll.
+ * Result of a signal poll requested using {@link #signalPoll(String)}.
*/
public static class SignalPollResult {
- // RSSI value in dBM.
- public int currentRssi;
- //Transmission bit rate in Mbps.
- public int txBitrate;
- // Association frequency in MHz.
- public int associationFrequency;
- //Last received packet bit rate in Mbps.
- public int rxBitrate;
+ /** @hide */
+ public SignalPollResult(int currentRssiDbm, int txBitrateMbps, int rxBitrateMbps,
+ int associationFrequencyMHz) {
+ this.currentRssiDbm = currentRssiDbm;
+ this.txBitrateMbps = txBitrateMbps;
+ this.rxBitrateMbps = rxBitrateMbps;
+ this.associationFrequencyMHz = associationFrequencyMHz;
+ }
+
+ /**
+ * RSSI value in dBM.
+ */
+ public final int currentRssiDbm;
+
+ /**
+ * Transmission bit rate in Mbps.
+ */
+ public final int txBitrateMbps;
+
+ /**
+ * Last received packet bit rate in Mbps.
+ */
+ public final int rxBitrateMbps;
+
+ /**
+ * Association frequency in MHz.
+ */
+ public final int associationFrequencyMHz;
}
/**
- * WiFi interface transimission counters.
+ * Transmission counters obtained using {@link #getTxPacketCounters(String)}.
*/
public static class TxPacketCounters {
- // Number of successfully transmitted packets.
- public int txSucceeded;
- // Number of tramsmission failures.
- public int txFailed;
+ /** @hide */
+ public TxPacketCounters(int txPacketSucceeded, int txPacketFailed) {
+ this.txPacketSucceeded = txPacketSucceeded;
+ this.txPacketFailed = txPacketFailed;
+ }
+
+ /**
+ * Number of successfully transmitted packets.
+ */
+ public final int txPacketSucceeded;
+
+ /**
+ * Number of packet transmission failures.
+ */
+ public final int txPacketFailed;
}
/**
- * Callbacks for SoftAp interface.
+ * Callbacks for SoftAp interface registered using
+ * {@link #registerApCallback(String, Executor, SoftApCallback)}.
*/
- public interface SoftApListener {
+ public interface SoftApCallback {
/**
- * Invoked when there is some fatal failure in the lower layers.
+ * Invoked when there is a fatal failure and the SoftAp is shutdown.
*/
void onFailure();
/**
- * Invoked when the associated stations changes.
+ * Invoked when there is a change in the associated station (STA).
+ * @param client Information about the client whose status has changed.
+ * @param isConnected Indication as to whether the client is connected (true), or
+ * disconnected (false).
*/
- void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected);
+ void onConnectedClientsChanged(@NonNull NativeWifiClient client, boolean isConnected);
/**
- * Invoked when the channel switch event happens.
+ * Invoked when a channel switch event happens - i.e. the SoftAp is moved to a different
+ * channel. Also called on initial registration.
+ * @param frequencyMhz The new frequency of the SoftAp. A value of 0 is invalid and is an
+ * indication that the SoftAp is not enabled.
+ * @param bandwidth The new bandwidth of the SoftAp.
*/
- void onSoftApChannelSwitched(int frequency, int bandwidth);
+ void onSoftApChannelSwitched(int frequencyMhz, @WifiAnnotations.Bandwidth int bandwidth);
}
/**
* Callback to notify the results of a
- * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} call.
- * Note: no callbacks will be triggered if the iface dies while sending a frame.
+ * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} call.
+ * Note: no callbacks will be triggered if the interface dies while sending a frame.
*/
public interface SendMgmtFrameCallback {
/**
@@ -211,6 +278,7 @@
void onFailure(@SendMgmtFrameError int reason);
}
+ /** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"SEND_MGMT_FRAME_ERROR_"},
value = {SEND_MGMT_FRAME_ERROR_UNKNOWN,
@@ -224,43 +292,44 @@
/**
* Unknown error occurred during call to
- * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}.
+ * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}.
*/
public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1;
/**
* Specifying the MCS rate in
- * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} is not
+ * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} is not
* supported by this device.
*/
public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2;
/**
* Driver reported that no ACK was received for the frame transmitted using
- * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}.
+ * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}.
*/
public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3;
/**
* Error code for when the driver fails to report on the status of the frame sent by
- * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}
+ * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}
* after {@link #SEND_MGMT_FRAME_TIMEOUT_MS} milliseconds.
*/
public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4;
/**
* An existing call to
- * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}
+ * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}
* is in progress. Another frame cannot be sent until the first call completes.
*/
public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5;
-
+ /** @hide */
public WifiCondManager(Context context) {
- mAlarmManager = (AlarmManager) context.getSystemService(AlarmManager.class);
+ mAlarmManager = context.getSystemService(AlarmManager.class);
mEventHandler = new Handler(context.getMainLooper());
}
+ /** @hide */
@VisibleForTesting
public WifiCondManager(Context context, IWificond wificond) {
this(context);
@@ -268,22 +337,26 @@
}
private class PnoScanEventHandler extends IPnoScanEvent.Stub {
+ private Executor mExecutor;
private ScanEventCallback mCallback;
- PnoScanEventHandler(@NonNull ScanEventCallback callback) {
+ PnoScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) {
+ mExecutor = executor;
mCallback = callback;
}
@Override
public void OnPnoNetworkFound() {
Log.d(TAG, "Pno scan result event");
- mCallback.onScanResultReady();
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mCallback.onScanResultReady());
}
@Override
public void OnPnoScanFailed() {
Log.d(TAG, "Pno Scan failed event");
- mCallback.onScanFailed();
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mCallback.onScanFailed());
}
}
@@ -291,9 +364,11 @@
* Listener for AP Interface events.
*/
private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub {
- private SoftApListener mSoftApListener;
+ private Executor mExecutor;
+ private SoftApCallback mSoftApListener;
- ApInterfaceEventCallback(SoftApListener listener) {
+ ApInterfaceEventCallback(Executor executor, SoftApCallback listener) {
+ mExecutor = executor;
mSoftApListener = listener;
}
@@ -304,12 +379,36 @@
+ client.macAddress + " isConnected: " + isConnected);
}
- mSoftApListener.onConnectedClientsChanged(client, isConnected);
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mSoftApListener.onConnectedClientsChanged(client, isConnected));
}
@Override
public void onSoftApChannelSwitched(int frequency, int bandwidth) {
- mSoftApListener.onSoftApChannelSwitched(frequency, bandwidth);
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mSoftApListener.onSoftApChannelSwitched(frequency,
+ toFrameworkBandwidth(bandwidth)));
+ }
+
+ private @WifiAnnotations.Bandwidth int toFrameworkBandwidth(int bandwidth) {
+ switch(bandwidth) {
+ case IApInterfaceEventCallback.BANDWIDTH_INVALID:
+ return SoftApInfo.CHANNEL_WIDTH_INVALID;
+ case IApInterfaceEventCallback.BANDWIDTH_20_NOHT:
+ return SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT;
+ case IApInterfaceEventCallback.BANDWIDTH_20:
+ return SoftApInfo.CHANNEL_WIDTH_20MHZ;
+ case IApInterfaceEventCallback.BANDWIDTH_40:
+ return SoftApInfo.CHANNEL_WIDTH_40MHZ;
+ case IApInterfaceEventCallback.BANDWIDTH_80:
+ return SoftApInfo.CHANNEL_WIDTH_80MHZ;
+ case IApInterfaceEventCallback.BANDWIDTH_80P80:
+ return SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
+ case IApInterfaceEventCallback.BANDWIDTH_160:
+ return SoftApInfo.CHANNEL_WIDTH_160MHZ;
+ default:
+ return SoftApInfo.CHANNEL_WIDTH_INVALID;
+ }
}
}
@@ -317,6 +416,7 @@
* Callback triggered by wificond.
*/
private class SendMgmtFrameEvent extends ISendMgmtFrameEvent.Stub {
+ private Executor mExecutor;
private SendMgmtFrameCallback mCallback;
private AlarmManager.OnAlarmListener mTimeoutCallback;
/**
@@ -332,14 +432,16 @@
r.run();
}
- SendMgmtFrameEvent(@NonNull SendMgmtFrameCallback callback) {
+ SendMgmtFrameEvent(@NonNull Executor executor, @NonNull SendMgmtFrameCallback callback) {
+ mExecutor = executor;
mCallback = callback;
// called in main thread
mTimeoutCallback = () -> runIfFirstCall(() -> {
if (mVerboseLoggingEnabled) {
Log.e(TAG, "Timed out waiting for ACK");
}
- mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT);
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT));
});
mWasCalled = false;
@@ -354,7 +456,8 @@
// post to main thread
mEventHandler.post(() -> runIfFirstCall(() -> {
mAlarmManager.cancel(mTimeoutCallback);
- mCallback.onAck(elapsedTimeMs);
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mCallback.onAck(elapsedTimeMs));
}));
}
@@ -364,7 +467,8 @@
// post to main thread
mEventHandler.post(() -> runIfFirstCall(() -> {
mAlarmManager.cancel(mTimeoutCallback);
- mCallback.onFailure(reason);
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mCallback.onFailure(reason));
}));
}
}
@@ -372,8 +476,9 @@
/**
* Called by the binder subsystem upon remote object death.
* Invoke all the register death handlers and clear state.
+ * @hide
*/
- @Override
+ @VisibleForTesting
public void binderDied() {
mEventHandler.post(() -> {
Log.e(TAG, "Wificond died!");
@@ -387,17 +492,22 @@
});
}
- /** Enable or disable verbose logging of WificondControl.
- * @param enable True to enable verbose logging. False to disable verbose logging.
+ /**
+ * Enable or disable verbose logging of the WifiCondManager module.
+ * @param enable True to enable verbose logging. False to disable verbose logging.
*/
public void enableVerboseLogging(boolean enable) {
mVerboseLoggingEnabled = enable;
}
/**
- * Initializes wificond & registers a death notification for wificond.
- * This method clears any existing state in wificond daemon.
+ * Initializes WifiCondManager & registers a death notification for the WifiCondManager which
+ * acts as a proxy for the wificond daemon (i.e. the death listener will be called when and if
+ * the wificond daemon dies).
*
+ * Note: This method clears any existing state in wificond daemon.
+ *
+ * @param deathEventHandler A {@link Runnable} to be called whenever the wificond daemon dies.
* @return Returns true on success.
*/
public boolean initialize(@NonNull Runnable deathEventHandler) {
@@ -428,7 +538,7 @@
return false;
}
try {
- mWificond.asBinder().linkToDeath(this, 0);
+ mWificond.asBinder().linkToDeath(() -> binderDied(), 0);
} catch (RemoteException e) {
Log.e(TAG, "Failed to register death notification for wificond");
// The remote has already died.
@@ -438,16 +548,27 @@
}
/**
- * Setup interface for client mode via wificond.
- * @return true on success.
- */
+ * Set up an interface for client (STA) mode.
+ *
+ * @param ifaceName Name of the interface to configure.
+ * @param executor The Executor on which to execute the callbacks.
+ * @param scanCallback A callback for framework initiated scans.
+ * @param pnoScanCallback A callback for PNO (offloaded) scans.
+ * @return true on success.
+ */
public boolean setupInterfaceForClientMode(@NonNull String ifaceName,
+ @NonNull @CallbackExecutor Executor executor,
@NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) {
Log.d(TAG, "Setting up interface for client mode");
if (!retrieveWificondAndRegisterForDeath()) {
return false;
}
+ if (scanCallback == null || pnoScanCallback == null || executor == null) {
+ Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks");
+ return false;
+ }
+
IClientInterface clientInterface = null;
try {
clientInterface = mWificond.createClientInterface(ifaceName);
@@ -472,10 +593,11 @@
}
mWificondScanners.put(ifaceName, wificondScanner);
Binder.allowBlocking(wificondScanner.asBinder());
- ScanEventHandler scanEventHandler = new ScanEventHandler(scanCallback);
+ ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback);
mScanEventHandlers.put(ifaceName, scanEventHandler);
wificondScanner.subscribeScanEvents(scanEventHandler);
- PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(pnoScanCallback);
+ PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor,
+ pnoScanCallback);
mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler);
wificondScanner.subscribePnoScanEvents(pnoScanEventHandler);
} catch (RemoteException e) {
@@ -486,8 +608,10 @@
}
/**
- * Teardown a specific STA interface configured in wificond.
+ * Tear down a specific client (STA) interface, initially configured using
+ * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}.
*
+ * @param ifaceName Name of the interface to tear down.
* @return Returns true on success.
*/
public boolean tearDownClientInterface(@NonNull String ifaceName) {
@@ -531,9 +655,11 @@
}
/**
- * Setup interface for softAp mode via wificond.
- * @return true on success.
- */
+ * Set up interface as a Soft AP.
+ *
+ * @param ifaceName Name of the interface to configure.
+ * @return true on success.
+ */
public boolean setupInterfaceForSoftApMode(@NonNull String ifaceName) {
Log.d(TAG, "Setting up interface for soft ap mode");
if (!retrieveWificondAndRegisterForDeath()) {
@@ -560,8 +686,10 @@
}
/**
- * Teardown a specific AP interface configured in wificond.
+ * Tear down a Soft AP interface initially configured using
+ * {@link #setupInterfaceForSoftApMode(String)}.
*
+ * @param ifaceName Name of the interface to tear down.
* @return Returns true on success.
*/
public boolean tearDownSoftApInterface(@NonNull String ifaceName) {
@@ -592,7 +720,8 @@
}
/**
- * Teardown all interfaces configured in wificond.
+ * Tear down all interfaces, whether clients (STA) or Soft AP.
+ *
* @return Returns true on success.
*/
public boolean tearDownInterfaces() {
@@ -624,12 +753,13 @@
}
/**
- * Request signal polling to wificond.
- * @param ifaceName Name of the interface.
- * Returns an SignalPollResult object.
- * Returns null on failure.
+ * Request signal polling.
+ *
+ * @param ifaceName Name of the interface on which to poll.
+ * @return A {@link SignalPollResult} object containing interface statistics, or a null on
+ * error.
*/
- public SignalPollResult signalPoll(@NonNull String ifaceName) {
+ @Nullable public SignalPollResult signalPoll(@NonNull String ifaceName) {
IClientInterface iface = getClientInterface(ifaceName);
if (iface == null) {
Log.e(TAG, "No valid wificond client interface handler");
@@ -647,21 +777,16 @@
Log.e(TAG, "Failed to do signal polling due to remote exception");
return null;
}
- SignalPollResult pollResult = new SignalPollResult();
- pollResult.currentRssi = resultArray[0];
- pollResult.txBitrate = resultArray[1];
- pollResult.associationFrequency = resultArray[2];
- pollResult.rxBitrate = resultArray[3];
- return pollResult;
+ return new SignalPollResult(resultArray[0], resultArray[1], resultArray[3], resultArray[2]);
}
/**
- * Fetch TX packet counters on current connection from wificond.
+ * Get current transmit (Tx) packet counters of the specified interface.
+ *
* @param ifaceName Name of the interface.
- * Returns an TxPacketCounters object.
- * Returns null on failure.
+ * @return {@link TxPacketCounters} of the current interface or null on error.
*/
- public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) {
+ @Nullable public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) {
IClientInterface iface = getClientInterface(ifaceName);
if (iface == null) {
Log.e(TAG, "No valid wificond client interface handler");
@@ -679,10 +804,7 @@
Log.e(TAG, "Failed to do signal polling due to remote exception");
return null;
}
- TxPacketCounters counters = new TxPacketCounters();
- counters.txSucceeded = resultArray[0];
- counters.txFailed = resultArray[1];
- return counters;
+ return new TxPacketCounters(resultArray[0], resultArray[1]);
}
/** Helper function to look up the scanner impl handle using name */
@@ -691,10 +813,16 @@
}
/**
- * Fetch the latest scan result from kernel via wificond.
- * @param ifaceName Name of the interface.
- * @return Returns an array of native scan results or an empty array on failure.
- */
+ * Fetch the latest scan results of the indicated type for the specified interface. Note that
+ * this method fetches the latest results - it does not initiate a scan. Initiating a scan can
+ * be done using {@link #startScan(String, int, Set, List)} or
+ * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}.
+ *
+ * @param ifaceName Name of the interface.
+ * @param scanType The type of scan result to be returned, can be
+ * {@link #SCAN_TYPE_SINGLE_SCAN} or {@link #SCAN_TYPE_PNO_SCAN}.
+ * @return Returns an array of {@link NativeScanResult} or an empty array on failure.
+ */
@NonNull public List<NativeScanResult> getScanResults(@NonNull String ifaceName,
@ScanResultType int scanType) {
IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
@@ -739,15 +867,23 @@
}
/**
- * Start a scan using wificond for the given parameters.
- * @param ifaceName Name of the interface.
- * @param scanType Type of scan to perform.
+ * Start a scan using the specified parameters. A scan is an asynchronous operation. The
+ * result of the operation is returned in the {@link ScanEventCallback} registered when
+ * setting up an interface using
+ * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}.
+ * The latest scans can be obtained using {@link #getScanResults(String, int)} and using a
+ * {@link #SCAN_TYPE_SINGLE_SCAN} for the {@code scanType}.
+ *
+ * @param ifaceName Name of the interface on which to initiate the scan.
+ * @param scanType Type of scan to perform, can be any of
+ * {@link WifiScanner#SCAN_TYPE_HIGH_ACCURACY}, {@link WifiScanner#SCAN_TYPE_LOW_POWER}, or
+ * {@link WifiScanner#SCAN_TYPE_LOW_LATENCY}.
* @param freqs list of frequencies to scan for, if null scan all supported channels.
* @param hiddenNetworkSSIDs List of hidden networks to be scanned for.
* @return Returns true on success.
*/
- public boolean scan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType,
- Set<Integer> freqs, List<byte[]> hiddenNetworkSSIDs) {
+ public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType,
+ @Nullable Set<Integer> freqs, @Nullable List<byte[]> hiddenNetworkSSIDs) {
IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
if (scannerImpl == null) {
Log.e(TAG, "No valid wificond scanner interface handler");
@@ -792,25 +928,40 @@
}
/**
- * Start PNO scan.
- * @param ifaceName Name of the interface.
- * @param pnoSettings Pno scan configuration.
+ * Request a PNO (Preferred Network Offload). The offload request and the scans are asynchronous
+ * operations. The result of the request are returned in the {@code callback} parameter which
+ * is an {@link PnoScanRequestCallback}. The scan results are are return in the
+ * {@link ScanEventCallback} which is registered when setting up an interface using
+ * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}.
+ * The latest PNO scans can be obtained using {@link #getScanResults(String, int)} with the
+ * {@code scanType} set to {@link #SCAN_TYPE_PNO_SCAN}.
+ *
+ * @param ifaceName Name of the interface on which to request a PNO.
+ * @param pnoSettings PNO scan configuration.
+ * @param executor The Executor on which to execute the callback.
+ * @param callback Callback for the results of the offload request.
* @return true on success.
*/
- public boolean startPnoScan(@NonNull String ifaceName, PnoSettings pnoSettings,
- PnoScanRequestCallback callback) {
+ public boolean startPnoScan(@NonNull String ifaceName, @NonNull PnoSettings pnoSettings,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull PnoScanRequestCallback callback) {
IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
if (scannerImpl == null) {
Log.e(TAG, "No valid wificond scanner interface handler");
return false;
}
+ if (callback == null || executor == null) {
+ Log.e(TAG, "startPnoScan called with a null callback");
+ return false;
+ }
+
try {
boolean success = scannerImpl.startPnoScan(pnoSettings);
if (success) {
- callback.onPnoRequestSucceeded();
+ executor.execute(callback::onPnoRequestSucceeded);
} else {
- callback.onPnoRequestFailed();
+ executor.execute(callback::onPnoRequestFailed);
}
return success;
} catch (RemoteException e1) {
@@ -820,8 +971,10 @@
}
/**
- * Stop PNO scan.
- * @param ifaceName Name of the interface.
+ * Stop PNO scan configured with
+ * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}.
+ *
+ * @param ifaceName Name of the interface on which the PNO scan was configured.
* @return true on success.
*/
public boolean stopPnoScan(@NonNull String ifaceName) {
@@ -839,8 +992,9 @@
}
/**
- * Abort ongoing single scan.
- * @param ifaceName Name of the interface.
+ * Abort ongoing single scan started with {@link #startScan(String, int, Set, List)}.
+ *
+ * @param ifaceName Name of the interface on which the scan was started.
*/
public void abortScan(@NonNull String ifaceName) {
IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
@@ -856,7 +1010,7 @@
}
/**
- * Query the list of valid frequencies for the provided band.
+ * Query the list of valid frequencies (in MHz) for the provided band.
* The result depends on the on the country code that has been set.
*
* @param band as specified by one of the WifiScanner.WIFI_BAND_* constants.
@@ -865,31 +1019,39 @@
* WifiScanner.WIFI_BAND_5_GHZ
* WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY
* WifiScanner.WIFI_BAND_6_GHZ
- * @return frequencies vector of valid frequencies (MHz), or null for error.
+ * @return frequencies vector of valid frequencies (MHz), or an empty array for error.
* @throws IllegalArgumentException if band is not recognized.
*/
- public int [] getChannelsForBand(@WifiAnnotations.WifiBandBasic int band) {
+ public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) {
if (mWificond == null) {
Log.e(TAG, "No valid wificond scanner interface handler");
- return null;
+ return new int[0];
}
+ int[] result = null;
try {
switch (band) {
case WifiScanner.WIFI_BAND_24_GHZ:
- return mWificond.getAvailable2gChannels();
+ result = mWificond.getAvailable2gChannels();
+ break;
case WifiScanner.WIFI_BAND_5_GHZ:
- return mWificond.getAvailable5gNonDFSChannels();
+ result = mWificond.getAvailable5gNonDFSChannels();
+ break;
case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY:
- return mWificond.getAvailableDFSChannels();
+ result = mWificond.getAvailableDFSChannels();
+ break;
case WifiScanner.WIFI_BAND_6_GHZ:
- return mWificond.getAvailable6gChannels();
+ result = mWificond.getAvailable6gChannels();
+ break;
default:
throw new IllegalArgumentException("unsupported band " + band);
}
} catch (RemoteException e1) {
Log.e(TAG, "Failed to request getChannelsForBand due to remote exception");
}
- return null;
+ if (result == null) {
+ result = new int[0];
+ }
+ return result;
}
/** Helper function to look up the interface handle using name */
@@ -898,22 +1060,33 @@
}
/**
- * Register the provided listener for SoftAp events.
+ * Register the provided callback handler for SoftAp events. Note that the Soft AP itself is
+ * configured using {@link #setupInterfaceForSoftApMode(String)}.
*
- * @param ifaceName Name of the interface.
- * @param listener Callback for AP events.
+ * @param ifaceName Name of the interface on which to register the callback.
+ * @param executor The Executor on which to execute the callbacks.
+ * @param callback Callback for AP events.
* @return true on success, false otherwise.
*/
- public boolean registerApListener(@NonNull String ifaceName, SoftApListener listener) {
+ public boolean registerApCallback(@NonNull String ifaceName,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull SoftApCallback callback) {
IApInterface iface = getApInterface(ifaceName);
if (iface == null) {
Log.e(TAG, "No valid ap interface handler");
return false;
}
+
+ if (callback == null || executor == null) {
+ Log.e(TAG, "registerApCallback called with a null callback");
+ return false;
+ }
+
try {
- IApInterfaceEventCallback callback = new ApInterfaceEventCallback(listener);
- mApInterfaceListeners.put(ifaceName, callback);
- boolean success = iface.registerCallback(callback);
+ IApInterfaceEventCallback wificondCallback = new ApInterfaceEventCallback(executor,
+ callback);
+ mApInterfaceListeners.put(ifaceName, wificondCallback);
+ boolean success = iface.registerCallback(wificondCallback);
if (!success) {
Log.e(TAG, "Failed to register ap callback.");
return false;
@@ -926,19 +1099,28 @@
}
/**
- * See {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int)}
+ * Send a management frame on the specified interface at the specified rate. Useful for probing
+ * the link with arbitrary frames.
+ *
+ * @param ifaceName The interface on which to send the frame.
+ * @param frame The raw byte array of the management frame to tramit.
+ * @param mcs The MCS (modulation and coding scheme), i.e. rate, at which to transmit the
+ * frame. Specified per IEEE 802.11.
+ * @param executor The Executor on which to execute the callbacks.
+ * @param callback A {@link SendMgmtFrameCallback} callback for results of the operation.
*/
- public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame,
- @NonNull SendMgmtFrameCallback callback, int mcs) {
+ public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame, int mcs,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull SendMgmtFrameCallback callback) {
- if (callback == null) {
+ if (callback == null || executor == null) {
Log.e(TAG, "callback cannot be null!");
return;
}
if (frame == null) {
Log.e(TAG, "frame cannot be null!");
- callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN);
+ executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN));
return;
}
@@ -946,17 +1128,17 @@
IClientInterface clientInterface = getClientInterface(ifaceName);
if (clientInterface == null) {
Log.e(TAG, "No valid wificond client interface handler");
- callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN);
+ executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN));
return;
}
if (!mSendMgmtFrameInProgress.compareAndSet(false, true)) {
Log.e(TAG, "An existing management frame transmission is in progress!");
- callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED);
+ executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED));
return;
}
- SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(callback);
+ SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(executor, callback);
try {
clientInterface.SendMgmtFrame(frame, sendMgmtFrameEvent, mcs);
} catch (RemoteException e) {
diff --git a/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java b/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java
index 775acc7..9439c79 100644
--- a/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java
+++ b/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java
@@ -30,7 +30,7 @@
import java.util.HashMap;
/**
- * Unit tests for {@link android.net.wifi.wificond.PnoSettingsResult}.
+ * Unit tests for {@link android.net.wifi.wificond.PnoSettings}.
*/
@SmallTest
public class PnoSettingsTest {
@@ -52,14 +52,14 @@
@Before
public void setUp() {
mPnoNetwork1 = new PnoNetwork();
- mPnoNetwork1.ssid = TEST_SSID_1;
- mPnoNetwork1.isHidden = true;
- mPnoNetwork1.frequencies = TEST_FREQUENCIES_1;
+ mPnoNetwork1.setSsid(TEST_SSID_1);
+ mPnoNetwork1.setHidden(true);
+ mPnoNetwork1.setFrequenciesMhz(TEST_FREQUENCIES_1);
mPnoNetwork2 = new PnoNetwork();
- mPnoNetwork2.ssid = TEST_SSID_2;
- mPnoNetwork2.isHidden = false;
- mPnoNetwork2.frequencies = TEST_FREQUENCIES_2;
+ mPnoNetwork2.setSsid(TEST_SSID_2);
+ mPnoNetwork2.setHidden(false);
+ mPnoNetwork2.setFrequenciesMhz(TEST_FREQUENCIES_2);
}
/**
@@ -69,10 +69,10 @@
@Test
public void canSerializeAndDeserialize() {
PnoSettings pnoSettings = new PnoSettings();
- pnoSettings.intervalMs = TEST_INTERVAL_MS;
- pnoSettings.min2gRssi = TEST_MIN_2G_RSSI;
- pnoSettings.min5gRssi = TEST_MIN_5G_RSSI;
- pnoSettings.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2));
+ pnoSettings.setIntervalMillis(TEST_INTERVAL_MS);
+ pnoSettings.setMin2gRssiDbm(TEST_MIN_2G_RSSI);
+ pnoSettings.setMin5gRssiDbm(TEST_MIN_5G_RSSI);
+ pnoSettings.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)));
Parcel parcel = Parcel.obtain();
pnoSettings.writeToParcel(parcel, 0);
@@ -90,16 +90,16 @@
@Test
public void testAsHashMapKey() {
PnoSettings pnoSettings1 = new PnoSettings();
- pnoSettings1.intervalMs = TEST_INTERVAL_MS;
- pnoSettings1.min2gRssi = TEST_MIN_2G_RSSI;
- pnoSettings1.min5gRssi = TEST_MIN_5G_RSSI;
- pnoSettings1.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2));
+ pnoSettings1.setIntervalMillis(TEST_INTERVAL_MS);
+ pnoSettings1.setMin2gRssiDbm(TEST_MIN_2G_RSSI);
+ pnoSettings1.setMin5gRssiDbm(TEST_MIN_5G_RSSI);
+ pnoSettings1.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)));
PnoSettings pnoSettings2 = new PnoSettings();
- pnoSettings2.intervalMs = TEST_INTERVAL_MS;
- pnoSettings2.min2gRssi = TEST_MIN_2G_RSSI;
- pnoSettings2.min5gRssi = TEST_MIN_5G_RSSI;
- pnoSettings2.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2));
+ pnoSettings2.setIntervalMillis(TEST_INTERVAL_MS);
+ pnoSettings2.setMin2gRssiDbm(TEST_MIN_2G_RSSI);
+ pnoSettings2.setMin5gRssiDbm(TEST_MIN_5G_RSSI);
+ pnoSettings2.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)));
assertEquals(pnoSettings1, pnoSettings2);
assertEquals(pnoSettings1.hashCode(), pnoSettings2.hashCode());
diff --git a/wifi/tests/src/android/net/wifi/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java
similarity index 89%
rename from wifi/tests/src/android/net/wifi/WifiCondManagerTest.java
rename to wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java
index 48a9afa..68e5336 100644
--- a/wifi/tests/src/android/net/wifi/WifiCondManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.wifi;
+package android.net.wifi.wificond;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -38,13 +38,18 @@
import android.app.AlarmManager;
import android.app.test.TestAlarmManager;
import android.content.Context;
+import android.net.wifi.IApInterface;
+import android.net.wifi.IApInterfaceEventCallback;
+import android.net.wifi.IClientInterface;
+import android.net.wifi.IPnoScanEvent;
+import android.net.wifi.IScanEvent;
+import android.net.wifi.ISendMgmtFrameEvent;
+import android.net.wifi.IWifiScannerImpl;
+import android.net.wifi.IWificond;
+import android.net.wifi.SoftApInfo;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiScanner;
import android.net.wifi.util.HexEncoding;
-import android.net.wifi.wificond.ChannelSettings;
-import android.net.wifi.wificond.HiddenNetwork;
-import android.net.wifi.wificond.NativeWifiClient;
-import android.net.wifi.wificond.PnoNetwork;
-import android.net.wifi.wificond.PnoSettings;
-import android.net.wifi.wificond.SingleScanSettings;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
@@ -67,7 +72,6 @@
import java.nio.charset.CharsetEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -88,7 +92,7 @@
@Mock
private IApInterface mApInterface;
@Mock
- private WifiCondManager.SoftApListener mSoftApListener;
+ private WifiCondManager.SoftApCallback mSoftApListener;
@Mock
private WifiCondManager.SendMgmtFrameCallback mSendMgmtFrameCallback;
@Mock
@@ -122,6 +126,7 @@
private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\"";
private static final int[] TEST_FREQUENCIES_1 = {};
private static final int[] TEST_FREQUENCIES_2 = {2500, 5124};
+ private static final byte[] TEST_RAW_MAC_BYTES = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
private static final List<byte[]> SCAN_HIDDEN_NETWORK_SSID_LIST =
new ArrayList<byte[]>() {{
@@ -131,22 +136,23 @@
LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2)));
}};
- private static final PnoSettings TEST_PNO_SETTINGS =
- new PnoSettings() {{
- intervalMs = 6000;
- pnoNetworks = new ArrayList<>();
- PnoNetwork network = new PnoNetwork();
- network.ssid = LocalNativeUtil.byteArrayFromArrayList(
- LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1));
- network.isHidden = true;
- network.frequencies = TEST_FREQUENCIES_1;
- pnoNetworks.add(network);
- network.ssid = LocalNativeUtil.byteArrayFromArrayList(
- LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2));
- network.isHidden = false;
- network.frequencies = TEST_FREQUENCIES_2;
- pnoNetworks.add(network);
- }};
+ private static final PnoSettings TEST_PNO_SETTINGS = new PnoSettings();
+ static {
+ TEST_PNO_SETTINGS.setIntervalMillis(6000);
+ List<PnoNetwork> initPnoNetworks = new ArrayList<>();
+ PnoNetwork network = new PnoNetwork();
+ network.setSsid(LocalNativeUtil.byteArrayFromArrayList(
+ LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1)));
+ network.setHidden(true);
+ network.setFrequenciesMhz(TEST_FREQUENCIES_1);
+ initPnoNetworks.add(network);
+ network.setSsid(LocalNativeUtil.byteArrayFromArrayList(
+ LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2)));
+ network.setHidden(false);
+ network.setFrequenciesMhz(TEST_FREQUENCIES_2);
+ initPnoNetworks.add(network);
+ TEST_PNO_SETTINGS.setPnoNetworks(initPnoNetworks);
+ }
private static final int TEST_MCS_RATE = 5;
private static final int TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS = 100;
@@ -180,8 +186,9 @@
when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl);
when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME);
mWificondControl = new WifiCondManager(mContext, mWificond);
- assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME,
- mNormalScanCallback, mPnoScanCallback));
+ assertEquals(true,
+ mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run,
+ mNormalScanCallback, mPnoScanCallback));
}
/**
@@ -264,7 +271,7 @@
assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME));
verify(mClientInterface, never()).signalPoll();
- assertFalse(mWificondControl.scan(
+ assertFalse(mWificondControl.startScan(
TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY,
SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST));
verify(mWifiScannerImpl, never()).scan(any());
@@ -348,8 +355,8 @@
public void testTeardownSoftApInterfaceClearsHandles() throws Exception {
testTeardownSoftApInterface();
- assertFalse(mWificondControl.registerApListener(
- TEST_INTERFACE_NAME, mSoftApListener));
+ assertFalse(mWificondControl.registerApCallback(
+ TEST_INTERFACE_NAME, Runnable::run, mSoftApListener));
verify(mApInterface, never()).registerCallback(any());
}
@@ -417,8 +424,8 @@
public void testSignalPoll() throws Exception {
when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
- mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, mNormalScanCallback,
- mPnoScanCallback);
+ mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run,
+ mNormalScanCallback, mPnoScanCallback);
mWificondControl.signalPoll(TEST_INTERFACE_NAME);
verify(mClientInterface).signalPoll();
}
@@ -432,7 +439,7 @@
// Configure client interface.
assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME,
- mNormalScanCallback, mPnoScanCallback));
+ Runnable::run, mNormalScanCallback, mPnoScanCallback));
// Tear down interfaces.
assertTrue(mWificondControl.tearDownInterfaces());
@@ -448,8 +455,8 @@
public void testGetTxPacketCounters() throws Exception {
when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
- mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, mNormalScanCallback,
- mPnoScanCallback);
+ mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run,
+ mNormalScanCallback, mPnoScanCallback);
mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME);
verify(mClientInterface).getPacketCounters();
}
@@ -464,7 +471,7 @@
// Configure client interface.
assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME,
- mNormalScanCallback, mPnoScanCallback));
+ Runnable::run, mNormalScanCallback, mPnoScanCallback));
// Tear down interfaces.
assertTrue(mWificondControl.tearDownInterfaces());
@@ -483,7 +490,7 @@
// Configure client interface.
assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME,
- mNormalScanCallback, mPnoScanCallback));
+ Runnable::run, mNormalScanCallback, mPnoScanCallback));
// Tear down interfaces.
assertTrue(mWificondControl.tearDownInterfaces());
@@ -500,7 +507,7 @@
@Test
public void testScan() throws Exception {
when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true);
- assertTrue(mWificondControl.scan(
+ assertTrue(mWificondControl.startScan(
TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER,
SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST));
verify(mWifiScannerImpl).scan(argThat(new ScanMatcher(
@@ -520,7 +527,7 @@
assertEquals(hiddenSsidWithDup.get(0),
hiddenSsidWithDup.get(hiddenSsidWithDup.size() - 1));
// Pass the List with duplicate elements into scan()
- assertTrue(mWificondControl.scan(
+ assertTrue(mWificondControl.startScan(
TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER,
SCAN_FREQ_SET, hiddenSsidWithDup));
// But the argument passed down should have the duplicate removed.
@@ -535,7 +542,7 @@
@Test
public void testScanNullParameters() throws Exception {
when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true);
- assertTrue(mWificondControl.scan(
+ assertTrue(mWificondControl.startScan(
TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, null, null));
verify(mWifiScannerImpl).scan(argThat(new ScanMatcher(
IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null)));
@@ -547,7 +554,7 @@
@Test
public void testScanFailure() throws Exception {
when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false);
- assertFalse(mWificondControl.scan(
+ assertFalse(mWificondControl.startScan(
TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY,
SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST));
verify(mWifiScannerImpl).scan(any(SingleScanSettings.class));
@@ -558,7 +565,7 @@
*/
@Test
public void testScanFailureDueToInvalidType() throws Exception {
- assertFalse(mWificondControl.scan(
+ assertFalse(mWificondControl.startScan(
TEST_INTERFACE_NAME, 100,
SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST));
verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class));
@@ -570,9 +577,10 @@
@Test
public void testStartPnoScan() throws Exception {
when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true);
- assertTrue(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS,
- mPnoScanRequestCallback));
- verify(mWifiScannerImpl).startPnoScan(argThat(new PnoScanMatcher(TEST_PNO_SETTINGS)));
+ assertTrue(
+ mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run,
+ mPnoScanRequestCallback));
+ verify(mWifiScannerImpl).startPnoScan(eq(TEST_PNO_SETTINGS));
verify(mPnoScanRequestCallback).onPnoRequestSucceeded();
}
@@ -665,8 +673,9 @@
public void testStartPnoScanForMetrics() throws Exception {
when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false);
- assertFalse(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS,
- mPnoScanRequestCallback));
+ assertFalse(
+ mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run,
+ mPnoScanRequestCallback));
verify(mPnoScanRequestCallback).onPnoRequestFailed();
}
@@ -695,11 +704,11 @@
final ArgumentCaptor<IApInterfaceEventCallback> apInterfaceCallbackCaptor =
ArgumentCaptor.forClass(IApInterfaceEventCallback.class);
- assertTrue(mWificondControl.registerApListener(
- TEST_INTERFACE_NAME, mSoftApListener));
+ assertTrue(mWificondControl.registerApCallback(
+ TEST_INTERFACE_NAME, Runnable::run, mSoftApListener));
verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture());
- final NativeWifiClient testClient = new NativeWifiClient();
+ final NativeWifiClient testClient = new NativeWifiClient(TEST_RAW_MAC_BYTES);
apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClient, true);
verify(mSoftApListener).onConnectedClientsChanged(eq(testClient), eq(true));
@@ -707,7 +716,8 @@
int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20;
apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency,
channelBandwidth);
- verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), eq(channelBandwidth));
+ verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency),
+ eq(SoftApInfo.CHANNEL_WIDTH_20MHZ));
}
/**
@@ -739,7 +749,7 @@
verify(deathHandler).run();
// The handles should be cleared after death.
- assertNull(mWificondControl.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ));
+ assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).length);
verify(mWificond, never()).getAvailable5gNonDFSChannels();
}
@@ -748,7 +758,8 @@
*/
@Test
public void testSendMgmtFrameNullCallback() throws Exception {
- mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, null, TEST_MCS_RATE);
+ mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
+ Runnable::run, null);
verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt());
}
@@ -758,8 +769,8 @@
*/
@Test
public void testSendMgmtFrameNullFrame() throws Exception {
- mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null,
- mSendMgmtFrameCallback, TEST_MCS_RATE);
+ mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null, TEST_MCS_RATE, Runnable::run,
+ mSendMgmtFrameCallback);
verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt());
verify(mSendMgmtFrameCallback).onFailure(anyInt());
@@ -770,8 +781,8 @@
*/
@Test
public void testSendMgmtFrameInvalidInterfaceName() throws Exception {
- mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME,
- mSendMgmtFrameCallback, TEST_MCS_RATE);
+ mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
+ Runnable::run, mSendMgmtFrameCallback);
verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt());
verify(mSendMgmtFrameCallback).onFailure(anyInt());
@@ -787,13 +798,15 @@
WifiCondManager.SendMgmtFrameCallback cb2 = mock(
WifiCondManager.SendMgmtFrameCallback.class);
- mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb1, TEST_MCS_RATE);
+ mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
+ Runnable::run, cb1);
verify(cb1, never()).onFailure(anyInt());
verify(mClientInterface, times(1))
.SendMgmtFrame(AdditionalMatchers.aryEq(TEST_PROBE_FRAME),
any(), eq(TEST_MCS_RATE));
- mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb2, TEST_MCS_RATE);
+ mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
+ Runnable::run, cb2);
verify(cb2).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED);
// verify SendMgmtFrame() still was only called once i.e. not called again
verify(mClientInterface, times(1))
@@ -820,8 +833,8 @@
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
alarmListenerCaptor.capture(), handlerCaptor.capture());
- mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME,
- cb, TEST_MCS_RATE);
+ mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
+ Runnable::run, cb);
mLooper.dispatchAll();
verify(cb).onFailure(anyInt());
@@ -854,7 +867,8 @@
final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
alarmListenerCaptor.capture(), handlerCaptor.capture());
- mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE);
+ mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
+ Runnable::run, cb);
sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS);
mLooper.dispatchAll();
@@ -887,7 +901,8 @@
final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
alarmListenerCaptor.capture(), handlerCaptor.capture());
- mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE);
+ mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
+ Runnable::run, cb);
sendMgmtFrameEventCaptor.getValue().OnFailure(
WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN);
@@ -921,7 +936,8 @@
final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
alarmListenerCaptor.capture(), handlerCaptor.capture());
- mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE);
+ mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
+ Runnable::run, cb);
handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm());
mLooper.dispatchAll();
@@ -987,8 +1003,8 @@
final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
alarmListenerCaptor.capture(), handlerCaptor.capture());
- mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME,
- mSendMgmtFrameCallback, TEST_MCS_RATE);
+ mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
+ Runnable::run, mSendMgmtFrameCallback);
// AlarmManager should post the onAlarm() callback onto the handler, but since we are
// triggering onAlarm() ourselves during the test, manually post onto handler
@@ -1015,8 +1031,8 @@
final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(),
alarmListenerCaptor.capture(), handlerCaptor.capture());
- mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME,
- mSendMgmtFrameCallback, TEST_MCS_RATE);
+ mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE,
+ Runnable::run, mSendMgmtFrameCallback);
// AlarmManager should post the onAlarm() callback onto the handler, but since we are
// triggering onAlarm() ourselves during the test, manually post onto handler
@@ -1086,56 +1102,6 @@
}
}
- // Create a ArgumentMatcher which captures a PnoSettings parameter and checks if it
- // matches the WifiNative.PnoSettings;
- private class PnoScanMatcher implements ArgumentMatcher<PnoSettings> {
- private final PnoSettings mExpectedPnoSettings;
-
- PnoScanMatcher(PnoSettings expectedPnoSettings) {
- this.mExpectedPnoSettings = expectedPnoSettings;
- }
-
- @Override
- public boolean matches(PnoSettings settings) {
- if (mExpectedPnoSettings == null) {
- return false;
- }
- if (settings.intervalMs != mExpectedPnoSettings.intervalMs
- || settings.min2gRssi != mExpectedPnoSettings.min2gRssi
- || settings.min5gRssi != mExpectedPnoSettings.min5gRssi
- || settings.min6gRssi != mExpectedPnoSettings.min6gRssi) {
- return false;
- }
- if (settings.pnoNetworks == null || mExpectedPnoSettings.pnoNetworks == null) {
- return false;
- }
- if (settings.pnoNetworks.size() != mExpectedPnoSettings.pnoNetworks.size()) {
- return false;
- }
-
- for (int i = 0; i < settings.pnoNetworks.size(); i++) {
- if (!Arrays.equals(settings.pnoNetworks.get(i).ssid,
- mExpectedPnoSettings.pnoNetworks.get(i).ssid)) {
- return false;
- }
- if (settings.pnoNetworks.get(i).isHidden != mExpectedPnoSettings.pnoNetworks.get(
- i).isHidden) {
- return false;
- }
- if (!Arrays.equals(settings.pnoNetworks.get(i).frequencies,
- mExpectedPnoSettings.pnoNetworks.get(i).frequencies)) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public String toString() {
- return "PnoScanMatcher{" + "mExpectedPnoSettings=" + mExpectedPnoSettings + '}';
- }
- }
-
private static class LocalNativeUtil {
private static final int SSID_BYTES_MAX_LEN = 32;