Merge "SoundPool: Fix lifetime of SoundPool native object" into tm-dev
diff --git a/Android.bp b/Android.bp
index 149b223..cd110de 100644
--- a/Android.bp
+++ b/Android.bp
@@ -272,8 +272,6 @@
include_dirs: [
"frameworks/av/aidl",
"frameworks/native/libs/permission/aidl",
- // TODO: remove when moved to the below package
- "frameworks/base/packages/ConnectivityT/framework-t/aidl-export",
"packages/modules/Bluetooth/framework/aidl-export",
"packages/modules/Connectivity/framework/aidl-export",
"packages/modules/Media/apex/aidl/stable",
@@ -531,8 +529,6 @@
include_dirs: [
"frameworks/av/aidl",
"frameworks/native/libs/permission/aidl",
- // TODO: remove when moved to the below package
- "frameworks/base/packages/ConnectivityT/framework-t/aidl-export",
"packages/modules/Bluetooth/framework/aidl-export",
"packages/modules/Connectivity/framework/aidl-export",
"packages/modules/Media/apex/aidl/stable",
diff --git a/apct-tests/perftests/blobstore/Android.bp b/apct-tests/perftests/blobstore/Android.bp
index 25c42507..9064b44 100644
--- a/apct-tests/perftests/blobstore/Android.bp
+++ b/apct-tests/perftests/blobstore/Android.bp
@@ -22,17 +22,18 @@
}
android_test {
- name: "BlobStorePerfTests",
- srcs: ["src/**/*.java"],
- static_libs: [
- "BlobStoreTestUtils",
- "androidx.test.rules",
- "androidx.annotation_annotation",
- "apct-perftests-utils",
- "ub-uiautomator",
- "collector-device-lib-platform",
- ],
- platform_apis: true,
- test_suites: ["device-tests"],
- certificate: "platform",
+ name: "BlobStorePerfTests",
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "BlobStoreTestUtils",
+ "androidx.test.rules",
+ "androidx.annotation_annotation",
+ "apct-perftests-utils",
+ "ub-uiautomator",
+ "collector-device-lib-platform",
+ "androidx.benchmark_benchmark-macro",
+ ],
+ platform_apis: true,
+ test_suites: ["device-tests"],
+ certificate: "platform",
}
diff --git a/apct-tests/perftests/blobstore/src/com/android/perftests/blob/BlobStorePerfTests.java b/apct-tests/perftests/blobstore/src/com/android/perftests/blob/BlobStorePerfTests.java
index faf61a7..665e986 100644
--- a/apct-tests/perftests/blobstore/src/com/android/perftests/blob/BlobStorePerfTests.java
+++ b/apct-tests/perftests/blobstore/src/com/android/perftests/blob/BlobStorePerfTests.java
@@ -15,15 +15,20 @@
*/
package com.android.perftests.blob;
+import static com.android.utils.blob.Utils.acquireLease;
+
import android.app.blob.BlobHandle;
import android.app.blob.BlobStoreManager;
import android.content.Context;
+import android.os.ParcelFileDescriptor;
import android.perftests.utils.ManualBenchmarkState;
import android.perftests.utils.PerfManualStatusReporter;
import android.perftests.utils.TraceMarkParser;
import android.perftests.utils.TraceMarkParser.TraceMarkSlice;
import android.support.test.uiautomator.UiDevice;
+import android.util.DataUnit;
+import androidx.benchmark.macro.MacrobenchmarkScope;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -36,12 +41,16 @@
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.List;
+import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@@ -53,6 +62,8 @@
// From f/b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
private static final String ATRACE_COMPUTE_DIGEST_PREFIX = "computeBlobDigest-";
+ public static final int BUFFER_SIZE_BYTES = 16 * 1024;
+
private Context mContext;
private BlobStoreManager mBlobStoreManager;
private AtraceUtils mAtraceUtils;
@@ -85,6 +96,8 @@
@After
public void tearDown() {
+ mContext.getFilesDir().delete();
+ runShellCommand("cmd package clear " + mContext.getPackageName());
runShellCommand("cmd blob_store idle-maintenance");
}
@@ -109,6 +122,110 @@
}
}
+ @Test
+ public void testDirectReads() throws Exception {
+ final File file = new File(mContext.getDataDir(), "test_read_file");
+ final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb);
+ try (FileOutputStream outputStream = new FileOutputStream(file)) {
+ writeData(outputStream, sizeBytes);
+ }
+
+ long durationNs = 0;
+ while (mState.keepRunning(durationNs)) {
+ dropCache();
+ try (FileInputStream inputStream = new FileInputStream(file)) {
+ final long startTimeNs = System.nanoTime();
+ readData(inputStream, sizeBytes);
+ durationNs = System.nanoTime() - startTimeNs;
+ }
+ }
+ }
+
+ @Test
+ public void testBlobStoreReads() throws Exception {
+ final FakeBlobData blobData = prepareDataBlob(fileSizeInMb);
+ commitBlob(blobData);
+ acquireLease(mContext, blobData.getBlobHandle(), "Test Desc");
+ final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb);
+
+ long durationNs = 0;
+ while (mState.keepRunning(durationNs)) {
+ dropCache();
+ try (FileInputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(
+ mBlobStoreManager.openBlob(blobData.getBlobHandle()))) {
+ final long startTimeNs = System.nanoTime();
+ readData(inputStream, sizeBytes);
+ durationNs = System.nanoTime() - startTimeNs;
+ }
+ }
+
+ deleteBlob(blobData.getBlobHandle());
+ }
+
+ @Test
+ public void testDirectWrites() throws Exception {
+ final File file = new File(mContext.getDataDir(), "test_write_file");
+ final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb);
+
+ long durationNs = 0;
+ while (mState.keepRunning(durationNs)) {
+ file.delete();
+ dropCache();
+ try (FileOutputStream outputStream = new FileOutputStream(file)) {
+ final long startTimeNs = System.nanoTime();
+ writeData(outputStream, sizeBytes);
+ durationNs = System.nanoTime() - startTimeNs;
+ }
+ }
+ }
+
+ @Test
+ public void testBlobStoreWrites() throws Exception {
+ final FakeBlobData blobData = prepareDataBlob(fileSizeInMb);
+ final long sizeBytes = DataUnit.MEBIBYTES.toBytes(fileSizeInMb);
+
+ long durationNs = 0;
+ while (mState.keepRunning(durationNs)) {
+ final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
+ try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+ dropCache();
+ try (FileOutputStream outputStream = new ParcelFileDescriptor
+ .AutoCloseOutputStream(session.openWrite(0, sizeBytes))) {
+ final long startTimeNs = System.nanoTime();
+ writeData(outputStream, sizeBytes);
+ durationNs = System.nanoTime() - startTimeNs;
+ }
+ }
+ mBlobStoreManager.abandonSession(sessionId);
+ }
+ }
+
+ private void readData(FileInputStream inputStream, long sizeBytes) throws Exception {
+ final byte[] buffer = new byte[BUFFER_SIZE_BYTES];
+ long bytesRead = 0;
+ while (bytesRead < sizeBytes) {
+ bytesRead += inputStream.read(buffer);
+ }
+ }
+
+ private void writeData(FileOutputStream outputStream, long sizeBytes) throws Exception {
+ final byte[] buffer = new byte[BUFFER_SIZE_BYTES];
+ long bytesWritten = 0;
+ final Random random = new Random(0);
+ while (bytesWritten < sizeBytes) {
+ random.nextBytes(buffer);
+ final int toWrite = (bytesWritten + buffer.length <= sizeBytes)
+ ? buffer.length : (int) (sizeBytes - bytesWritten);
+ outputStream.write(buffer, 0, toWrite);
+ bytesWritten += toWrite;
+ }
+ }
+
+ private void dropCache() {
+ final MacrobenchmarkScope scope = new MacrobenchmarkScope(mContext.getPackageName(), false);
+ scope.dropKernelPageCache();
+ }
+
private void collectDigestDurationsFromTrace(TraceMarkParser parser, List<Long> durations) {
mAtraceUtils.performDump(parser, (key, slices) -> {
for (TraceMarkSlice slice : slices) {
@@ -119,7 +236,7 @@
private FakeBlobData prepareDataBlob(int fileSizeInMb) throws Exception {
final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
- .setFileSize(fileSizeInMb * 1024 * 1024 /* bytes */)
+ .setFileSize(DataUnit.MEBIBYTES.toBytes(fileSizeInMb))
.build();
blobData.prepare();
return blobData;
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
index f822a18..c3fc4d1 100644
--- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
@@ -1,6 +1,7 @@
package com.android.server.usage;
import android.annotation.CurrentTimeMillisLong;
+import android.annotation.ElapsedRealtimeLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
@@ -150,6 +151,12 @@
boolean shouldObfuscateInstantApps);
/**
+ * Return the bucketing reason code of the given app.
+ */
+ int getAppStandbyBucketReason(@NonNull String packageName, @UserIdInt int userId,
+ @ElapsedRealtimeLong long elapsedRealtime);
+
+ /**
* Put the specified app in the
* {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED}
* bucket. If it has been used by the user recently, the restriction will delayed until an
@@ -245,4 +252,7 @@
*/
@Nullable
String getAppStandbyConstant(@NonNull String key);
+
+ /** Clears the last used timestamps data for the given {@code packageName}. */
+ void clearLastUsedTimestampsForTest(@NonNull String packageName, @UserIdInt int userId);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 528be3c..a09f39f 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -348,7 +348,8 @@
new SparseArray<>();
private AppStateTrackerImpl mAppStateTracker;
- private boolean mAppStandbyParole;
+ @VisibleForTesting
+ boolean mAppStandbyParole;
/**
* A container to keep rolling window history of previous times when an alarm was sent to
@@ -1891,6 +1892,9 @@
(AppStateTrackerImpl) LocalServices.getService(AppStateTracker.class);
mAppStateTracker.addListener(mForceAppStandbyListener);
+ final BatteryManager bm = getContext().getSystemService(BatteryManager.class);
+ mAppStandbyParole = bm.isCharging();
+
mClockReceiver.scheduleTimeTickEvent();
mClockReceiver.scheduleDateChangedEvent();
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index 405b12d..1b2cdb8 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -265,31 +265,22 @@
)
);
- /**
- * This array essentially stores the state of mActiveServices array.
- * The ith index stores the job present on the ith JobServiceContext.
- * We manipulate this array until we arrive at what jobs should be running on
- * what JobServiceContext.
- */
- JobStatus[] mRecycledAssignContextIdToJobMap = new JobStatus[MAX_JOB_CONTEXTS_COUNT];
+ private final ArraySet<ContextAssignment> mRecycledChanged = new ArraySet<>();
+ private final ArraySet<ContextAssignment> mRecycledIdle = new ArraySet<>();
+ private final ArraySet<ContextAssignment> mRecycledPreferredUidOnly = new ArraySet<>();
+ private final ArraySet<ContextAssignment> mRecycledStoppable = new ArraySet<>();
- boolean[] mRecycledSlotChanged = new boolean[MAX_JOB_CONTEXTS_COUNT];
-
- int[] mRecycledPreferredUidForContext = new int[MAX_JOB_CONTEXTS_COUNT];
-
- int[] mRecycledWorkTypeForContext = new int[MAX_JOB_CONTEXTS_COUNT];
-
- String[] mRecycledPreemptReasonForContext = new String[MAX_JOB_CONTEXTS_COUNT];
-
- int[] mRecycledPreemptReasonCodeForContext = new int[MAX_JOB_CONTEXTS_COUNT];
-
- String[] mRecycledShouldStopJobReason = new String[MAX_JOB_CONTEXTS_COUNT];
+ private final Pools.Pool<ContextAssignment> mContextAssignmentPool =
+ new Pools.SimplePool<>(MAX_JOB_CONTEXTS_COUNT);
/**
- * Set of JobServiceContexts that we use to run jobs.
+ * Set of JobServiceContexts that are actively running jobs.
*/
final List<JobServiceContext> mActiveServices = new ArrayList<>();
+ /** Set of JobServiceContexts that aren't currently running any jobs. */
+ final ArraySet<JobServiceContext> mIdleContexts = new ArraySet<>();
+
private final ArraySet<JobStatus> mRunningJobs = new ArraySet<>();
private final WorkCountTracker mWorkCountTracker = new WorkCountTracker();
@@ -378,7 +369,7 @@
final IBatteryStats batteryStats = IBatteryStats.Stub.asInterface(
ServiceManager.getService(BatteryStats.SERVICE_NAME));
for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
- mActiveServices.add(
+ mIdleContexts.add(
new JobServiceContext(mService, this, batteryStats,
mService.mJobPackageTracker, mContext.getMainLooper()));
}
@@ -581,13 +572,10 @@
final List<JobServiceContext> activeServices = mActiveServices;
// To avoid GC churn, we recycle the arrays.
- JobStatus[] contextIdToJobMap = mRecycledAssignContextIdToJobMap;
- boolean[] slotChanged = mRecycledSlotChanged;
- int[] preferredUidForContext = mRecycledPreferredUidForContext;
- int[] workTypeForContext = mRecycledWorkTypeForContext;
- String[] preemptReasonForContext = mRecycledPreemptReasonForContext;
- int[] preemptReasonCodeForContext = mRecycledPreemptReasonCodeForContext;
- String[] shouldStopJobReason = mRecycledShouldStopJobReason;
+ final ArraySet<ContextAssignment> changed = mRecycledChanged;
+ final ArraySet<ContextAssignment> idle = mRecycledIdle;
+ final ArraySet<ContextAssignment> preferredUidOnly = mRecycledPreferredUidOnly;
+ final ArraySet<ContextAssignment> stoppable = mRecycledStoppable;
updateCounterConfigLocked();
// Reset everything since we'll re-evaluate the current state.
@@ -598,23 +586,50 @@
// shouldStopRunningJobLocked().
updateNonRunningPrioritiesLocked(pendingJobQueue, true);
- for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
- final JobServiceContext js = activeServices.get(i);
- final JobStatus status = js.getRunningJobLocked();
+ final int numRunningJobs = activeServices.size();
+ for (int i = 0; i < numRunningJobs; ++i) {
+ final JobServiceContext jsc = activeServices.get(i);
+ final JobStatus js = jsc.getRunningJobLocked();
- if ((contextIdToJobMap[i] = status) != null) {
- mWorkCountTracker.incrementRunningJobCount(js.getRunningJobWorkType());
- workTypeForContext[i] = js.getRunningJobWorkType();
+ ContextAssignment assignment = mContextAssignmentPool.acquire();
+ if (assignment == null) {
+ assignment = new ContextAssignment();
}
- slotChanged[i] = false;
- preferredUidForContext[i] = js.getPreferredUid();
- preemptReasonForContext[i] = null;
- preemptReasonCodeForContext[i] = JobParameters.STOP_REASON_UNDEFINED;
- shouldStopJobReason[i] = shouldStopRunningJobLocked(js);
+ assignment.context = jsc;
+
+ if (js != null) {
+ mWorkCountTracker.incrementRunningJobCount(jsc.getRunningJobWorkType());
+ assignment.workType = jsc.getRunningJobWorkType();
+ }
+
+ assignment.preferredUid = jsc.getPreferredUid();
+ if ((assignment.shouldStopJobReason = shouldStopRunningJobLocked(jsc)) != null) {
+ stoppable.add(assignment);
+ } else {
+ preferredUidOnly.add(assignment);
+ }
+ }
+ for (int i = numRunningJobs; i < MAX_JOB_CONTEXTS_COUNT; ++i) {
+ final JobServiceContext jsc;
+ final int numIdleContexts = mIdleContexts.size();
+ if (numIdleContexts > 0) {
+ jsc = mIdleContexts.removeAt(numIdleContexts - 1);
+ } else {
+ Slog.wtf(TAG, "Had fewer than " + MAX_JOB_CONTEXTS_COUNT + " in existence");
+ jsc = createNewJobServiceContext();
+ }
+
+ ContextAssignment assignment = mContextAssignmentPool.acquire();
+ if (assignment == null) {
+ assignment = new ContextAssignment();
+ }
+
+ assignment.context = jsc;
+ idle.add(assignment);
}
if (DEBUG) {
- Slog.d(TAG, printContextIdToJobMap(contextIdToJobMap, "running jobs initial"));
+ Slog.d(TAG, printAssignments("running jobs initial", stoppable, preferredUidOnly));
}
mWorkCountTracker.onCountDone();
@@ -626,125 +641,152 @@
continue;
}
- // Find an available slot for nextPending. The context should be available OR
- // it should have the lowest bias among all running jobs
- // (sharing the same Uid as nextPending)
- int minBiasForPreemption = Integer.MAX_VALUE;
- int selectedContextId = -1;
- int allWorkTypes = getJobWorkTypes(nextPending);
- int workType = mWorkCountTracker.canJobStart(allWorkTypes);
- boolean startingJob = false;
- int preemptReasonCode = JobParameters.STOP_REASON_UNDEFINED;
- String preemptReason = null;
+ // Find an available slot for nextPending. The context should be one of the following:
+ // 1. Unused
+ // 2. Its job should have used up its minimum execution guarantee so it
+ // 3. Its job should have the lowest bias among all running jobs (sharing the same UID
+ // as nextPending)
+ ContextAssignment selectedContext = null;
+ final int allWorkTypes = getJobWorkTypes(nextPending);
final boolean pkgConcurrencyOkay = !isPkgConcurrencyLimitedLocked(nextPending);
- // TODO(141645789): rewrite this to look at empty contexts first so we don't
- // unnecessarily preempt
- for (int j = 0; j < MAX_JOB_CONTEXTS_COUNT; j++) {
- JobStatus job = contextIdToJobMap[j];
- int preferredUid = preferredUidForContext[j];
- if (job == null) {
- final boolean preferredUidOkay = (preferredUid == nextPending.getUid())
- || (preferredUid == JobServiceContext.NO_PREFERRED_UID);
-
- if (preferredUidOkay && pkgConcurrencyOkay && workType != WORK_TYPE_NONE) {
- // This slot is free, and we haven't yet hit the limit on
- // concurrent jobs... we can just throw the job in to here.
- selectedContextId = j;
- startingJob = true;
- break;
- }
- // No job on this context, but nextPending can't run here because
- // the context has a preferred Uid or we have reached the limit on
- // concurrent jobs.
- continue;
+ boolean startingJob = false;
+ if (idle.size() > 0) {
+ final int idx = idle.size() - 1;
+ final ContextAssignment assignment = idle.valueAt(idx);
+ final boolean preferredUidOkay = (assignment.preferredUid == nextPending.getUid())
+ || (assignment.preferredUid == JobServiceContext.NO_PREFERRED_UID);
+ int workType = mWorkCountTracker.canJobStart(allWorkTypes);
+ if (preferredUidOkay && pkgConcurrencyOkay && workType != WORK_TYPE_NONE) {
+ // This slot is free, and we haven't yet hit the limit on
+ // concurrent jobs... we can just throw the job in to here.
+ selectedContext = assignment;
+ startingJob = true;
+ idle.removeAt(idx);
+ assignment.newJob = nextPending;
+ assignment.newWorkType = workType;
}
- if (job.getUid() != nextPending.getUid()) {
+ }
+ if (selectedContext == null) {
+ for (int s = stoppable.size() - 1; s >= 0; --s) {
+ ContextAssignment assignment = stoppable.valueAt(s);
+ JobStatus runningJob = assignment.context.getRunningJobLocked();
// Maybe stop the job if it has had its day in the sun. Don't let a different
// app preempt jobs started for TOP apps though.
- final String reason = shouldStopJobReason[j];
- if (job.lastEvaluatedBias < JobInfo.BIAS_TOP_APP
- && reason != null && mWorkCountTracker.canJobStart(allWorkTypes,
- activeServices.get(j).getRunningJobWorkType()) != WORK_TYPE_NONE) {
- // Right now, the way the code is set up, we don't need to explicitly
- // assign the new job to this context since we'll reassign when the
- // preempted job finally stops.
- preemptReason = reason;
- preemptReasonCode = JobParameters.STOP_REASON_DEVICE_STATE;
+ if (runningJob.lastEvaluatedBias < JobInfo.BIAS_TOP_APP
+ && assignment.shouldStopJobReason != null) {
+ int replaceWorkType = mWorkCountTracker.canJobStart(allWorkTypes,
+ assignment.context.getRunningJobWorkType());
+ if (replaceWorkType != WORK_TYPE_NONE) {
+ // Right now, the way the code is set up, we don't need to explicitly
+ // assign the new job to this context since we'll reassign when the
+ // preempted job finally stops.
+ assignment.preemptReason = assignment.shouldStopJobReason;
+ assignment.preemptReasonCode = JobParameters.STOP_REASON_DEVICE_STATE;
+ selectedContext = assignment;
+ stoppable.removeAt(s);
+ assignment.newJob = nextPending;
+ assignment.newWorkType = replaceWorkType;
+ break;
+ }
}
- continue;
}
+ }
+ if (selectedContext == null) {
+ int lowestBiasSeen = Integer.MAX_VALUE;
+ for (int p = preferredUidOnly.size() - 1; p >= 0; --p) {
+ final ContextAssignment assignment = preferredUidOnly.valueAt(p);
+ final JobStatus runningJob = assignment.context.getRunningJobLocked();
+ if (runningJob.getUid() != nextPending.getUid()) {
+ continue;
+ }
+ final int jobBias = mService.evaluateJobBiasLocked(runningJob);
+ if (jobBias >= nextPending.lastEvaluatedBias) {
+ continue;
+ }
- final int jobBias = mService.evaluateJobBiasLocked(job);
- if (jobBias >= nextPending.lastEvaluatedBias) {
- continue;
+ if (selectedContext == null || lowestBiasSeen > jobBias) {
+ // Step down the preemption threshold - wind up replacing
+ // the lowest-bias running job
+ lowestBiasSeen = jobBias;
+ selectedContext = assignment;
+ assignment.preemptReason = "higher bias job found";
+ assignment.preemptReasonCode = JobParameters.STOP_REASON_PREEMPT;
+ // In this case, we're just going to preempt a low bias job, we're not
+ // actually starting a job, so don't set startingJob to true.
+ }
}
-
- if (minBiasForPreemption > jobBias) {
- // Step down the preemption threshold - wind up replacing
- // the lowest-bias running job
- minBiasForPreemption = jobBias;
- selectedContextId = j;
- preemptReason = "higher bias job found";
- preemptReasonCode = JobParameters.STOP_REASON_PREEMPT;
- // In this case, we're just going to preempt a low bias job, we're not
- // actually starting a job, so don't set startingJob.
+ if (selectedContext != null) {
+ selectedContext.newJob = nextPending;
+ preferredUidOnly.remove(selectedContext);
}
}
final PackageStats packageStats = getPkgStatsLocked(
nextPending.getSourceUserId(), nextPending.getSourcePackageName());
- if (selectedContextId != -1) {
- contextIdToJobMap[selectedContextId] = nextPending;
- slotChanged[selectedContextId] = true;
- preemptReasonCodeForContext[selectedContextId] = preemptReasonCode;
- preemptReasonForContext[selectedContextId] = preemptReason;
+ if (selectedContext != null) {
+ changed.add(selectedContext);
packageStats.adjustStagedCount(true, nextPending.shouldTreatAsExpeditedJob());
}
if (startingJob) {
// Increase the counters when we're going to start a job.
- workTypeForContext[selectedContextId] = workType;
- mWorkCountTracker.stageJob(workType, allWorkTypes);
+ mWorkCountTracker.stageJob(selectedContext.newWorkType, allWorkTypes);
mActivePkgStats.add(
nextPending.getSourceUserId(), nextPending.getSourcePackageName(),
packageStats);
}
}
if (DEBUG) {
- Slog.d(TAG, printContextIdToJobMap(contextIdToJobMap, "running jobs final"));
+ Slog.d(TAG, printAssignments("running jobs final",
+ stoppable, preferredUidOnly, changed));
Slog.d(TAG, "assignJobsToContexts: " + mWorkCountTracker.toString());
}
- for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
- boolean preservePreferredUid = false;
- if (slotChanged[i]) {
- JobStatus js = activeServices.get(i).getRunningJobLocked();
- if (js != null) {
- if (DEBUG) {
- Slog.d(TAG, "preempting job: "
- + activeServices.get(i).getRunningJobLocked());
- }
- // preferredUid will be set to uid of currently running job.
- activeServices.get(i).cancelExecutingJobLocked(
- preemptReasonCodeForContext[i],
- JobParameters.INTERNAL_STOP_REASON_PREEMPT, preemptReasonForContext[i]);
- // Only preserve the UID if we're preempting for the same UID. If we're stopping
- // the job because something is pending (eg. EJs), then we shouldn't preserve
- // the UID.
- preservePreferredUid =
- preemptReasonCodeForContext[i] == JobParameters.STOP_REASON_PREEMPT;
- } else {
- final JobStatus pendingJob = contextIdToJobMap[i];
- if (DEBUG) {
- Slog.d(TAG, "About to run job on context "
- + i + ", job: " + pendingJob);
- }
- startJobLocked(activeServices.get(i), pendingJob, workTypeForContext[i]);
+ for (int c = changed.size() - 1; c >= 0; --c) {
+ final ContextAssignment assignment = changed.valueAt(c);
+ final JobStatus js = assignment.context.getRunningJobLocked();
+ if (js != null) {
+ if (DEBUG) {
+ Slog.d(TAG, "preempting job: " + js);
}
+ // preferredUid will be set to uid of currently running job.
+ assignment.context.cancelExecutingJobLocked(
+ assignment.preemptReasonCode,
+ JobParameters.INTERNAL_STOP_REASON_PREEMPT, assignment.preemptReason);
+ } else {
+ final JobStatus pendingJob = assignment.newJob;
+ if (DEBUG) {
+ Slog.d(TAG, "About to run job on context "
+ + assignment.context.getId() + ", job: " + pendingJob);
+ }
+ startJobLocked(assignment.context, pendingJob, assignment.newWorkType);
}
- if (!preservePreferredUid) {
- activeServices.get(i).clearPreferredUid();
- }
+
+ assignment.clear();
+ mContextAssignmentPool.release(assignment);
}
+ for (int s = stoppable.size() - 1; s >= 0; --s) {
+ final ContextAssignment assignment = stoppable.valueAt(s);
+ // The preferred UID is set when we cancel with PREEMPT reason, but don't preserve the
+ // UID for any stoppable contexts since we want to open the context up to any/all apps.
+ assignment.context.clearPreferredUid();
+ assignment.clear();
+ mContextAssignmentPool.release(assignment);
+ }
+ for (int p = preferredUidOnly.size() - 1; p >= 0; --p) {
+ final ContextAssignment assignment = preferredUidOnly.valueAt(p);
+ assignment.clear();
+ mContextAssignmentPool.release(assignment);
+ }
+ for (int i = idle.size() - 1; i >= 0; --i) {
+ final ContextAssignment assignment = idle.valueAt(i);
+ mIdleContexts.add(assignment.context);
+ assignment.clear();
+ mContextAssignmentPool.release(assignment);
+ }
+ changed.clear();
+ idle.clear();
+ stoppable.clear();
+ preferredUidOnly.clear();
mWorkCountTracker.resetStagingCount();
mActivePkgStats.forEach(mPackageStatsStagingCountClearer);
noteConcurrency();
@@ -787,7 +829,7 @@
@GuardedBy("mLock")
private void stopLongRunningJobsLocked(@NonNull String debugReason) {
- for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; ++i) {
+ for (int i = 0; i < mActiveServices.size(); ++i) {
final JobServiceContext jsc = mActiveServices.get(i);
final JobStatus jobStatus = jsc.getRunningJobLocked();
@@ -931,6 +973,8 @@
}
} else {
mRunningJobs.add(jobStatus);
+ mActiveServices.add(worker);
+ mIdleContexts.remove(worker);
mWorkCountTracker.onJobStarted(workType);
packageStats.adjustRunningCount(true, jobStatus.shouldTreatAsExpeditedJob());
mActivePkgStats.add(
@@ -950,6 +994,8 @@
@WorkType final int workType) {
mWorkCountTracker.onJobFinished(workType);
mRunningJobs.remove(jobStatus);
+ mActiveServices.remove(worker);
+ mIdleContexts.add(worker);
final PackageStats packageStats =
mActivePkgStats.get(jobStatus.getSourceUserId(), jobStatus.getSourcePackageName());
if (packageStats == null) {
@@ -1093,7 +1139,7 @@
/**
* Returns {@code null} if the job can continue running and a non-null String if the job should
* be stopped. The non-null String details the reason for stopping the job. A job will generally
- * be stopped if there similar job types waiting to be run and stopping this job would allow
+ * be stopped if there are similar job types waiting to be run and stopping this job would allow
* another job to run, or if system state suggests the job should stop.
*/
@Nullable
@@ -1202,6 +1248,14 @@
return foundSome;
}
+ @NonNull
+ private JobServiceContext createNewJobServiceContext() {
+ return new JobServiceContext(mService, this,
+ IBatteryStats.Stub.asInterface(
+ ServiceManager.getService(BatteryStats.SERVICE_NAME)),
+ mService.mJobPackageTracker, mContext.getMainLooper());
+ }
+
@GuardedBy("mLock")
private String printPendingQueueLocked() {
StringBuilder s = new StringBuilder("Pending queue: ");
@@ -1218,13 +1272,26 @@
return s.toString();
}
- private static String printContextIdToJobMap(JobStatus[] map, String initial) {
- StringBuilder s = new StringBuilder(initial + ": ");
- for (int i=0; i<map.length; i++) {
- s.append("(")
- .append(map[i] == null? -1: map[i].getJobId())
- .append(map[i] == null? -1: map[i].getUid())
- .append(")" );
+ private static String printAssignments(String header, ArraySet<ContextAssignment>... list) {
+ final StringBuilder s = new StringBuilder(header + ": ");
+ for (int l = 0; l < list.length; ++l) {
+ ArraySet<ContextAssignment> assignments = list[l];
+ for (int c = 0; c < assignments.size(); ++c) {
+ final ContextAssignment assignment = assignments.valueAt(c);
+ final JobStatus job = assignment.newJob == null
+ ? assignment.context.getRunningJobLocked() : assignment.newJob;
+
+ if (l > 0 || c > 0) {
+ s.append(" ");
+ }
+ s.append("(").append(assignment.context.getId()).append("=");
+ if (job == null) {
+ s.append("nothing");
+ } else {
+ s.append(job.getJobId()).append("/").append(job.getUid());
+ }
+ s.append(")");
+ }
}
return s.toString();
}
@@ -1327,10 +1394,13 @@
}
@GuardedBy("mLock")
- void dumpActiveJobsLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate,
+ void dumpContextInfoLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate,
long nowElapsed, long nowUptime) {
pw.println("Active jobs:");
pw.increaseIndent();
+ if (mActiveServices.size() == 0) {
+ pw.println("N/A");
+ }
for (int i = 0; i < mActiveServices.size(); i++) {
JobServiceContext jsc = mActiveServices.get(i);
final JobStatus job = jsc.getRunningJobLocked();
@@ -1339,7 +1409,8 @@
continue;
}
- pw.print("Slot #"); pw.print(i); pw.print(": ");
+ pw.print("Slot #"); pw.print(i);
+ pw.print("(ID="); pw.print(jsc.getId()); pw.print("): ");
jsc.dumpLocked(pw, nowElapsed);
if (job != null) {
@@ -1361,6 +1432,19 @@
}
}
pw.decreaseIndent();
+
+ pw.println();
+ pw.print("Idle contexts (");
+ pw.print(mIdleContexts.size());
+ pw.println("):");
+ pw.increaseIndent();
+ for (int i = 0; i < mIdleContexts.size(); i++) {
+ JobServiceContext jsc = mIdleContexts.valueAt(i);
+
+ pw.print("ID="); pw.print(jsc.getId()); pw.print(": ");
+ jsc.dumpLocked(pw, nowElapsed);
+ }
+ pw.decreaseIndent();
}
public void dumpProtoLocked(ProtoOutputStream proto, long tag, long now, long nowRealtime) {
@@ -1989,4 +2073,26 @@
pw.println("}");
}
}
+
+ private static final class ContextAssignment {
+ public JobServiceContext context;
+ public int preferredUid = JobServiceContext.NO_PREFERRED_UID;
+ public int workType = WORK_TYPE_NONE;
+ public String preemptReason;
+ public int preemptReasonCode = JobParameters.STOP_REASON_UNDEFINED;
+ public String shouldStopJobReason;
+ public JobStatus newJob;
+ public int newWorkType = WORK_TYPE_NONE;
+
+ void clear() {
+ context = null;
+ preferredUid = JobServiceContext.NO_PREFERRED_UID;
+ workType = WORK_TYPE_NONE;
+ preemptReason = null;
+ preemptReasonCode = JobParameters.STOP_REASON_UNDEFINED;
+ shouldStopJobReason = null;
+ newJob = null;
+ newWorkType = WORK_TYPE_NONE;
+ }
+ }
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 2028be7..0b8162a 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -3770,7 +3770,7 @@
pw.decreaseIndent();
pw.println();
- mConcurrencyManager.dumpActiveJobsLocked(pw, predicate, nowElapsed, nowUptime);
+ mConcurrencyManager.dumpContextInfoLocked(pw, predicate, nowElapsed, nowUptime);
pw.println();
boolean recentPrinted = false;
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 00d1bff..54e0a4c 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -433,6 +433,10 @@
mPreferredUid = NO_PREFERRED_UID;
}
+ int getId() {
+ return hashCode();
+ }
+
long getExecutionStartTimeElapsed() {
return mExecutionStartTimeElapsed;
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/PendingJobQueue.java b/apex/jobscheduler/service/java/com/android/server/job/PendingJobQueue.java
index f91472b..daf1ee1 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/PendingJobQueue.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/PendingJobQueue.java
@@ -182,8 +182,10 @@
if (earliestQueue != null) {
final JobStatus job = earliestQueue.next();
// Change the front of the queue if we've pulled pullLimit jobs from the current head
+ // or we're dealing with test jobs
// or the current head has no more jobs to provide.
if (++mPullCount >= pullLimit
+ || (job != null && earliestQueue.peekNextOverrideState() != job.overrideState)
|| earliestQueue.peekNextTimestamp() == AppJobQueue.NO_NEXT_TIMESTAMP) {
mOrderedQueues.poll();
if (earliestQueue.peekNextTimestamp() != AppJobQueue.NO_NEXT_TIMESTAMP) {
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/ChargingModifier.java b/apex/jobscheduler/service/java/com/android/server/tare/ChargingModifier.java
index 712e13e..2b48d49 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/ChargingModifier.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/ChargingModifier.java
@@ -76,6 +76,8 @@
}
private final class ChargingTracker extends BroadcastReceiver {
+ private boolean mIsSetup = false;
+
/**
* Track whether we're "charging", where charging means that we're ready to commit to
* doing work.
@@ -83,6 +85,10 @@
private volatile boolean mCharging;
public void startTracking(@NonNull Context context) {
+ if (mIsSetup) {
+ return;
+ }
+
final IntentFilter filter = new IntentFilter();
filter.addAction(BatteryManager.ACTION_CHARGING);
filter.addAction(BatteryManager.ACTION_DISCHARGING);
@@ -91,10 +97,17 @@
// Initialise tracker state.
final BatteryManager batteryManager = context.getSystemService(BatteryManager.class);
mCharging = batteryManager.isCharging();
+
+ mIsSetup = true;
}
public void stopTracking(@NonNull Context context) {
+ if (!mIsSetup) {
+ return;
+ }
+
context.unregisterReceiver(this);
+ mIsSetup = false;
}
@Override
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java b/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java
index 8a64238..47ff307 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java
@@ -72,6 +72,7 @@
}
private final class DeviceIdleTracker extends BroadcastReceiver {
+ private boolean mIsSetup = false;
private volatile boolean mDeviceIdle;
private volatile boolean mDeviceLightIdle;
@@ -80,6 +81,10 @@
}
void startTracking(@NonNull Context context) {
+ if (mIsSetup) {
+ return;
+ }
+
IntentFilter filter = new IntentFilter();
filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
filter.addAction(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
@@ -88,10 +93,17 @@
// Initialise tracker state.
mDeviceIdle = mPowerManager.isDeviceIdleMode();
mDeviceLightIdle = mPowerManager.isLightDeviceIdleMode();
+
+ mIsSetup = true;
}
void stopTracking(@NonNull Context context) {
+ if (!mIsSetup) {
+ return;
+ }
+
context.unregisterReceiver(this);
+ mIsSetup = false;
}
@Override
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/PowerSaveModeModifier.java b/apex/jobscheduler/service/java/com/android/server/tare/PowerSaveModeModifier.java
index 4aaa9f4..542bfd1 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/PowerSaveModeModifier.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/PowerSaveModeModifier.java
@@ -72,6 +72,8 @@
// TODO: migrate to relying on PowerSaveState and ServiceType.TARE
private final class PowerSaveModeTracker extends BroadcastReceiver {
+ private boolean mIsSetup = false;
+
private final PowerManager mPowerManager;
private volatile boolean mPowerSaveModeEnabled;
@@ -80,16 +82,27 @@
}
public void startTracking(@NonNull Context context) {
+ if (mIsSetup) {
+ return;
+ }
+
final IntentFilter filter = new IntentFilter();
filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
context.registerReceiver(this, filter);
// Initialise tracker state.
mPowerSaveModeEnabled = mPowerManager.isPowerSaveMode();
+
+ mIsSetup = true;
}
public void stopTracking(@NonNull Context context) {
+ if (!mIsSetup) {
+ return;
+ }
+
context.unregisterReceiver(this);
+ mIsSetup = false;
}
@Override
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
index 2e3b377..80f3fea 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
@@ -623,7 +623,8 @@
* @param elapsedRealtime current time
* @param screenTimeThresholds Array of screen times, in ascending order, first one is 0
* @param elapsedTimeThresholds Array of elapsed time, in ascending order, first one is 0
- * @return The index whose values the app's used time exceeds (in both arrays)
+ * @return The index whose values the app's used time exceeds (in both arrays) or {@code -1} to
+ * indicate that the app has never been used.
*/
int getThresholdIndex(String packageName, int userId, long elapsedRealtime,
long[] screenTimeThresholds, long[] elapsedTimeThresholds) {
@@ -631,14 +632,13 @@
AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName,
elapsedRealtime, false);
// If we don't have any state for the app, assume never used
- if (appUsageHistory == null) return screenTimeThresholds.length - 1;
+ if (appUsageHistory == null || appUsageHistory.lastUsedElapsedTime < 0
+ || appUsageHistory.lastUsedScreenTime < 0) {
+ return -1;
+ }
- long screenOnDelta = appUsageHistory.lastUsedScreenTime >= 0
- ? getScreenOnTime(elapsedRealtime) - appUsageHistory.lastUsedScreenTime
- : Long.MAX_VALUE;
- long elapsedDelta = appUsageHistory.lastUsedElapsedTime >= 0
- ? getElapsedTime(elapsedRealtime) - appUsageHistory.lastUsedElapsedTime
- : Long.MAX_VALUE;
+ long screenOnDelta = getScreenOnTime(elapsedRealtime) - appUsageHistory.lastUsedScreenTime;
+ long elapsedDelta = getElapsedTime(elapsedRealtime) - appUsageHistory.lastUsedElapsedTime;
if (DEBUG) Slog.d(TAG, packageName
+ " lastUsedScreen=" + appUsageHistory.lastUsedScreenTime
@@ -686,6 +686,17 @@
Integer.toString(userId)), APP_IDLE_FILENAME);
}
+ void clearLastUsedTimestamps(String packageName, int userId) {
+ ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
+ AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName,
+ SystemClock.elapsedRealtime(), false /* create */);
+ if (appUsageHistory != null) {
+ appUsageHistory.lastUsedByUserElapsedTime = Integer.MIN_VALUE;
+ appUsageHistory.lastUsedElapsedTime = Integer.MIN_VALUE;
+ appUsageHistory.lastUsedScreenTime = Integer.MIN_VALUE;
+ }
+ }
+
/**
* Check if App Idle File exists on disk
* @param userId
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 5029130..b520102 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -898,11 +898,9 @@
}
}
- final long elapsedLastUsedByUserTimeDelta = app.lastUsedByUserElapsedTime >= 0
- ? elapsedTimeAdjusted - app.lastUsedByUserElapsedTime
- : Long.MAX_VALUE;
- if (app.lastRestrictAttemptElapsedTime > app.lastUsedByUserElapsedTime
- && elapsedLastUsedByUserTimeDelta
+ if (app.lastUsedByUserElapsedTime >= 0
+ && app.lastRestrictAttemptElapsedTime > app.lastUsedByUserElapsedTime
+ && elapsedTimeAdjusted - app.lastUsedByUserElapsedTime
>= mInjector.getAutoRestrictedBucketDelayMs()) {
newBucket = STANDBY_BUCKET_RESTRICTED;
reason = app.lastRestrictReason;
@@ -974,7 +972,7 @@
long elapsedRealtime) {
int bucketIndex = mAppIdleHistory.getThresholdIndex(packageName, userId,
elapsedRealtime, mAppStandbyScreenThresholds, mAppStandbyElapsedThresholds);
- return THRESHOLD_BUCKETS[bucketIndex];
+ return bucketIndex >= 0 ? THRESHOLD_BUCKETS[bucketIndex] : STANDBY_BUCKET_NEVER;
}
private void notifyBatteryStats(String packageName, int userId, boolean idle) {
@@ -1438,8 +1436,8 @@
}
}
- @VisibleForTesting
- int getAppStandbyBucketReason(String packageName, int userId, long elapsedRealtime) {
+ @Override
+ public int getAppStandbyBucketReason(String packageName, int userId, long elapsedRealtime) {
synchronized (mAppIdleLock) {
return mAppIdleHistory.getAppStandbyReason(packageName, userId, elapsedRealtime);
}
@@ -1857,6 +1855,13 @@
}
@Override
+ public void clearLastUsedTimestampsForTest(@NonNull String packageName, @UserIdInt int userId) {
+ synchronized (mAppIdleLock) {
+ mAppIdleHistory.clearLastUsedTimestamps(packageName, userId);
+ }
+ }
+
+ @Override
public void flushToDisk() {
synchronized (mAppIdleLock) {
mAppIdleHistory.writeAppIdleTimes(mInjector.elapsedRealtime());
@@ -2096,6 +2101,13 @@
.sendToTarget();
}
+ @VisibleForTesting
+ AppIdleHistory getAppIdleHistoryForTest() {
+ synchronized (mAppIdleLock) {
+ return mAppIdleHistory;
+ }
+ }
+
@Override
public void dumpUsers(IndentingPrintWriter idpw, int[] userIds, List<String> pkgs) {
synchronized (mAppIdleLock) {
diff --git a/core/api/current.txt b/core/api/current.txt
index 226c7d5..d03ab96 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -8,9 +8,6 @@
public static final class Manifest.permission {
ctor public Manifest.permission();
field public static final String ACCEPT_HANDOVER = "android.permission.ACCEPT_HANDOVER";
- field public static final String ACCESS_ADSERVICES_ATTRIBUTION = "android.permission.ACCESS_ADSERVICES_ATTRIBUTION";
- field public static final String ACCESS_ADSERVICES_CUSTOM_AUDIENCES = "android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCES";
- field public static final String ACCESS_ADSERVICES_TOPICS = "android.permission.ACCESS_ADSERVICES_TOPICS";
field public static final String ACCESS_BACKGROUND_LOCATION = "android.permission.ACCESS_BACKGROUND_LOCATION";
field public static final String ACCESS_BLOBS_ACROSS_USERS = "android.permission.ACCESS_BLOBS_ACROSS_USERS";
field public static final String ACCESS_CHECKIN_PROPERTIES = "android.permission.ACCESS_CHECKIN_PROPERTIES";
@@ -12331,6 +12328,7 @@
method @Nullable public java.util.Set<java.lang.String> getCategories();
method @Nullable public CharSequence getDisabledMessage();
method public int getDisabledReason();
+ method public int getExcludedFromSurfaces();
method @Nullable public android.os.PersistableBundle getExtras();
method @NonNull public String getId();
method @Nullable public android.content.Intent getIntent();
@@ -12347,8 +12345,8 @@
method public boolean isDeclaredInManifest();
method public boolean isDynamic();
method public boolean isEnabled();
+ method public boolean isExcludedFromSurfaces(int);
method public boolean isImmutable();
- method public boolean isIncludedIn(int);
method public boolean isPinned();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.ShortcutInfo> CREATOR;
@@ -24461,6 +24459,7 @@
method public void close();
method @NonNull public android.media.metrics.LogSessionId getSessionId();
method public void reportBundleMetrics(@NonNull android.os.PersistableBundle);
+ field public static final String KEY_STATSD_ATOM = "bundlesession-statsd-atom";
}
public final class EditingSession implements java.lang.AutoCloseable {
@@ -24484,6 +24483,7 @@
method @NonNull public android.media.metrics.PlaybackSession createPlaybackSession();
method @NonNull public android.media.metrics.RecordingSession createRecordingSession();
method @NonNull public android.media.metrics.TranscodingSession createTranscodingSession();
+ method @NonNull public void releaseSessionId(@NonNull String);
field public static final long INVALID_TIMESTAMP = -1L; // 0xffffffffffffffffL
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index f3867d8..d6949bf 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1108,7 +1108,7 @@
method @RequiresPermission("android.permission.NOTIFY_PENDING_SYSTEM_UPDATE") public void notifyPendingSystemUpdate(long, boolean);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public boolean packageHasActiveAdmins(String);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, android.Manifest.permission.PROVISION_DEMO_DEVICE}) public void provisionFullyManagedDevice(@NonNull android.app.admin.FullyManagedDeviceProvisioningParams) throws android.app.admin.ProvisioningException;
- method @RequiresPermission(android.Manifest.permission.SEND_LOST_MODE_LOCATION_UPDATES) public void sendLostModeLocationUpdate(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
+ method @RequiresPermission(android.Manifest.permission.TRIGGER_LOST_MODE) public void sendLostModeLocationUpdate(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS) public boolean setActiveProfileOwner(@NonNull android.content.ComponentName, String) throws java.lang.IllegalArgumentException;
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setDeviceProvisioningConfigApplied();
method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setDpcDownloaded(boolean);
@@ -1195,13 +1195,16 @@
public static final class DevicePolicyResources.Strings {
}
- public static final class DevicePolicyResources.Strings.PermissionController {
- field public static final String BACKGROUND_ACCESS_DISABLED_BY_ADMIN_MESSAGE = "PermissionController.BACKGROUND_ACCESS_DISABLED_BY_ADMIN_MESSAGE";
- field public static final String BACKGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE = "PermissionController.BACKGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE";
- field public static final String FOREGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE = "PermissionController.FOREGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE";
- field public static final String HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE = "PermissionController.HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE";
- field public static final String LOCATION_AUTO_GRANTED_MESSAGE = "PermissionController.LOCATION_AUTO_GRANTED_MESSAGE";
- field public static final String WORK_PROFILE_DEFAULT_APPS_TITLE = "PermissionController.WORK_PROFILE_DEFAULT_APPS_TITLE";
+ public static final class DevicePolicyResources.Strings.DefaultAppSettings {
+ field public static final String HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE = "DefaultAppSettings.HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE";
+ field public static final String WORK_PROFILE_DEFAULT_APPS_TITLE = "DefaultAppSettings.WORK_PROFILE_DEFAULT_APPS_TITLE";
+ }
+
+ public static final class DevicePolicyResources.Strings.PermissionSettings {
+ field public static final String BACKGROUND_ACCESS_DISABLED_BY_ADMIN_MESSAGE = "PermissionSettings.BACKGROUND_ACCESS_DISABLED_BY_ADMIN_MESSAGE";
+ field public static final String BACKGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE = "PermissionSettings.BACKGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE";
+ field public static final String FOREGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE = "PermissionSettings.FOREGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE";
+ field public static final String LOCATION_AUTO_GRANTED_MESSAGE = "PermissionSettings.LOCATION_AUTO_GRANTED_MESSAGE";
}
public class DevicePolicyResourcesManager {
@@ -2633,18 +2636,18 @@
method public int describeContents();
method @NonNull public float[] getAnchorPointInOutputUvSpace();
method @NonNull public float[] getAnchorPointInWorldSpace();
- method public float getCameraOrbitPitchDegrees();
- method public float getCameraOrbitYawDegrees();
+ method @FloatRange(from=-90.0F, to=90.0f) public float getCameraOrbitPitchDegrees();
+ method @FloatRange(from=-180.0F, to=180.0f) public float getCameraOrbitYawDegrees();
method public float getDollyDistanceInWorldSpace();
- method public float getFrustumFarInWorldSpace();
- method public float getFrustumNearInWorldSpace();
- method public float getVerticalFovDegrees();
+ method @FloatRange(from=0.0f) public float getFrustumFarInWorldSpace();
+ method @FloatRange(from=0.0f) public float getFrustumNearInWorldSpace();
+ method @FloatRange(from=0.0f, to=180.0f, fromInclusive=false) public float getVerticalFovDegrees();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.wallpapereffectsgeneration.CameraAttributes> CREATOR;
}
public static final class CameraAttributes.Builder {
- ctor public CameraAttributes.Builder(@NonNull float[], @NonNull float[]);
+ ctor public CameraAttributes.Builder(@NonNull @Size(3) float[], @NonNull @Size(2) float[]);
method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes build();
method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes.Builder setCameraOrbitPitchDegrees(@FloatRange(from=-90.0F, to=90.0f) float);
method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes.Builder setCameraOrbitYawDegrees(@FloatRange(from=-180.0F, to=180.0f) float);
@@ -2672,12 +2675,11 @@
method @NonNull public String getTaskId();
method @NonNull public java.util.List<android.app.wallpapereffectsgeneration.TexturedMesh> getTexturedMeshes();
method public void writeToParcel(@NonNull android.os.Parcel, int);
- field public static final int CINEMATIC_EFFECT_STATUS_ERROR = 2; // 0x2
- field public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 3; // 0x3
+ field public static final int CINEMATIC_EFFECT_STATUS_ERROR = 0; // 0x0
+ field public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 2; // 0x2
field public static final int CINEMATIC_EFFECT_STATUS_OK = 1; // 0x1
- field public static final int CINEMATIC_EFFECT_STATUS_PENDING = 4; // 0x4
- field public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 5; // 0x5
- field public static final int CINEMATIC_EFFECT_STATUS_UNKNOWN = 0; // 0x0
+ field public static final int CINEMATIC_EFFECT_STATUS_PENDING = 3; // 0x3
+ field public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 4; // 0x4
field @NonNull public static final android.os.Parcelable.Creator<android.app.wallpapereffectsgeneration.CinematicEffectResponse> CREATOR;
field public static final int IMAGE_CONTENT_TYPE_LANDSCAPE = 2; // 0x2
field public static final int IMAGE_CONTENT_TYPE_OTHER = 3; // 0x3
@@ -2805,8 +2807,11 @@
public final class VirtualDeviceParams implements android.os.Parcelable {
method public int describeContents();
method @NonNull public java.util.Set<android.content.ComponentName> getAllowedActivities();
+ method @NonNull public java.util.Set<android.content.ComponentName> getAllowedCrossTaskNavigations();
method @NonNull public java.util.Set<android.content.ComponentName> getBlockedActivities();
+ method @NonNull public java.util.Set<android.content.ComponentName> getBlockedCrossTaskNavigations();
method public int getDefaultActivityPolicy();
+ method public int getDefaultNavigationPolicy();
method public int getLockState();
method @NonNull public java.util.Set<android.os.UserHandle> getUsersWithMatchingAccounts();
method public void writeToParcel(@NonNull android.os.Parcel, int);
@@ -2815,13 +2820,17 @@
field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.VirtualDeviceParams> CREATOR;
field public static final int LOCK_STATE_ALWAYS_UNLOCKED = 1; // 0x1
field public static final int LOCK_STATE_DEFAULT = 0; // 0x0
+ field public static final int NAVIGATION_POLICY_DEFAULT_ALLOWED = 0; // 0x0
+ field public static final int NAVIGATION_POLICY_DEFAULT_BLOCKED = 1; // 0x1
}
public static final class VirtualDeviceParams.Builder {
ctor public VirtualDeviceParams.Builder();
method @NonNull public android.companion.virtual.VirtualDeviceParams build();
method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setAllowedActivities(@NonNull java.util.Set<android.content.ComponentName>);
+ method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setAllowedCrossTaskNavigations(@NonNull java.util.Set<android.content.ComponentName>);
method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedActivities(@NonNull java.util.Set<android.content.ComponentName>);
+ method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedCrossTaskNavigations(@NonNull java.util.Set<android.content.ComponentName>);
method @NonNull @RequiresPermission(value=android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY, conditional=true) public android.companion.virtual.VirtualDeviceParams.Builder setLockState(int);
method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setUsersWithMatchingAccounts(@NonNull java.util.Set<android.os.UserHandle>);
}
@@ -11806,10 +11815,10 @@
package android.service.trust {
public final class GrantTrustResult implements android.os.Parcelable {
+ ctor public GrantTrustResult(int);
method public int describeContents();
method public int getStatus();
method @NonNull public static String statusToString(int);
- method @NonNull public static android.service.trust.GrantTrustResult withStatus(int);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.trust.GrantTrustResult> CREATOR;
field public static final int STATUS_UNKNOWN = 0; // 0x0
@@ -12031,8 +12040,9 @@
public abstract class WallpaperEffectsGenerationService extends android.app.Service {
ctor public WallpaperEffectsGenerationService();
method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method public abstract void onGenerateCinematicEffect(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectRequest);
+ method @MainThread public abstract void onGenerateCinematicEffect(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectRequest);
method public final void returnCinematicEffectResponse(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectResponse);
+ field public static final String SERVICE_INTERFACE = "android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService";
}
}
@@ -13368,7 +13378,6 @@
}
public class TelephonyManager {
- method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void addCarrierPrivilegesListener(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CarrierPrivilegesListener);
method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) @WorkerThread public void bootstrapAuthenticationRequest(int, @NonNull android.net.Uri, @NonNull android.telephony.gba.UaSecurityProtocolIdentifier, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.BootstrapAuthenticationCallback);
method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult changeIccLockPin(@NonNull String, @NonNull String);
@@ -13469,7 +13478,6 @@
method @RequiresPermission(android.Manifest.permission.REBOOT) public int prepareForUnattendedReboot();
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerCarrierPrivilegesCallback(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CarrierPrivilegesCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void removeCarrierPrivilegesListener(@NonNull android.telephony.TelephonyManager.CarrierPrivilegesListener);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean);
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestModemActivityInfo(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.ModemActivityInfo,android.telephony.TelephonyManager.ModemActivityInfoException>);
@@ -13630,10 +13638,6 @@
method public default void onCarrierServiceChanged(@Nullable String, int);
}
- @Deprecated public static interface TelephonyManager.CarrierPrivilegesListener {
- method @Deprecated public void onCarrierPrivilegesChanged(@NonNull java.util.List<java.lang.String>, @NonNull int[]);
- }
-
public static class TelephonyManager.ModemActivityInfoException extends java.lang.Exception {
ctor public TelephonyManager.ModemActivityInfoException(int);
method public int getErrorCode();
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index a67d002..f7bf716 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -3250,6 +3250,7 @@
method public void onDisplayAreaVanished(@NonNull android.window.DisplayAreaInfo);
method @CallSuper @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public java.util.List<android.window.DisplayAreaAppearedInfo> registerOrganizer(int);
field public static final int FEATURE_DEFAULT_TASK_CONTAINER = 1; // 0x1
+ field public static final int FEATURE_IME = 8; // 0x8
field public static final int FEATURE_ONE_HANDED = 3; // 0x3
field public static final int FEATURE_ROOT = 0; // 0x0
field public static final int FEATURE_SYSTEM_FIRST = 0; // 0x0
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a28b3e9..5eda587 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5707,7 +5707,6 @@
* their launch had come from the original activity.
* @param intent The Intent to start.
* @param options ActivityOptions or null.
- * @param permissionToken Token received from the system that permits this call to be made.
* @param ignoreTargetSecurity If true, the activity manager will not check whether the
* caller it is doing the start is, is actually allowed to start the target activity.
* If you set this to true, you must set an explicit component in the Intent and do any
@@ -5716,18 +5715,18 @@
* @hide
*/
public void startActivityAsCaller(Intent intent, @Nullable Bundle options,
- IBinder permissionToken, boolean ignoreTargetSecurity, int userId) {
- startActivityAsCaller(intent, options, permissionToken, ignoreTargetSecurity, userId, -1);
+ boolean ignoreTargetSecurity, int userId) {
+ startActivityAsCaller(intent, options, ignoreTargetSecurity, userId, -1);
}
/**
- * @see #startActivityAsCaller(Intent, Bundle, IBinder, boolean, int)
+ * @see #startActivityAsCaller(Intent, Bundle, boolean, int)
* @param requestCode The request code used for returning a result or -1 if no result should be
* returned.
* @hide
*/
public void startActivityAsCaller(Intent intent, @Nullable Bundle options,
- IBinder permissionToken, boolean ignoreTargetSecurity, int userId, int requestCode) {
+ boolean ignoreTargetSecurity, int userId, int requestCode) {
if (mParent != null) {
throw new RuntimeException("Can't be called from a child");
}
@@ -5735,8 +5734,7 @@
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivityAsCaller(
this, mMainThread.getApplicationThread(), mToken, this,
- intent, requestCode, options, permissionToken, ignoreTargetSecurity,
- userId);
+ intent, requestCode, options, ignoreTargetSecurity, userId);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 5b05b45..88844b5 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -4890,6 +4890,11 @@
}
/** @hide */
+ public static boolean isProcStateConsideredInteraction(@ProcessState int procState) {
+ return (procState <= PROCESS_STATE_TOP || procState == PROCESS_STATE_BOUND_TOP);
+ }
+
+ /** @hide */
public static String procStateToString(int procState) {
final String procStateStr;
switch (procState) {
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 9fe8e79..95ac799 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -630,8 +630,9 @@
/**
* Delete uid from the ActivityManagerService PendingStartActivityUids list.
* @param uid uid
+ * @param nowElapsed starting time of updateOomAdj
*/
- public abstract void deletePendingTopUid(int uid);
+ public abstract void deletePendingTopUid(int uid, long nowElapsed);
/**
* Is the uid in ActivityManagerService PendingStartActivityUids list?
@@ -684,6 +685,11 @@
public abstract @TempAllowListType int getPushMessagingOverQuotaBehavior();
/**
+ * Return the startForeground() grace period after calling startForegroundService().
+ */
+ public abstract int getServiceStartForegroundTimeout();
+
+ /**
* Returns the capability of the given uid
*/
public abstract @ProcessCapability int getUidCapability(int uid);
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 0d81036..0f54ce5 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -361,6 +361,10 @@
private static final String KEY_LAUNCH_INTO_PIP_PARAMS =
"android.activity.launchIntoPipParams";
+ /** See {@link #setDismissKeyguardIfInsecure()}. */
+ private static final String KEY_DISMISS_KEYGUARD_IF_INSECURE =
+ "android.activity.dismissKeyguardIfInsecure";
+
/**
* @see #setLaunchCookie
* @hide
@@ -457,6 +461,7 @@
private boolean mLaunchedFromBubble;
private boolean mTransientLaunch;
private PictureInPictureParams mLaunchIntoPipParams;
+ private boolean mDismissKeyguardIfInsecure;
/**
* Create an ActivityOptions specifying a custom animation to run when
@@ -1254,6 +1259,7 @@
mLaunchIntoPipParams = opts.getParcelable(KEY_LAUNCH_INTO_PIP_PARAMS);
mIsEligibleForLegacyPermissionPrompt =
opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE);
+ mDismissKeyguardIfInsecure = opts.getBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE);
}
/**
@@ -1850,6 +1856,27 @@
}
/**
+ * Sets whether the insecure keyguard should go away when this activity launches. In case the
+ * keyguard is secure, this option will be ignored.
+ *
+ * @see Activity#setShowWhenLocked(boolean)
+ * @see android.R.attr#showWhenLocked
+ * @hide
+ */
+ public void setDismissKeyguardIfInsecure() {
+ mDismissKeyguardIfInsecure = true;
+ }
+
+ /**
+ * @see #setDismissKeyguardIfInsecure()
+ * @return whether the insecure keyguard should go away when the activity launches.
+ * @hide
+ */
+ public boolean getDismissKeyguardIfInsecure() {
+ return mDismissKeyguardIfInsecure;
+ }
+
+ /**
* Update the current values in this ActivityOptions from those supplied
* in <var>otherOptions</var>. Any values
* defined in <var>otherOptions</var> replace those in the base options.
@@ -2110,6 +2137,9 @@
b.putBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE,
mIsEligibleForLegacyPermissionPrompt);
}
+ if (mDismissKeyguardIfInsecure) {
+ b.putBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE, mDismissKeyguardIfInsecure);
+ }
return b;
}
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index a836625..6fc0c26 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -106,14 +106,6 @@
RESIZE_MODE_PRESERVE_WINDOW | RESIZE_MODE_FORCED;
/**
- * Extra included on intents that are delegating the call to
- * ActivityManager#startActivityAsCaller to another app. This token is necessary for that call
- * to succeed. Type is IBinder.
- * @hide
- */
- public static final String EXTRA_PERMISSION_TOKEN = "android.app.extra.PERMISSION_TOKEN";
-
- /**
* Extra included on intents that contain an EXTRA_INTENT, with options that the contained
* intent may want to be started with. Type is Bundle.
* TODO: remove once the ChooserActivity moves to systemui
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index ef9a2f2..87b2417 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -141,7 +141,7 @@
int startActivityAsCaller(in IApplicationThread caller, in String callingPackage,
in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options,
- IBinder permissionToken, boolean ignoreTargetSecurity, int userId);
+ boolean ignoreTargetSecurity, int userId);
boolean isActivityStartAllowedOnDisplay(int displayId, in Intent intent, in String resolvedType,
int userId);
@@ -182,18 +182,6 @@
int addAppTask(in IBinder activityToken, in Intent intent,
in ActivityManager.TaskDescription description, in Bitmap thumbnail);
Point getAppTaskThumbnailSize();
- /**
- * Only callable from the system. This token grants a temporary permission to call
- * #startActivityAsCaller. The token will time out after START_AS_CALLER_TOKEN_TIMEOUT
- * if it is not used.
- *
- * @param componentName The component name of the delegated component that is allowed to
- * call #startActivityAsCaller with the returned token.
- *
- * @return Returns a token that can be given to a "delegate" app that may call
- * #startActivityAsCaller
- */
- IBinder requestStartActivityPermissionToken(in ComponentName componentName);
oneway void releaseSomeActivities(in IApplicationThread app);
Bitmap getTaskDescriptionIcon(in String filename, int userId);
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index ac979c4..995a9f3 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -381,6 +381,10 @@
* Force the global system in or out of touch mode. This can be used if your
* instrumentation relies on the UI being in one more or the other when it starts.
*
+ * <p><b>Note:</b> Starting from Android {@link Build.VERSION_CODES#TIRAMISU}, this method
+ * will only take effect if the instrumentation was sourced from a process with
+ * {@code MODIFY_TOUCH_MODE_STATE} internal permission granted (shell already have it).
+ *
* @param inTouch Set to true to be in touch mode, false to be in focus mode.
*/
public void setInTouchMode(boolean inTouch) {
@@ -1995,7 +1999,7 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public ActivityResult execStartActivityAsCaller(
Context who, IBinder contextThread, IBinder token, Activity target,
- Intent intent, int requestCode, Bundle options, IBinder permissionToken,
+ Intent intent, int requestCode, Bundle options,
boolean ignoreTargetSecurity, int userId) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
@@ -2030,7 +2034,7 @@
.startActivityAsCaller(whoThread, who.getOpPackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
- requestCode, 0, null, options, permissionToken,
+ requestCode, 0, null, options,
ignoreTargetSecurity, userId);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index f523a7d..83fe29f 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -19,7 +19,6 @@
import android.app.ActivityManager.RunningTaskInfo;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
-import android.os.Binder;
import android.os.Build;
import android.os.RemoteException;
import android.window.TaskSnapshot;
@@ -32,10 +31,18 @@
*/
public abstract class TaskStackListener extends ITaskStackListener.Stub {
+ /** Whether this listener and the callback dispatcher are in different processes. */
+ private boolean mIsRemote = true;
+
@UnsupportedAppUsage
public TaskStackListener() {
}
+ /** Indicates that this listener lives in system server. */
+ public void setIsLocal() {
+ mIsRemote = false;
+ }
+
@Override
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void onTaskStackChanged() throws RemoteException {
@@ -154,8 +161,7 @@
@Override
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) throws RemoteException {
- if (Binder.getCallingPid() != android.os.Process.myPid()
- && snapshot != null && snapshot.getHardwareBuffer() != null) {
+ if (mIsRemote && snapshot != null && snapshot.getHardwareBuffer() != null) {
// Preemptively clear any reference to the buffer
snapshot.getHardwareBuffer().close();
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 82e5ebf..f9f0c58b 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -60,7 +60,6 @@
import android.net.PrivateDnsConnectivityChecker;
import android.net.ProxyInfo;
import android.net.Uri;
-import android.net.wifi.WifiSsid;
import android.nfc.NfcAdapter;
import android.os.Binder;
import android.os.Build;
@@ -112,7 +111,6 @@
import java.lang.annotation.RetentionPolicy;
import java.net.InetSocketAddress;
import java.net.Proxy;
-import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
@@ -6197,7 +6195,7 @@
* organization-owned managed profile.
*
* <p>The caller must hold the
- * {@link android.Manifest.permission#SEND_LOST_MODE_LOCATION_UPDATES} permission.
+ * {@link android.Manifest.permission#TRIGGER_LOST_MODE} permission.
*
* <p> Not for use by third-party applications.
*
@@ -6207,7 +6205,7 @@
* @hide
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.SEND_LOST_MODE_LOCATION_UPDATES)
+ @RequiresPermission(android.Manifest.permission.TRIGGER_LOST_MODE)
public void sendLostModeLocationUpdate(@NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<Boolean> callback) {
throwIfParentInstance("sendLostModeLocationUpdate");
@@ -15237,26 +15235,15 @@
*/
public void setWifiSsidPolicy(@Nullable WifiSsidPolicy policy) {
throwIfParentInstance("setWifiSsidPolicy");
- if (mService != null) {
- try {
- if (policy == null) {
- mService.setSsidAllowlist(new ArrayList<>());
- } else {
- int policyType = policy.getPolicyType();
- List<String> ssidList = new ArrayList<>();
- for (WifiSsid ssid : policy.getSsids()) {
- ssidList.add(new String(ssid.getBytes(), StandardCharsets.UTF_8));
- }
- if (policyType == WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST) {
- mService.setSsidAllowlist(ssidList);
- } else {
- mService.setSsidDenylist(ssidList);
- }
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ if (mService == null) {
+ return;
}
+ try {
+ mService.setWifiSsidPolicy(policy);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
}
/**
@@ -15274,30 +15261,10 @@
return null;
}
try {
- List<String> allowlist = mService.getSsidAllowlist();
- if (!allowlist.isEmpty()) {
- List<WifiSsid> wifiSsidAllowlist = new ArrayList<>();
- for (String ssid : allowlist) {
- wifiSsidAllowlist.add(
- WifiSsid.fromBytes(ssid.getBytes(StandardCharsets.UTF_8)));
- }
- return new WifiSsidPolicy(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST,
- new ArraySet<>(wifiSsidAllowlist));
- }
- List<String> denylist = mService.getSsidDenylist();
- if (!denylist.isEmpty()) {
- List<WifiSsid> wifiSsidDenylist = new ArrayList<>();
- for (String ssid : denylist) {
- wifiSsidDenylist.add(
- WifiSsid.fromBytes(ssid.getBytes(StandardCharsets.UTF_8)));
- }
- return new WifiSsidPolicy(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST,
- new ArraySet<>(wifiSsidDenylist));
- }
+ return mService.getWifiSsidPolicy();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- return null;
}
/**
diff --git a/core/java/android/app/admin/DevicePolicyResources.java b/core/java/android/app/admin/DevicePolicyResources.java
index 2b3780e..ea30ef7 100644
--- a/core/java/android/app/admin/DevicePolicyResources.java
+++ b/core/java/android/app/admin/DevicePolicyResources.java
@@ -1741,26 +1741,14 @@
/**
* Class containing the identifiers used to update device management-related system strings
- * in the Permissions module.
+ * for the permission settings.
*/
- public static final class PermissionController {
-
- private PermissionController() {
+ public static final class PermissionSettings {
+
+ private PermissionSettings() {
}
- private static final String PREFIX = "PermissionController.";
-
- /**
- * Title for settings page to show default apps for work.
- */
- public static final String WORK_PROFILE_DEFAULT_APPS_TITLE =
- PREFIX + "WORK_PROFILE_DEFAULT_APPS_TITLE";
-
- /**
- * Summary indicating that a home role holder app is missing work profile support.
- */
- public static final String HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE =
- PREFIX + "HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE";
+ private static final String PREFIX = "PermissionSettings.";
/**
* Summary of a permission switch in Settings when the background access is denied by an
@@ -1790,5 +1778,29 @@
public static final String LOCATION_AUTO_GRANTED_MESSAGE =
PREFIX + "LOCATION_AUTO_GRANTED_MESSAGE";
}
+
+ /**
+ * Class containing the identifiers used to update device management-related system strings
+ * for the default app settings.
+ */
+ public static final class DefaultAppSettings {
+
+ private DefaultAppSettings() {
+ }
+
+ private static final String PREFIX = "DefaultAppSettings.";
+
+ /**
+ * Title for settings page to show default apps for work.
+ */
+ public static final String WORK_PROFILE_DEFAULT_APPS_TITLE =
+ PREFIX + "WORK_PROFILE_DEFAULT_APPS_TITLE";
+
+ /**
+ * Summary indicating that a home role holder app is missing work profile support.
+ */
+ public static final String HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE =
+ PREFIX + "HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE";
+ }
}
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 8a9ef4b..6c6a7ca 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -33,6 +33,7 @@
import android.app.admin.FactoryResetProtectionPolicy;
import android.app.admin.ManagedProfileProvisioningParams;
import android.app.admin.FullyManagedDeviceProvisioningParams;
+import android.app.admin.WifiSsidPolicy;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
@@ -545,10 +546,8 @@
void setMinimumRequiredWifiSecurityLevel(int level);
int getMinimumRequiredWifiSecurityLevel();
- void setSsidAllowlist(in List<String> ssids);
- List<String> getSsidAllowlist();
- void setSsidDenylist(in List<String> ssids);
- List<String> getSsidDenylist();
+ void setWifiSsidPolicy(in WifiSsidPolicy policy);
+ WifiSsidPolicy getWifiSsidPolicy();
List<UserHandle> listForegroundAffiliatedUsers();
void setDrawables(in List<DevicePolicyDrawableResource> drawables);
diff --git a/core/java/android/app/admin/WifiSsidPolicy.java b/core/java/android/app/admin/WifiSsidPolicy.java
index e918075..3fefe4b 100644
--- a/core/java/android/app/admin/WifiSsidPolicy.java
+++ b/core/java/android/app/admin/WifiSsidPolicy.java
@@ -25,6 +25,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
import java.util.Set;
/**
@@ -135,6 +136,23 @@
}
@Override
+ public boolean equals(Object thatObject) {
+ if (this == thatObject) {
+ return true;
+ }
+ if (!(thatObject instanceof WifiSsidPolicy)) {
+ return false;
+ }
+ WifiSsidPolicy that = (WifiSsidPolicy) thatObject;
+ return mPolicyType == that.mPolicyType && Objects.equals(mSsids, that.mSsids);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPolicyType, mSsids);
+ }
+
+ @Override
public int describeContents() {
return 0;
}
diff --git a/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java b/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java
index dfbc7a4..c91ce24 100644
--- a/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java
+++ b/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java
@@ -18,6 +18,7 @@
import android.annotation.FloatRange;
import android.annotation.NonNull;
+import android.annotation.Size;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -117,6 +118,7 @@
/**
* Get the camera yaw orbit rotation.
*/
+ @FloatRange(from = -180.0f, to = 180.0f)
public float getCameraOrbitYawDegrees() {
return mCameraOrbitYawDegrees;
}
@@ -124,6 +126,7 @@
/**
* Get the camera pitch orbit rotation.
*/
+ @FloatRange(from = -90.0f, to = 90.0f)
public float getCameraOrbitPitchDegrees() {
return mCameraOrbitPitchDegrees;
}
@@ -138,6 +141,7 @@
/**
* Get the camera vertical fov degrees.
*/
+ @FloatRange(from = 0.0f, to = 180.0f, fromInclusive = false)
public float getVerticalFovDegrees() {
return mVerticalFovDegrees;
}
@@ -145,6 +149,7 @@
/**
* Get the frustum in near plane.
*/
+ @FloatRange(from = 0.0f)
public float getFrustumNearInWorldSpace() {
return mFrustumNearInWorldSpace;
}
@@ -152,6 +157,7 @@
/**
* Get the frustum in far plane.
*/
+ @FloatRange(from = 0.0f)
public float getFrustumFarInWorldSpace() {
return mFrustumFarInWorldSpace;
}
@@ -217,8 +223,8 @@
* @hide
*/
@SystemApi
- public Builder(@NonNull float[] anchorPointInWorldSpace,
- @NonNull float[] anchorPointInOutputUvSpace) {
+ public Builder(@NonNull @Size(3) float[] anchorPointInWorldSpace,
+ @NonNull @Size(2) float[] anchorPointInOutputUvSpace) {
mAnchorPointInWorldSpace = anchorPointInWorldSpace;
mAnchorPointInOutputUvSpace = anchorPointInOutputUvSpace;
}
diff --git a/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java b/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java
index 1254794..b1d2b38 100644
--- a/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java
+++ b/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java
@@ -39,27 +39,31 @@
public final class CinematicEffectResponse implements Parcelable {
/** @hide */
@IntDef(prefix = {"CINEMATIC_EFFECT_STATUS_"},
- value = {CINEMATIC_EFFECT_STATUS_UNKNOWN,
+ value = {CINEMATIC_EFFECT_STATUS_ERROR,
CINEMATIC_EFFECT_STATUS_OK,
- CINEMATIC_EFFECT_STATUS_ERROR,
CINEMATIC_EFFECT_STATUS_NOT_READY,
CINEMATIC_EFFECT_STATUS_PENDING,
- CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS})
+ CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS
+ })
@Retention(RetentionPolicy.SOURCE)
public @interface CinematicEffectStatusCode {}
- /** Cinematic effect generation unknown status. */
- public static final int CINEMATIC_EFFECT_STATUS_UNKNOWN = 0;
+ /** Cinematic effect generation failure with internal error. */
+ public static final int CINEMATIC_EFFECT_STATUS_ERROR = 0;
+
/** Cinematic effect generation success. */
public static final int CINEMATIC_EFFECT_STATUS_OK = 1;
- /** Cinematic effect generation failure. */
- public static final int CINEMATIC_EFFECT_STATUS_ERROR = 2;
+
/** Service not ready for cinematic effect generation. */
- public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 3;
- /** Cienmatic effect generation process is pending. */
- public static final int CINEMATIC_EFFECT_STATUS_PENDING = 4;
- /** Too manay requests for server to handle. */
- public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 5;
+ public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 2;
+ /**
+ * There is already a task being processed for the same task id.
+ * Client should wait for the response and not send the same request
+ * again.
+ */
+ public static final int CINEMATIC_EFFECT_STATUS_PENDING = 3;
+ /** Too many requests for server to handle. */
+ public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 4;
/** @hide */
@IntDef(prefix = {"IMAGE_CONTENT_TYPE_"},
@@ -71,13 +75,13 @@
@Retention(RetentionPolicy.SOURCE)
public @interface ImageContentType {}
- /** Image content unknown. */
+ /** Unable to determine image type. */
public static final int IMAGE_CONTENT_TYPE_UNKNOWN = 0;
/** Image content is people portrait. */
public static final int IMAGE_CONTENT_TYPE_PEOPLE_PORTRAIT = 1;
/** Image content is landscape. */
public static final int IMAGE_CONTENT_TYPE_LANDSCAPE = 2;
- /** Image content is doesn't belong to other types. */
+ /** Image content is not people portrait or landscape. */
public static final int IMAGE_CONTENT_TYPE_OTHER = 3;
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index a1983ca..914b321 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -469,6 +469,10 @@
/**
* Called when the top activity is changed.
*
+ * <p>Note: When there are no activities running on the virtual display, the
+ * {@link #onDisplayEmpty(int)} will be called. If the value topActivity is cached, it
+ * should be cleared when {@link #onDisplayEmpty(int)} is called.
+ *
* @param displayId The display ID on which the activity change happened.
* @param topActivity The component name of the top activity.
*/
diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java
index cbb5183..3b1ff3f 100644
--- a/core/java/android/companion/virtual/VirtualDeviceParams.java
+++ b/core/java/android/companion/virtual/VirtualDeviceParams.java
@@ -83,8 +83,31 @@
*/
public static final int ACTIVITY_POLICY_DEFAULT_BLOCKED = 1;
+ /** @hide */
+ @IntDef(prefix = "NAVIGATION_POLICY_",
+ value = {NAVIGATION_POLICY_DEFAULT_ALLOWED, NAVIGATION_POLICY_DEFAULT_BLOCKED})
+ @Retention(RetentionPolicy.SOURCE)
+ @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+ public @interface NavigationPolicy {}
+
+ /**
+ * Indicates that tasks are allowed to navigate to other tasks on this virtual device,
+ * unless they are explicitly blocked by {@link Builder#setBlockedCrossTaskNavigations}.
+ */
+ public static final int NAVIGATION_POLICY_DEFAULT_ALLOWED = 0;
+
+ /**
+ * Indicates that tasks are blocked from navigating to other tasks by default on this virtual
+ * device, unless allowed by {@link Builder#setAllowedCrossTaskNavigations}.
+ */
+ public static final int NAVIGATION_POLICY_DEFAULT_BLOCKED = 1;
+
private final int mLockState;
@NonNull private final ArraySet<UserHandle> mUsersWithMatchingAccounts;
+ @NonNull private final ArraySet<ComponentName> mAllowedCrossTaskNavigations;
+ @NonNull private final ArraySet<ComponentName> mBlockedCrossTaskNavigations;
+ @NavigationPolicy
+ private final int mDefaultNavigationPolicy;
@NonNull private final ArraySet<ComponentName> mAllowedActivities;
@NonNull private final ArraySet<ComponentName> mBlockedActivities;
@ActivityPolicy
@@ -93,15 +116,23 @@
private VirtualDeviceParams(
@LockState int lockState,
@NonNull Set<UserHandle> usersWithMatchingAccounts,
+ @NonNull Set<ComponentName> allowedCrossTaskNavigations,
+ @NonNull Set<ComponentName> blockedCrossTaskNavigations,
+ @NavigationPolicy int defaultNavigationPolicy,
@NonNull Set<ComponentName> allowedActivities,
@NonNull Set<ComponentName> blockedActivities,
@ActivityPolicy int defaultActivityPolicy) {
Preconditions.checkNotNull(usersWithMatchingAccounts);
+ Preconditions.checkNotNull(allowedCrossTaskNavigations);
+ Preconditions.checkNotNull(blockedCrossTaskNavigations);
Preconditions.checkNotNull(allowedActivities);
Preconditions.checkNotNull(blockedActivities);
mLockState = lockState;
mUsersWithMatchingAccounts = new ArraySet<>(usersWithMatchingAccounts);
+ mAllowedCrossTaskNavigations = new ArraySet<>(allowedCrossTaskNavigations);
+ mBlockedCrossTaskNavigations = new ArraySet<>(blockedCrossTaskNavigations);
+ mDefaultNavigationPolicy = defaultNavigationPolicy;
mAllowedActivities = new ArraySet<>(allowedActivities);
mBlockedActivities = new ArraySet<>(blockedActivities);
mDefaultActivityPolicy = defaultActivityPolicy;
@@ -111,6 +142,9 @@
private VirtualDeviceParams(Parcel parcel) {
mLockState = parcel.readInt();
mUsersWithMatchingAccounts = (ArraySet<UserHandle>) parcel.readArraySet(null);
+ mAllowedCrossTaskNavigations = (ArraySet<ComponentName>) parcel.readArraySet(null);
+ mBlockedCrossTaskNavigations = (ArraySet<ComponentName>) parcel.readArraySet(null);
+ mDefaultNavigationPolicy = parcel.readInt();
mAllowedActivities = (ArraySet<ComponentName>) parcel.readArraySet(null);
mBlockedActivities = (ArraySet<ComponentName>) parcel.readArraySet(null);
mDefaultActivityPolicy = parcel.readInt();
@@ -136,6 +170,45 @@
}
/**
+ * Returns the set of tasks that are allowed to navigate from current task,
+ * or empty set if all tasks are allowed, except the ones explicitly blocked.
+ * If neither allowed or blocked tasks are provided, all task navigations will
+ * be be allowed by default.
+ *
+ * @see Builder#setAllowedCrossTaskNavigations(Set)
+ */
+ @NonNull
+ public Set<ComponentName> getAllowedCrossTaskNavigations() {
+ return Collections.unmodifiableSet(mAllowedCrossTaskNavigations);
+ }
+
+ /**
+ * Returns the set of tasks that are blocked from navigating from the current task,
+ * or empty set to indicate that all tasks in {@link #getAllowedCrossTaskNavigations}
+ * are allowed. If neither allowed or blocked tasks are provided, all task navigations
+ * will be be allowed by default.
+ *
+ * @see Builder#setBlockedCrossTaskNavigations(Set)
+ */
+ @NonNull
+ public Set<ComponentName> getBlockedCrossTaskNavigations() {
+ return Collections.unmodifiableSet(mBlockedCrossTaskNavigations);
+ }
+
+ /**
+ * Returns {@link #NAVIGATION_POLICY_DEFAULT_ALLOWED} if tasks are allowed to navigate on
+ * this virtual device by default, or {@link #NAVIGATION_POLICY_DEFAULT_BLOCKED} if tasks
+ * must be allowed by {@link Builder#setAllowedCrossTaskNavigations} to navigate here.
+ *
+ * @see Builder#setAllowedCrossTaskNavigations
+ * @see Builder#setBlockedCrossTaskNavigations
+ */
+ @NavigationPolicy
+ public int getDefaultNavigationPolicy() {
+ return mDefaultNavigationPolicy;
+ }
+
+ /**
* Returns the set of activities allowed to be streamed, or empty set if all activities are
* allowed, except the ones explicitly blocked.
*
@@ -179,6 +252,9 @@
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mLockState);
dest.writeArraySet(mUsersWithMatchingAccounts);
+ dest.writeArraySet(mAllowedCrossTaskNavigations);
+ dest.writeArraySet(mBlockedCrossTaskNavigations);
+ dest.writeInt(mDefaultNavigationPolicy);
dest.writeArraySet(mAllowedActivities);
dest.writeArraySet(mBlockedActivities);
dest.writeInt(mDefaultActivityPolicy);
@@ -195,6 +271,9 @@
VirtualDeviceParams that = (VirtualDeviceParams) o;
return mLockState == that.mLockState
&& mUsersWithMatchingAccounts.equals(that.mUsersWithMatchingAccounts)
+ && Objects.equals(mAllowedCrossTaskNavigations, that.mAllowedCrossTaskNavigations)
+ && Objects.equals(mBlockedCrossTaskNavigations, that.mBlockedCrossTaskNavigations)
+ && mDefaultNavigationPolicy == that.mDefaultNavigationPolicy
&& Objects.equals(mAllowedActivities, that.mAllowedActivities)
&& Objects.equals(mBlockedActivities, that.mBlockedActivities)
&& mDefaultActivityPolicy == that.mDefaultActivityPolicy;
@@ -203,8 +282,9 @@
@Override
public int hashCode() {
return Objects.hash(
- mLockState, mUsersWithMatchingAccounts, mAllowedActivities, mBlockedActivities,
- mDefaultActivityPolicy);
+ mLockState, mUsersWithMatchingAccounts, mAllowedCrossTaskNavigations,
+ mBlockedCrossTaskNavigations, mDefaultNavigationPolicy, mAllowedActivities,
+ mBlockedActivities, mDefaultActivityPolicy);
}
@Override
@@ -213,6 +293,9 @@
return "VirtualDeviceParams("
+ " mLockState=" + mLockState
+ " mUsersWithMatchingAccounts=" + mUsersWithMatchingAccounts
+ + " mAllowedCrossTaskNavigations=" + mAllowedCrossTaskNavigations
+ + " mBlockedCrossTaskNavigations=" + mBlockedCrossTaskNavigations
+ + " mDefaultNavigationPolicy=" + mDefaultNavigationPolicy
+ " mAllowedActivities=" + mAllowedActivities
+ " mBlockedActivities=" + mBlockedActivities
+ " mDefaultActivityPolicy=" + mDefaultActivityPolicy
@@ -237,7 +320,12 @@
public static final class Builder {
private @LockState int mLockState = LOCK_STATE_DEFAULT;
- @NonNull private Set<UserHandle> mUsersWithMatchingAccounts = Collections.emptySet();;
+ @NonNull private Set<UserHandle> mUsersWithMatchingAccounts = Collections.emptySet();
+ @NonNull private Set<ComponentName> mAllowedCrossTaskNavigations = Collections.emptySet();
+ @NonNull private Set<ComponentName> mBlockedCrossTaskNavigations = Collections.emptySet();
+ @NavigationPolicy
+ private int mDefaultNavigationPolicy = NAVIGATION_POLICY_DEFAULT_ALLOWED;
+ private boolean mDefaultNavigationPolicyConfigured = false;
@NonNull private Set<ComponentName> mBlockedActivities = Collections.emptySet();
@NonNull private Set<ComponentName> mAllowedActivities = Collections.emptySet();
@ActivityPolicy
@@ -288,6 +376,70 @@
}
/**
+ * Sets the tasks allowed to navigate from current task in the virtual device. Tasks
+ * not in {@code allowedCrossTaskNavigations} will be blocked from navigating to a new
+ * task. Calling this method will cause {@link #getDefaultNavigationPolicy()} to be
+ * {@link #NAVIGATION_POLICY_DEFAULT_BLOCKED}, meaning tasks not in
+ * {@code allowedCrossTaskNavigations} will be blocked from navigating here.
+ *
+ * <p>This method must not be called if {@link #setBlockedCrossTaskNavigations(Set)} has
+ * been called.
+ *
+ * @throws IllegalArgumentException if {@link #setBlockedCrossTaskNavigations(Set)} has been
+ * called.
+ *
+ * @param allowedCrossTaskNavigations A set of tasks {@link ComponentName} allowed to
+ * navigate to new tasks in the virtual device.
+ */
+ @NonNull
+ public Builder setAllowedCrossTaskNavigations(
+ @NonNull Set<ComponentName> allowedCrossTaskNavigations) {
+ Preconditions.checkNotNull(allowedCrossTaskNavigations);
+ if (mDefaultNavigationPolicyConfigured
+ && mDefaultNavigationPolicy != NAVIGATION_POLICY_DEFAULT_BLOCKED) {
+ throw new IllegalArgumentException(
+ "Allowed cross task navigation and blocked task navigation cannot "
+ + " both be set.");
+ }
+ mDefaultNavigationPolicy = NAVIGATION_POLICY_DEFAULT_BLOCKED;
+ mDefaultNavigationPolicyConfigured = true;
+ mAllowedCrossTaskNavigations = allowedCrossTaskNavigations;
+ return this;
+ }
+
+ /**
+ * Sets the tasks blocked from navigating from current task in the virtual device.
+ * Tasks are allowed to navigate unless they are in
+ * {@code blockedCrossTaskNavigations}. Calling this method will cause
+ * {@link #NAVIGATION_POLICY_DEFAULT_ALLOWED}, meaning activities are allowed to launch
+ * unless they are in {@code blockedCrossTaskNavigations}.
+ *
+ * <p> This method must not be called if {@link #setAllowedCrossTaskNavigations(Set)} has
+ * been called.
+ *
+ * @throws IllegalArgumentException if {@link #setAllowedCrossTaskNavigations(Set)} has
+ * been called.
+ *
+ * @param blockedCrossTaskNavigations A set of tasks {@link ComponentName} to be
+ * blocked from navigating to new tasks in the virtual device.
+ */
+ @NonNull
+ public Builder setBlockedCrossTaskNavigations(
+ @NonNull Set<ComponentName> blockedCrossTaskNavigations) {
+ Preconditions.checkNotNull(blockedCrossTaskNavigations);
+ if (mDefaultNavigationPolicyConfigured
+ && mDefaultNavigationPolicy != NAVIGATION_POLICY_DEFAULT_ALLOWED) {
+ throw new IllegalArgumentException(
+ "Allowed cross task navigation and blocked task navigation cannot "
+ + " be set.");
+ }
+ mDefaultNavigationPolicy = NAVIGATION_POLICY_DEFAULT_ALLOWED;
+ mDefaultNavigationPolicyConfigured = true;
+ mBlockedCrossTaskNavigations = blockedCrossTaskNavigations;
+ return this;
+ }
+
+ /**
* Sets the activities allowed to be launched in the virtual device. Calling this method
* will cause {@link #getDefaultActivityPolicy()} to be
* {@link #ACTIVITY_POLICY_DEFAULT_BLOCKED}, meaning activities not in
@@ -349,6 +501,9 @@
return new VirtualDeviceParams(
mLockState,
mUsersWithMatchingAccounts,
+ mAllowedCrossTaskNavigations,
+ mBlockedCrossTaskNavigations,
+ mDefaultNavigationPolicy,
mAllowedActivities,
mBlockedActivities,
mDefaultActivityPolicy);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 450e09a..236c244 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -419,8 +419,8 @@
public @interface FileLocation{}
/**
- * The installer did not call SessionParams#setPackageSource(int) to specify the package
- * source.
+ * The installer did not call {@link PackageInstaller.SessionParams#setPackageSource(int)} to
+ * specify the package source.
*/
public static final int PACKAGE_SOURCE_UNSPECIFIED = 0;
@@ -444,8 +444,8 @@
/**
* Code indicating that the package being installed comes from a file that was downloaded to
- * the device by the user. For use in place of PACKAGE_SOURCE_LOCAL_FILE when the installer
- * knows the package was downloaded.
+ * the device by the user. For use in place of {@link #PACKAGE_SOURCE_LOCAL_FILE} when the
+ * installer knows the package was downloaded.
*/
public static final int PACKAGE_SOURCE_DOWNLOADED_FILE = 4;
@@ -1984,7 +1984,13 @@
}
/**
- * Sets the apk package installation source.
+ * Optionally indicate the package source of the app being installed. This is
+ * informational and may be used as a signal by the system.
+ *
+ * An installer should specify {@link #PACKAGE_SOURCE_OTHER} if no other package source
+ * constant adequately reflects the source for this session.
+ *
+ * The default value is {@link #PACKAGE_SOURCE_UNSPECIFIED}.
*/
public void setPackageSource(@PackageSourceType int packageSource) {
this.packageSource = packageSource;
@@ -2302,8 +2308,14 @@
*
* <ul>
* <li>{@code requireUserAction} is set to {@link #USER_ACTION_NOT_REQUIRED}.</li>
- * <li>The app being installed targets {@link android.os.Build.VERSION_CODES#Q API 29}
- * or higher.</li>
+ * <li>The app being installed targets:
+ * <ul>
+ * <li>{@link android.os.Build.VERSION_CODES#Q API 29} or higher on
+ * Android S ({@link android.os.Build.VERSION_CODES#S API 31})</li>
+ * <li>{@link android.os.Build.VERSION_CODES#R API 30} or higher after
+ * Android S ({@link android.os.Build.VERSION_CODES#S API 31})</li>
+ * </ul>
+ * </li>
* <li>The installer is the {@link InstallSourceInfo#getInstallingPackageName()
* installer of record} of an existing version of the app (in other words, this install
* session is an app update) or the installer is updating itself.</li>
@@ -2991,7 +3003,8 @@
}
/**
- * Gets the apk package installation source.
+ * Get the package source that was set in
+ * {@link PackageInstaller.SessionParams#setPackageSource(int)}.
*/
public @PackageSourceType int getPackageSource() {
return packageSource;
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 56d092d..52774e3 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -2241,10 +2241,20 @@
}
/**
- * Return true if the shortcut is included in specified surface.
+ * Return true if the shortcut is excluded from specified surface.
*/
- public boolean isIncludedIn(@Surface int surface) {
- return (mExcludedSurfaces & surface) == 0;
+ public boolean isExcludedFromSurfaces(@Surface int surface) {
+ return (mExcludedSurfaces & surface) != 0;
+ }
+
+ /**
+ * Returns a bitmask of all surfaces this shortcut is excluded from.
+ *
+ * @see ShortcutInfo.Builder#setExcludedFromSurfaces(int)
+ */
+ @Surface
+ public int getExcludedFromSurfaces() {
+ return mExcludedSurfaces;
}
/**
@@ -2543,7 +2553,7 @@
if (isLongLived()) {
sb.append("Liv");
}
- if (!isIncludedIn(SURFACE_LAUNCHER)) {
+ if (isExcludedFromSurfaces(SURFACE_LAUNCHER)) {
sb.append("Hid-L");
}
sb.append("]");
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 6972875..6b540d7 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -1486,6 +1486,10 @@
}
}
+ // Only warn once for assuming that root or system UID has a permission
+ // to reduce duplicate logcat output.
+ private static volatile boolean sShouldWarnMissingActivityManager = true;
+
/* @hide */
private static int checkPermissionUncached(@Nullable String permission, int pid, int uid) {
final IActivityManager am = ActivityManager.getService();
@@ -1495,8 +1499,11 @@
// permission this is.
final int appId = UserHandle.getAppId(uid);
if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
- Slog.w(LOG_TAG, "Missing ActivityManager; assuming " + uid + " holds "
- + permission);
+ if (sShouldWarnMissingActivityManager) {
+ Slog.w(LOG_TAG, "Missing ActivityManager; assuming " + uid + " holds "
+ + permission);
+ sShouldWarnMissingActivityManager = false;
+ }
return PackageManager.PERMISSION_GRANTED;
}
Slog.w(LOG_TAG, "Missing ActivityManager; assuming " + uid + " does not hold "
@@ -1504,6 +1511,7 @@
return PackageManager.PERMISSION_DENIED;
}
try {
+ sShouldWarnMissingActivityManager = true;
return am.checkPermission(permission, pid, uid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5191c95..6e65817 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -78,6 +78,7 @@
import android.os.ServiceManager;
import android.os.UserHandle;
import android.speech.tts.TextToSpeech;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.AndroidException;
import android.util.ArrayMap;
@@ -86,6 +87,7 @@
import android.util.MemoryIntArray;
import android.view.Display;
import android.view.MotionEvent;
+import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import android.widget.Editor;
@@ -7477,6 +7479,16 @@
"accessibility_shortcut_dialog_shown";
/**
+ * Setting specifying if the timeout restriction
+ * {@link ViewConfiguration#getAccessibilityShortcutKeyTimeout()}
+ * of the accessibility shortcut dialog is skipped.
+ *
+ * @hide
+ */
+ public static final String SKIP_ACCESSIBILITY_SHORTCUT_DIALOG_TIMEOUT_RESTRICTION =
+ "skip_accessibility_shortcut_dialog_timeout_restriction";
+
+ /**
* Setting specifying the accessibility services, accessibility shortcut targets,
* or features to be toggled via the accessibility shortcut.
*
@@ -11305,8 +11317,9 @@
/**
* Whether or not data roaming is enabled. (0 = false, 1 = true)
+ * Use {@link TelephonyManager#isDataRoamingEnabled} instead of calling via settings.
*/
- @Readable
+ @Readable(maxTargetSdk = Build.VERSION_CODES.S)
public static final String DATA_ROAMING = "data_roaming";
/**
@@ -11469,6 +11482,15 @@
public static final String DEVICE_PROVISIONED = "device_provisioned";
/**
+ * Whether bypassing the device policy management role holder qualifcation is allowed,
+ * (0 = false, 1 = true).
+ *
+ * @hide
+ */
+ public static final String BYPASS_DEVICE_POLICY_MANAGEMENT_ROLE_QUALIFICATIONS =
+ "bypass_device_policy_management_role_qualifications";
+
+ /**
* Indicates whether mobile data should be allowed while the device is being provisioned.
* This allows the provisioning process to turn off mobile data before the user
* has an opportunity to set things up, preventing other processes from burning
diff --git a/core/java/android/security/keystore/recovery/WrappedApplicationKey.java b/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
index 0cb69a4..61fd041 100644
--- a/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
+++ b/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
@@ -167,10 +167,7 @@
protected WrappedApplicationKey(Parcel in) {
mAlias = in.readString();
mEncryptedKeyMaterial = in.createByteArray();
- // Check if there is still data to be read.
- if (in.dataAvail() > 0) {
- mMetadata = in.createByteArray();
- }
+ mMetadata = in.createByteArray();
}
@Override
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index b701e07..e9f099a 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -876,7 +876,7 @@
* if (filter != null) {
* fieldBuilder.setFilter(filter);
* }
- * Presentations.Builder presentationsBuilder = new Presentations.Builder(id);
+ * Presentations.Builder presentationsBuilder = new Presentations.Builder();
* if (presentation != null) {
* presentationsBuilder.setMenuPresentation(presentation);
* }
diff --git a/core/java/android/service/autofill/Field.java b/core/java/android/service/autofill/Field.java
index 8c905a6..d63cf33 100644
--- a/core/java/android/service/autofill/Field.java
+++ b/core/java/android/service/autofill/Field.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
import com.android.internal.util.DataClass;
@@ -26,10 +25,9 @@
import java.util.regex.Pattern;
/**
- * This class is used to set all information of a field. Such as the
- * {@link AutofillId} of the field, the {@link AutofillValue} to be autofilled,
- * a <a href="#Filtering">explicit filter</a>, and presentations to be visualized,
- * etc.
+ * This class is used to set all information of a field. Such as the {@link AutofillValue}
+ * to be autofilled, a <a href="#Filtering">explicit filter</a>, and presentations to be
+ * visualized, etc.
*/
public final class Field {
diff --git a/core/java/android/service/games/GameSessionTrampolineActivity.java b/core/java/android/service/games/GameSessionTrampolineActivity.java
index ddea098..3d97d0f 100644
--- a/core/java/android/service/games/GameSessionTrampolineActivity.java
+++ b/core/java/android/service/games/GameSessionTrampolineActivity.java
@@ -51,7 +51,6 @@
startActivityAsCaller(
getIntent().getParcelableExtra(INTENT_KEY),
getIntent().getBundleExtra(OPTIONS_KEY),
- null,
false,
getUserId(),
REQUEST_CODE);
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
index 38659e1..091bf79 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
@@ -42,7 +42,19 @@
*/
@NonNull
static QuickAccessWalletClient create(@NonNull Context context) {
- return new QuickAccessWalletClientImpl(context);
+ return create(context, null /* bgExecutor */);
+ }
+
+ /**
+ * Create a client for accessing wallet cards from the {@link QuickAccessWalletService}. If the
+ * service is unavailable, {@link #isWalletServiceAvailable()} will return false.
+ * @param context Context.
+ * @param bgExecutor A background {@link Executor} for service registration.
+ * @hide
+ */
+ @NonNull
+ static QuickAccessWalletClient create(@NonNull Context context, @Nullable Executor bgExecutor) {
+ return new QuickAccessWalletClientImpl(context, bgExecutor);
}
/**
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
index 95b51ea..a3304a9 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
@@ -67,6 +67,7 @@
private final Context mContext;
private final Queue<ApiCaller> mRequestQueue;
private final Map<WalletServiceEventListener, String> mEventListeners;
+ private final Executor mLifecycleExecutor;
private boolean mIsConnected;
/** Timeout for active service connections (1 minute) */
private static final long SERVICE_CONNECTION_TIMEOUT_MS = 60 * 1000;
@@ -79,10 +80,11 @@
private static final int MSG_TIMEOUT_SERVICE = 5;
- QuickAccessWalletClientImpl(@NonNull Context context) {
+ QuickAccessWalletClientImpl(@NonNull Context context, @Nullable Executor bgExecutor) {
mContext = context.getApplicationContext();
mServiceInfo = QuickAccessWalletServiceInfo.tryCreate(context);
mHandler = new Handler(Looper.getMainLooper());
+ mLifecycleExecutor = (bgExecutor == null) ? Runnable::run : bgExecutor;
mRequestQueue = new LinkedList<>();
mEventListeners = new HashMap<>(1);
}
@@ -369,7 +371,7 @@
Intent intent = new Intent(SERVICE_INTERFACE);
intent.setComponent(mServiceInfo.getComponentName());
int flags = Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY;
- mContext.bindService(intent, this, flags);
+ mLifecycleExecutor.execute(() -> mContext.bindService(intent, this, flags));
resetServiceConnectionTimeout();
}
@@ -411,7 +413,7 @@
return;
}
mIsConnected = false;
- mContext.unbindService(/*conn=*/ this);
+ mLifecycleExecutor.execute(() -> mContext.unbindService(/*conn=*/ this));
mService = null;
mEventListeners.clear();
mRequestQueue.clear();
diff --git a/core/java/android/service/trust/GrantTrustResult.java b/core/java/android/service/trust/GrantTrustResult.java
index 7cf708a..5b06bb8 100644
--- a/core/java/android/service/trust/GrantTrustResult.java
+++ b/core/java/android/service/trust/GrantTrustResult.java
@@ -32,7 +32,7 @@
*
* @hide
*/
-@DataClass(genHiddenConstructor = true)
+@DataClass
@SystemApi
public final class GrantTrustResult implements Parcelable {
@@ -42,15 +42,10 @@
/** The device went from locked to unlocked as a result of the call. */
public static final int STATUS_UNLOCKED_BY_GRANT = 1;
+ /** The status code of the result. */
@Status
private int mStatus;
- /** Returns a new {@link GrantTrustResult} with the specified status. */
- @NonNull
- public static GrantTrustResult withStatus(@Status int status) {
- return new GrantTrustResult(status);
- }
-
// Code below generated by codegen v1.0.23.
@@ -90,7 +85,8 @@
/**
* Creates a new GrantTrustResult.
*
- * @hide
+ * @param status
+ * The status code of the result.
*/
@DataClass.Generated.Member
public GrantTrustResult(
@@ -109,6 +105,9 @@
// onConstructed(); // You can define this method to get a callback
}
+ /**
+ * The status code of the result.
+ */
@DataClass.Generated.Member
public @Status int getStatus() {
return mStatus;
@@ -165,10 +164,10 @@
};
@DataClass.Generated(
- time = 1647878197834L,
+ time = 1648138312806L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/service/trust/GrantTrustResult.java",
- inputSignatures = "public static final int STATUS_UNKNOWN\npublic static final int STATUS_UNLOCKED_BY_GRANT\nprivate @android.service.trust.GrantTrustResult.Status int mStatus\npublic static @android.annotation.NonNull android.service.trust.GrantTrustResult withStatus(int)\nclass GrantTrustResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
+ inputSignatures = "public static final int STATUS_UNKNOWN\npublic static final int STATUS_UNLOCKED_BY_GRANT\nprivate @android.service.trust.GrantTrustResult.Status int mStatus\nclass GrantTrustResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 3174083..dd0ac2e 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -24,6 +24,7 @@
import static android.graphics.Matrix.MSKEW_Y;
import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
import static android.view.View.SYSTEM_UI_FLAG_VISIBLE;
+import static android.view.ViewRootImpl.LOCAL_LAYOUT;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import android.animation.Animator;
@@ -39,6 +40,7 @@
import android.app.WallpaperColors;
import android.app.WallpaperInfo;
import android.app.WallpaperManager;
+import android.app.WindowConfiguration;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.Intent;
@@ -257,6 +259,8 @@
private final Point mLastSurfaceSize = new Point();
private final Matrix mTmpMatrix = new Matrix();
private final float[] mTmpValues = new float[9];
+ private final WindowLayout mWindowLayout = new WindowLayout();
+ private final Rect mTempRect = new Rect();
final WindowManager.LayoutParams mLayout
= new WindowManager.LayoutParams();
@@ -391,8 +395,9 @@
final BaseIWindow mWindow = new BaseIWindow() {
@Override
public void resized(ClientWindowFrames frames, boolean reportDraw,
- MergedConfiguration mergedConfiguration, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId, int syncSeqId, int resizeMode) {
+ MergedConfiguration mergedConfiguration, InsetsState insetsState,
+ boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId,
+ int syncSeqId, int resizeMode) {
Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED,
reportDraw ? 1 : 0,
mergedConfiguration);
@@ -1091,7 +1096,8 @@
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
final Configuration config = mMergedConfiguration.getMergedConfiguration();
- final Rect maxBounds = config.windowConfiguration.getMaxBounds();
+ final WindowConfiguration winConfig = config.windowConfiguration;
+ final Rect maxBounds = winConfig.getMaxBounds();
if (myWidth == ViewGroup.LayoutParams.MATCH_PARENT
&& myHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
mLayout.width = myWidth;
@@ -1149,10 +1155,28 @@
mLayout.surfaceInsets.set(0, 0, 0, 0);
}
- final int relayoutResult = mSession.relayout(
- mWindow, mLayout, mWidth, mHeight,
- View.VISIBLE, 0, mWinFrames, mMergedConfiguration, mSurfaceControl,
- mInsetsState, mTempControls, mSyncSeqIdBundle);
+ int relayoutResult = 0;
+ if (LOCAL_LAYOUT) {
+ if (!mSurfaceControl.isValid()) {
+ relayoutResult = mSession.updateVisibility(mWindow, mLayout,
+ View.VISIBLE, mMergedConfiguration, mSurfaceControl,
+ mInsetsState, mTempControls);
+ }
+
+ final Rect displayCutoutSafe = mTempRect;
+ mInsetsState.getDisplayCutoutSafe(displayCutoutSafe);
+ mWindowLayout.computeFrames(mLayout, mInsetsState, displayCutoutSafe,
+ winConfig.getBounds(), winConfig.getWindowingMode(), mWidth,
+ mHeight, mRequestedVisibilities, null /* attachedWindowFrame */,
+ 1f /* compatScale */, mWinFrames);
+
+ mSession.updateLayout(mWindow, mLayout, 0 /* flags */, mWinFrames, mWidth,
+ mHeight);
+ } else {
+ relayoutResult = mSession.relayout(mWindow, mLayout, mWidth, mHeight,
+ View.VISIBLE, 0, mWinFrames, mMergedConfiguration,
+ mSurfaceControl, mInsetsState, mTempControls, mSyncSeqIdBundle);
+ }
final int transformHint = SurfaceControl.rotationToBufferTransform(
(mDisplayInstallOrientation + mDisplay.getRotation()) % 4);
@@ -1202,7 +1226,7 @@
null /* ignoringVisibilityState */, config.isScreenRound(),
false /* alwaysConsumeSystemBars */, mLayout.softInputMode,
mLayout.flags, SYSTEM_UI_FLAG_VISIBLE, mLayout.type,
- config.windowConfiguration.getWindowingMode(), null /* typeSideMap */);
+ winConfig.getWindowingMode(), null /* typeSideMap */);
if (!fixedSize) {
final Rect padding = mIWallpaperEngine.mDisplayPadding;
diff --git a/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java b/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java
index 18b654e..2898149 100644
--- a/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java
+++ b/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java
@@ -19,6 +19,7 @@
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import android.annotation.CallSuper;
+import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.Service;
@@ -69,7 +70,6 @@
* {@link android.permission#MANAGE_WALLPAPER_EFFECTS_GENERATION}
* permission.
*
- * @hide
*/
public static final String SERVICE_INTERFACE =
"android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService";
@@ -97,6 +97,7 @@
*
* @param request the cinematic effect request passed from the client.
*/
+ @MainThread
public abstract void onGenerateCinematicEffect(@NonNull CinematicEffectRequest request);
/**
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index f844592..a3696e3 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -38,7 +38,6 @@
import android.telephony.Annotation.SimActivationState;
import android.telephony.Annotation.SrvccState;
import android.telephony.TelephonyManager.CarrierPrivilegesCallback;
-import android.telephony.TelephonyManager.CarrierPrivilegesListener;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo;
import android.util.ArraySet;
@@ -1264,149 +1263,52 @@
pkgName, attributionTag, callback, new int[0], notifyNow);
}
- // TODO(b/216549778): Remove listener logic once all clients switch to CarrierPrivilegesCallback
private static class CarrierPrivilegesCallbackWrapper extends ICarrierPrivilegesCallback.Stub
implements ListenerExecutor {
- // Either mListener or mCallback may be null, never both
- @Nullable private final WeakReference<CarrierPrivilegesListener> mListener;
- @Nullable private final WeakReference<CarrierPrivilegesCallback> mCallback;
+ @NonNull private final WeakReference<CarrierPrivilegesCallback> mCallback;
@NonNull private final Executor mExecutor;
CarrierPrivilegesCallbackWrapper(
@NonNull CarrierPrivilegesCallback callback, @NonNull Executor executor) {
- mListener = null;
mCallback = new WeakReference<>(callback);
mExecutor = executor;
}
- CarrierPrivilegesCallbackWrapper(
- @NonNull CarrierPrivilegesListener listener, @NonNull Executor executor) {
- mListener = new WeakReference<>(listener);
- mCallback = null;
- mExecutor = executor;
- }
-
@Override
public void onCarrierPrivilegesChanged(
@NonNull List<String> privilegedPackageNames, @NonNull int[] privilegedUids) {
- if (mListener != null) {
- Binder.withCleanCallingIdentity(
- () ->
- executeSafely(
- mExecutor,
- mListener::get,
- cpl ->
- cpl.onCarrierPrivilegesChanged(
- privilegedPackageNames, privilegedUids)));
- }
-
- if (mCallback != null) {
- // AIDL interface does not support Set, keep the List/Array and translate them here
- Set<String> privilegedPkgNamesSet = Set.copyOf(privilegedPackageNames);
- Set<Integer> privilegedUidsSet = Arrays.stream(privilegedUids).boxed().collect(
- Collectors.toSet());
- Binder.withCleanCallingIdentity(
- () ->
- executeSafely(
- mExecutor,
- mCallback::get,
- cpc ->
- cpc.onCarrierPrivilegesChanged(
- privilegedPkgNamesSet, privilegedUidsSet)));
- }
+ // AIDL interface does not support Set, keep the List/Array and translate them here
+ Set<String> privilegedPkgNamesSet = Set.copyOf(privilegedPackageNames);
+ Set<Integer> privilegedUidsSet = Arrays.stream(privilegedUids).boxed().collect(
+ Collectors.toSet());
+ Binder.withCleanCallingIdentity(
+ () ->
+ executeSafely(
+ mExecutor,
+ mCallback::get,
+ cpc ->
+ cpc.onCarrierPrivilegesChanged(
+ privilegedPkgNamesSet, privilegedUidsSet)));
}
@Override
public void onCarrierServiceChanged(@Nullable String packageName, int uid) {
- if (mCallback != null) {
- Binder.withCleanCallingIdentity(
- () ->
- executeSafely(
- mExecutor,
- mCallback::get,
- cpc -> cpc.onCarrierServiceChanged(packageName, uid)));
- }
+ Binder.withCleanCallingIdentity(
+ () ->
+ executeSafely(
+ mExecutor,
+ mCallback::get,
+ cpc -> cpc.onCarrierServiceChanged(packageName, uid)));
}
}
- // TODO(b/216549778): Change the map key to CarrierPrivilegesCallback once all clients switch to
- // CarrierPrivilegesCallback. Before that, the key is either CarrierPrivilegesCallback or
- // CarrierPrivilegesListener, no logic actually depends on the type.
@NonNull
@GuardedBy("sCarrierPrivilegeCallbacks")
- private static final WeakHashMap<Object, WeakReference<CarrierPrivilegesCallbackWrapper>>
+ private static final WeakHashMap<CarrierPrivilegesCallback,
+ WeakReference<CarrierPrivilegesCallbackWrapper>>
sCarrierPrivilegeCallbacks = new WeakHashMap<>();
/**
- * Registers a {@link CarrierPrivilegesListener} on the given {@code logicalSlotIndex} to
- * receive callbacks when the set of packages with carrier privileges changes. The callback will
- * immediately be called with the latest state.
- *
- * @param logicalSlotIndex The SIM slot to listen on
- * @param executor The executor where {@code listener} will be invoked
- * @param listener The callback to register
- *
- * @deprecated Use {@link #addCarrierPrivilegesCallback} instead. This API will be removed
- * prior to API finalization.
- */
- @Deprecated
- public void addCarrierPrivilegesListener(
- int logicalSlotIndex,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull CarrierPrivilegesListener listener) {
- if (listener == null || executor == null) {
- throw new IllegalArgumentException("listener and executor must be non-null");
- }
- synchronized (sCarrierPrivilegeCallbacks) {
- WeakReference<CarrierPrivilegesCallbackWrapper> existing =
- sCarrierPrivilegeCallbacks.get(listener);
- if (existing != null && existing.get() != null) {
- Log.d(TAG, "addCarrierPrivilegesListener: listener already registered");
- return;
- }
- CarrierPrivilegesCallbackWrapper wrapper =
- new CarrierPrivilegesCallbackWrapper(listener, executor);
- sCarrierPrivilegeCallbacks.put(listener, new WeakReference<>(wrapper));
- try {
- sRegistry.addCarrierPrivilegesCallback(
- logicalSlotIndex,
- wrapper,
- mContext.getOpPackageName(),
- mContext.getAttributionTag());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
- /**
- * Unregisters a {@link CarrierPrivilegesListener}.
- *
- * @param listener The callback to unregister
- *
- * @deprecated Use {@link #removeCarrierPrivilegesCallback} instead. The callback will prior
- * to API finalization.
- */
- @Deprecated
- public void removeCarrierPrivilegesListener(@NonNull CarrierPrivilegesListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("listener must be non-null");
- }
- synchronized (sCarrierPrivilegeCallbacks) {
- WeakReference<CarrierPrivilegesCallbackWrapper> ref =
- sCarrierPrivilegeCallbacks.remove(listener);
- if (ref == null) return;
- CarrierPrivilegesCallbackWrapper wrapper = ref.get();
- if (wrapper == null) return;
- try {
- sRegistry.removeCarrierPrivilegesCallback(wrapper, mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
- /**
* Registers a {@link CarrierPrivilegesCallback} on the given {@code logicalSlotIndex} to
* receive callbacks when the set of packages with carrier privileges changes. The callback will
* immediately be called with the latest state.
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 5dcf393..a856474 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -54,26 +54,14 @@
void executeCommand(String command, String parameters, in ParcelFileDescriptor descriptor);
void resized(in ClientWindowFrames frames, boolean reportDraw,
- in MergedConfiguration newMergedConfiguration,
+ in MergedConfiguration newMergedConfiguration, in InsetsState insetsState,
boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId,
int syncSeqId, int resizeMode);
/**
- * Called when the window insets configuration has changed.
- *
- * @param willMove The window frame will be moved soon.
- * @param willResize The window frame will be resized soon.
- */
- void insetsChanged(in InsetsState insetsState, in boolean willMove, in boolean willResize);
-
- /**
* Called when this window retrieved control over a specified set of insets sources.
- *
- * @param willMove The window frame will be moved soon.
- * @param willResize The window frame will be resized soon.
*/
- void insetsControlChanged(in InsetsState insetsState, in InsetsSourceControl[] activeControls,
- in boolean willMove, in boolean willResize);
+ void insetsControlChanged(in InsetsState insetsState, in InsetsSourceControl[] activeControls);
/**
* Called when a set of insets source window should be shown by policy.
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index fd86900..7098602 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -107,6 +107,41 @@
out InsetsState insetsState, out InsetsSourceControl[] activeControls,
out Bundle bundle);
+ /**
+ * Changes the view visibility and the attributes of a window. This should only be called when
+ * the visibility of the root view is changed. This returns a valid surface if the root view is
+ * visible. This also returns the latest information for the caller to compute its window frame.
+ *
+ * @param window The window being updated.
+ * @param attrs If non-null, new attributes to apply to the window.
+ * @param viewVisibility Window root view's visibility.
+ * @param outMergedConfiguration New config container that holds global, override and merged
+ * config for window, if it is now becoming visible and the merged configuration has changed
+ * since it was last displayed.
+ * @param outSurfaceControl Object in which is placed the new display surface.
+ * @param outInsetsState The current insets state in the system.
+ * @param outActiveControls The insets source controls for the caller to override the insets
+ * state in the system.
+ *
+ * @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_FIRST_TIME}.
+ */
+ int updateVisibility(IWindow window, in WindowManager.LayoutParams attrs, int viewVisibility,
+ out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl,
+ out InsetsState outInsetsState, out InsetsSourceControl[] outActiveControls);
+
+ /**
+ * Reports the layout results and the attributes of a window to the server.
+ *
+ * @param window The window being reported.
+ * @param attrs If non-null, new attributes to apply to the window.
+ * @param flags Request flags: {@link WindowManagerGlobal#RELAYOUT_INSETS_PENDING}.
+ * @param clientFrames the window frames computed by the client.
+ * @param requestedWidth The width the window wants to be.
+ * @param requestedHeight The height the window wants to be.
+ */
+ oneway void updateLayout(IWindow window, in WindowManager.LayoutParams attrs, int flags,
+ in ClientWindowFrames clientFrames, int requestedWidth, int requestedHeight);
+
/*
* Notify the window manager that an application is relaunching and
* windows should be prepared for replacement.
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index a13579d..406281d 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -401,7 +401,7 @@
public void relayout(WindowManager.LayoutParams attrs,
WindowlessWindowManager.ResizeCompleteCallback callback) {
mViewRoot.setLayoutParams(attrs, false);
- mViewRoot.setReportNextDraw();
+ mViewRoot.setReportNextDraw(true /* syncBuffer */);
mWm.setCompletionCallback(mViewRoot.mWindow.asBinder(), callback);
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 4138556..c04b096 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -50,6 +50,7 @@
import com.android.internal.view.SurfaceCallbackHelper;
import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
@@ -203,8 +204,6 @@
private int mSurfaceFlags = SurfaceControl.HIDDEN;
- private int mPendingReportDraws;
-
/**
* Transaction that should be used from the render thread. This transaction is only thread safe
* with other calls directly from the render thread.
@@ -212,11 +211,6 @@
private final SurfaceControl.Transaction mRtTransaction = new SurfaceControl.Transaction();
/**
- * Used on the main thread to set the transaction that will be synced with the main window.
- */
- private final Transaction mSyncTransaction = new Transaction();
-
- /**
* Transaction that should be used whe
* {@link HardwareRenderer.FrameDrawingCallback#onFrameDraw} is invoked. All
* frame callbacks can use the same transaction since they will be thread safe
@@ -391,31 +385,12 @@
}
}
- private void performDrawFinished(@Nullable Transaction t) {
- if (t != null) {
- mSyncTransaction.merge(t);
+ private void performDrawFinished() {
+ mDrawFinished = true;
+ if (mAttachedToWindow) {
+ mParent.requestTransparentRegion(SurfaceView.this);
+ invalidate();
}
-
- if (mPendingReportDraws > 0) {
- mDrawFinished = true;
- if (mAttachedToWindow) {
- mParent.requestTransparentRegion(SurfaceView.this);
- notifyDrawFinished();
- invalidate();
- }
- } else {
- Log.e(TAG, System.identityHashCode(this) + "finished drawing"
- + " but no pending report draw (extra call"
- + " to draw completion runnable?)");
- }
- }
-
- void notifyDrawFinished() {
- ViewRootImpl viewRoot = getViewRootImpl();
- if (viewRoot != null) {
- viewRoot.pendingDrawFinished(mSyncTransaction);
- }
- mPendingReportDraws--;
}
@Override
@@ -438,10 +413,6 @@
mGlobalListenersAdded = false;
}
- while (mPendingReportDraws > 0) {
- notifyDrawFinished();
- }
-
mRequestedVisible = false;
updateSurface();
@@ -993,10 +964,17 @@
return;
}
- final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
- translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction);
final boolean redrawNeeded = sizeChanged || creating || hintChanged
|| (mVisible && !mDrawFinished);
+ final TransactionCallback transactionCallback =
+ redrawNeeded ? new TransactionCallback() : null;
+ if (redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInSync()) {
+ mBlastBufferQueue.syncNextTransaction(
+ false /* acquireSingleBuffer */,
+ transactionCallback::onTransactionReady);
+ }
+ final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
+ translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction);
try {
SurfaceHolder.Callback[] callbacks = null;
@@ -1015,9 +993,7 @@
mIsCreating = true;
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ "visibleChanged -- surfaceCreated");
- if (callbacks == null) {
- callbacks = getSurfaceCallbacks();
- }
+ callbacks = getSurfaceCallbacks();
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceCreated(mSurfaceHolder);
}
@@ -1035,32 +1011,7 @@
}
}
if (redrawNeeded) {
- if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
- + "surfaceRedrawNeeded");
- if (callbacks == null) {
- callbacks = getSurfaceCallbacks();
- }
-
- final boolean wasRelayoutRequested = viewRoot.wasRelayoutRequested();
- if (wasRelayoutRequested && (mBlastBufferQueue != null)) {
- mBlastBufferQueue.syncNextTransaction(
- false /* acquireSingleBuffer */,
- this::onDrawFinished);
- }
- mPendingReportDraws++;
- viewRoot.drawPending();
- SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() -> {
- if (mBlastBufferQueue != null) {
- mBlastBufferQueue.stopContinuousSyncTransaction();
- }
- // If relayout was requested, then a callback from BBQ will
- // be invoked with the sync transaction. onDrawFinished will be
- // called in there
- if (!wasRelayoutRequested) {
- onDrawFinished(null);
- }
- });
- sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
+ redrawNeeded(callbacks, transactionCallback);
}
}
} finally {
@@ -1079,6 +1030,64 @@
}
}
+ private void redrawNeeded(SurfaceHolder.Callback[] callbacks,
+ @Nullable TransactionCallback transactionCallback) {
+ if (DEBUG) {
+ Log.i(TAG, System.identityHashCode(this) + " surfaceRedrawNeeded");
+ }
+ final SurfaceHolder.Callback[] capturedCallbacks =
+ callbacks == null ? getSurfaceCallbacks() : callbacks;
+
+ ViewRootImpl viewRoot = getViewRootImpl();
+ boolean isVriSync = viewRoot.addToSync(syncBufferCallback ->
+ redrawNeededAsync(capturedCallbacks, () -> {
+ if (mBlastBufferQueue != null) {
+ mBlastBufferQueue.stopContinuousSyncTransaction();
+ }
+
+ Transaction t = null;
+ if (transactionCallback != null && mBlastBufferQueue != null) {
+ t = transactionCallback.waitForTransaction();
+ }
+ // If relayout was requested, then a callback from BBQ will
+ // be invoked with the sync transaction. onDrawFinished will be
+ // called in there
+ syncBufferCallback.onBufferReady(t);
+ onDrawFinished();
+ }));
+
+ // If isVriSync, then everything was setup in the addToSync.
+ if (isVriSync) {
+ return;
+ }
+
+ redrawNeededAsync(capturedCallbacks, this::onDrawFinished);
+ }
+
+ private void redrawNeededAsync(SurfaceHolder.Callback[] callbacks,
+ Runnable callbacksCollected) {
+ SurfaceCallbackHelper sch = new SurfaceCallbackHelper(callbacksCollected);
+ sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
+ }
+
+ private static class TransactionCallback {
+ private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
+ private Transaction mTransaction;
+
+ Transaction waitForTransaction() {
+ try {
+ mCountDownLatch.await();
+ } catch (InterruptedException e) {
+ }
+ return mTransaction;
+ }
+
+ void onTransactionReady(Transaction t) {
+ mTransaction = t;
+ mCountDownLatch.countDown();
+ }
+ }
+
/**
* Copy the Surface from the SurfaceControl or the blast adapter.
*
@@ -1189,13 +1198,13 @@
mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
}
- private void onDrawFinished(@Nullable Transaction t) {
+ private void onDrawFinished() {
if (DEBUG) {
Log.i(TAG, System.identityHashCode(this) + " "
+ "finishedDrawing");
}
- runOnUiThread(() -> performDrawFinished(t));
+ runOnUiThread(this::performDrawFinished);
}
/**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index febd2e2..7d823b1 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -11939,13 +11939,22 @@
@NonNull
List<Rect> collectPreferKeepClearRects() {
ListenerInfo info = mListenerInfo;
- final List<Rect> list = new ArrayList<>();
+ boolean keepBoundsClear =
+ (info != null && info.mPreferKeepClear) || mPreferKeepClearForFocus;
+ boolean hasCustomKeepClearRects = info != null && info.mKeepClearRects != null;
- if ((info != null && info.mPreferKeepClear) || mPreferKeepClearForFocus) {
+ if (!keepBoundsClear && !hasCustomKeepClearRects) {
+ return Collections.emptyList();
+ } else if (keepBoundsClear && !hasCustomKeepClearRects) {
+ return Collections.singletonList(new Rect(0, 0, getWidth(), getHeight()));
+ }
+
+ final List<Rect> list = new ArrayList<>();
+ if (keepBoundsClear) {
list.add(new Rect(0, 0, getWidth(), getHeight()));
}
- if (info != null && info.mKeepClearRects != null) {
+ if (hasCustomKeepClearRects) {
list.addAll(info.mKeepClearRects);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 172cd03..0df8a0b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -78,11 +78,13 @@
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
+import static android.view.WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER;
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INSETS_CONTROLLER;
@@ -226,7 +228,6 @@
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
-import java.util.function.Consumer;
/**
* The top of a view hierarchy, implementing the needed protocol between View
@@ -279,6 +280,13 @@
public static final boolean CAPTION_ON_SHELL = false;
/**
+ * Whether the client should compute the window frame on its own.
+ * @hide
+ */
+ public static final boolean LOCAL_LAYOUT =
+ SystemProperties.getBoolean("persist.debug.local_layout", false);
+
+ /**
* Set this system property to true to force the view hierarchy to render
* at 60 Hz. This can be used to measure the potential framerate.
*/
@@ -578,11 +586,16 @@
boolean mReportNextDraw;
+
/**
- * Set whether the draw should use blast sync. This is in case the draw is canceled,
- * but will be rescheduled. We still want the next draw to be sync.
+ * Set whether the draw should send the buffer to system server. When set to true, VRI will
+ * create a sync transaction with BBQ and send the resulting buffer to system server. If false,
+ * VRI will not try to sync a buffer in BBQ, but still report when a draw occurred.
*/
- boolean mNextDrawUseBlastSync;
+ private boolean mSyncBuffer = false;
+
+ int mSyncSeqId = 0;
+ int mLastSyncSeqId = 0;
boolean mFullRedrawNeeded;
boolean mNewSurfaceNeeded;
@@ -666,9 +679,6 @@
final Rect mPendingBackDropFrame = new Rect();
- private boolean mWillMove;
- private boolean mWillResize;
-
boolean mPendingAlwaysConsumeSystemBars;
private final InsetsState mTempInsets = new InsetsState();
private final InsetsSourceControl[] mTempControls = new InsetsSourceControl[SIZE];
@@ -803,14 +813,16 @@
return mHandwritingInitiator;
}
+ private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer();
+ private int mLastSyncId = -1;
+ private SurfaceSyncer.SyncBufferCallback mSyncBufferCallback;
+
/**
* Keeps track of the last frame number that was attempted to draw. Should only be accessed on
* the RenderThread.
*/
private long mRtLastAttemptedDrawFrameNum = 0;
- private Consumer<SurfaceControl.Transaction> mBLASTDrawConsumer;
-
private HashSet<ScrollCaptureCallback> mRootScrollCaptureCallbacks;
private long mScrollCaptureRequestTimeout = SCROLL_CAPTURE_REQUEST_TIMEOUT_MILLIS;
@@ -840,8 +852,6 @@
* integer back over relayout.
*/
private Bundle mRelayoutBundle = new Bundle();
- private int mSyncSeqId = 0;
- private int mLastSyncSeqId = 0;
private String mTag = TAG;
@@ -1856,10 +1866,6 @@
void notifyInsetsChanged() {
mApplyInsetsRequested = true;
- if (mWillMove || mWillResize) {
- // The window frame will be changed soon. The following logic will be executed then.
- return;
- }
requestLayout();
// See comment for View.sForceLayoutWhenInsetsChanged
@@ -2322,10 +2328,9 @@
final int systemUiFlag = publicType == Type.statusBars()
? View.SYSTEM_UI_FLAG_FULLSCREEN
: View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
- final boolean wasVisible = (info.globalVisibility & systemUiFlag) == 0;
if (visible) {
info.globalVisibility &= ~systemUiFlag;
- if (!wasVisible && hasControl) {
+ if (hasControl && (mAttachInfo.mSystemUiVisibility & systemUiFlag) != 0) {
// The local system UI visibility can only be cleared while we have the control.
info.localChanges |= systemUiFlag;
}
@@ -2645,7 +2650,6 @@
private void performTraversals() {
// cache mView since it is used so much below...
final View host = mView;
-
if (DBG) {
System.out.println("======================================");
System.out.println("performTraversals");
@@ -2763,7 +2767,7 @@
// Execute enqueued actions on every traversal in case a detached view enqueued an action
getRunQueue().executeActions(mAttachInfo.mHandler);
- if (mApplyInsetsRequested && !(mWillMove || mWillResize)) {
+ if (mApplyInsetsRequested) {
dispatchApplyInsets(host);
}
@@ -2890,8 +2894,6 @@
mView.onSystemBarAppearanceChanged(mDispatchedSystemBarAppearance);
}
}
- final boolean wasReportNextDraw = mReportNextDraw;
- boolean useBlastSync = mNextDrawUseBlastSync;
if (mFirst || windowShouldResize || viewVisibilityChanged || params != null
|| mForceNextWindowRelayout) {
@@ -2930,9 +2932,7 @@
Log.d(mTag, "Relayout called with blastSync");
}
reportNextDraw();
- if (isHardwareEnabled()) {
- useBlastSync = true;
- }
+ mSyncBuffer = true;
}
final boolean surfaceControlChanged =
@@ -3168,7 +3168,7 @@
// done to achieve a more hermetic fix for S, but it's entirely
// possible that checking the most recent value is actually more
// correct here.
- if (!mStopped || wasReportNextDraw) {
+ if (!mStopped || mReportNextDraw) {
if (mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight()
|| dispatchApplyInsets || updatedConfiguration) {
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width,
@@ -3237,7 +3237,7 @@
prepareSurfaces();
}
- final boolean didLayout = layoutRequested && (!mStopped || wasReportNextDraw);
+ final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
boolean triggerGlobalLayoutListener = didLayout
|| mAttachInfo.mRecomputeGlobalAttributes;
if (didLayout) {
@@ -3430,51 +3430,37 @@
mImeFocusController.onTraversal(hasWindowFocus, mWindowAttributes);
- // Remember if we must report the next draw.
if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
reportNextDraw();
}
- boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;
- if (mBLASTDrawConsumer != null) {
- useBlastSync = true;
+ boolean cancelAndRedraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw();
+ if (!cancelAndRedraw) {
+ createSyncIfNeeded();
}
- if (!cancelDraw) {
+ if (!isViewVisible) {
+ if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
+ for (int i = 0; i < mPendingTransitions.size(); ++i) {
+ mPendingTransitions.get(i).endChangingAnimations();
+ }
+ mPendingTransitions.clear();
+ }
+
+ if (mSyncBufferCallback != null) {
+ mSyncBufferCallback.onBufferReady(null);
+ }
+ } else if (cancelAndRedraw) {
+ // Try again
+ scheduleTraversals();
+ } else {
if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
for (int i = 0; i < mPendingTransitions.size(); ++i) {
mPendingTransitions.get(i).startChangingAnimations();
}
mPendingTransitions.clear();
}
- performDraw(useBlastSync);
- mNextDrawUseBlastSync = false;
- } else {
- if (isViewVisible) {
- // Try again
- mNextDrawUseBlastSync = useBlastSync;
- scheduleTraversals();
- } else {
- if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
- for (int i = 0; i < mPendingTransitions.size(); ++i) {
- mPendingTransitions.get(i).endChangingAnimations();
- }
- mPendingTransitions.clear();
- }
-
- // We may never draw since it's not visible. Report back that we're finished
- // drawing.
- if (!wasReportNextDraw && mReportNextDraw) {
- mReportNextDraw = false;
- pendingDrawFinished();
- }
-
- // Make sure the consumer is not waiting if the view root was just made invisible.
- if (mBLASTDrawConsumer != null) {
- mBLASTDrawConsumer.accept(null);
- mBLASTDrawConsumer = null;
- }
- }
+ performDraw();
}
if (mAttachInfo.mContentCaptureEvents != null) {
@@ -3483,6 +3469,36 @@
mIsInTraversal = false;
mRelayoutRequested = false;
+
+ if (!cancelAndRedraw) {
+ mReportNextDraw = false;
+ mSyncBufferCallback = null;
+ mSyncBuffer = false;
+ if (mLastSyncId != -1) {
+ mSurfaceSyncer.markSyncReady(mLastSyncId);
+ mLastSyncId = -1;
+ }
+ }
+ }
+
+ private void createSyncIfNeeded() {
+ // Started a sync already or there's nothing needing to sync
+ if (mLastSyncId != -1 || !mReportNextDraw) {
+ return;
+ }
+
+ final int seqId = mSyncSeqId;
+ mLastSyncId = mSurfaceSyncer.setupSync(transaction -> {
+ // Callback will be invoked on executor thread so post to main thread.
+ mHandler.postAtFrontOfQueue(() -> {
+ mSurfaceChangedTransaction.merge(transaction);
+ reportDrawFinished(seqId);
+ });
+ });
+ if (DEBUG_BLAST) {
+ Log.d(mTag, "Setup new sync id=" + mLastSyncId);
+ }
+ mSurfaceSyncer.addToSync(mLastSyncId, mSyncTarget);
}
private void notifyContentCatpureEvents() {
@@ -4096,57 +4112,13 @@
}
}
- /**
- * A count of the number of calls to pendingDrawFinished we
- * require to notify the WM drawing is complete.
- */
- int mDrawsNeededToReport = 0;
-
- /**
- * Delay notifying WM of draw finished until
- * a balanced call to pendingDrawFinished.
- */
- void drawPending() {
- mDrawsNeededToReport++;
- }
-
- void pendingDrawFinished(Transaction t) {
- if (mDrawsNeededToReport == 0) {
- throw new RuntimeException("Unbalanced drawPending/pendingDrawFinished calls");
- }
-
- if (t != null) {
- if (DEBUG_BLAST) {
- Log.d(mTag, "Merging transaction into main window transaction");
- }
- mSurfaceChangedTransaction.merge(t);
- }
-
- mDrawsNeededToReport--;
- if (mDrawsNeededToReport == 0) {
- reportDrawFinished();
- } else if (DEBUG_BLAST) {
- Log.d(mTag, "pendingDrawFinished. Waiting on draw reported mDrawsNeededToReport="
- + mDrawsNeededToReport);
- }
- }
-
- void pendingDrawFinished() {
- pendingDrawFinished(null);
- }
-
- private void postDrawFinished() {
- mHandler.sendEmptyMessage(MSG_DRAW_FINISHED);
- }
-
- private void reportDrawFinished() {
+ private void reportDrawFinished(int seqId) {
if (DEBUG_BLAST) {
- Log.d(mTag, "reportDrawFinished");
+ Log.d(mTag, "reportDrawFinished " + Debug.getCallers(5));
}
- mDrawsNeededToReport = 0;
try {
- mWindowSession.finishDrawing(mWindow, mSurfaceChangedTransaction, Integer.MAX_VALUE);
+ mWindowSession.finishDrawing(mWindow, mSurfaceChangedTransaction, seqId);
} catch (RemoteException e) {
Log.e(mTag, "Unable to report draw finished", e);
mSurfaceChangedTransaction.apply();
@@ -4162,6 +4134,19 @@
return mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled();
}
+ boolean addToSync(SurfaceSyncer.SyncTarget syncable) {
+ if (mLastSyncId == -1) {
+ return false;
+ }
+ mSurfaceSyncer.addToSync(mLastSyncId, syncable);
+ return true;
+ }
+
+
+ public boolean isInSync() {
+ return mLastSyncId != -1;
+ }
+
private void addFrameCommitCallbackIfNeeded() {
if (!isHardwareEnabled()) {
return;
@@ -4192,188 +4177,82 @@
});
}
- private HardwareRenderer.FrameCommitCallback createFrameCommitCallbackForSync(
- boolean useBlastSync, boolean reportNextDraw, Consumer<Transaction> blastSyncConsumer) {
- return didProduceBuffer -> {
- if (DEBUG_BLAST) {
- Log.d(mTag, "Received frameCommittedCallback "
- + " lastAttemptedDrawFrameNum=" + mRtLastAttemptedDrawFrameNum
- + " didProduceBuffer=" + didProduceBuffer);
- }
-
- // If frame wasn't drawn, clear out the next transaction so it doesn't affect the next
- // draw attempt. The next transaction and transaction complete callback were only set
- // for the current draw attempt.
- final Transaction pendingTransactions;
- if (!didProduceBuffer) {
- mBlastBufferQueue.syncNextTransaction(null);
- // Get the transactions that were sent to mergeWithNextTransaction since the
- // frame didn't draw on this vsync. It's possible the frame will draw later, but
- // it's better to not be sync than to block on a frame that may never come.
- pendingTransactions = mBlastBufferQueue.gatherPendingTransactions(
- mRtLastAttemptedDrawFrameNum);
- if (!useBlastSync && !reportNextDraw) {
- pendingTransactions.apply();
- }
- } else {
- pendingTransactions = null;
- }
- // Post at front of queue so the buffer can be processed immediately and allow RT
- // to continue processing new buffers. If RT tries to process buffers before the sync
- // buffer is applied, the new buffers will not get acquired and could result in a
- // deadlock. UI thread would wait on RT, but RT would be blocked waiting for a free
- // buffer.
- mHandler.postAtFrontOfQueue(() -> {
- if (!didProduceBuffer && useBlastSync) {
- mSurfaceChangedTransaction.merge(pendingTransactions);
- if (blastSyncConsumer != null) {
- blastSyncConsumer.accept(mSurfaceChangedTransaction);
- }
- }
-
- // This is to ensure pendingDrawFinished is only called exactly one time per draw
- // attempt when reportNextDraw is true. Since, we sometimes create a sync
- // transaction callback, the callback will handle calling pendingDrawFinished.
- // However, there are cases where the transaction callback may not be called.
- // 1. If useBlastSync is false, then we know that a sync transaction callback was
- // not created so we won't invoke pendingDrawFinished there.
- // 2. If the draw didn't produce a frame, didProduceBuffer == false, then we know
- // the sync transaction callback will not be invoked even if one was set up.
- if (reportNextDraw && (!didProduceBuffer || !useBlastSync)) {
- pendingDrawFinished();
- }
- });
-
- };
- }
-
@Nullable
- private FrameDrawingCallback createFrameDrawingCallbackIfNeeded(boolean useBlastSync,
- boolean reportNextDraw) {
+ private void registerFrameDrawingCallbackForBlur() {
if (!isHardwareEnabled()) {
- return null;
+ return;
}
final boolean hasBlurUpdates = mBlurRegionAggregator.hasUpdates();
final boolean needsCallbackForBlur = hasBlurUpdates || mBlurRegionAggregator.hasRegions();
- if (!useBlastSync && !needsCallbackForBlur && !reportNextDraw && !mHasPendingTransactions) {
- return null;
- }
-
- final Consumer<SurfaceControl.Transaction> blastSyncConsumer = mBLASTDrawConsumer;
- mBLASTDrawConsumer = null;
-
- if (DEBUG_BLAST) {
- Log.d(mTag, "Creating frameDrawingCallback"
- + " nextDrawUseBlastSync=" + useBlastSync
- + " reportNextDraw=" + reportNextDraw
- + " hasBlurUpdates=" + hasBlurUpdates
- + " hasBlastSyncConsumer=" + (blastSyncConsumer != null)
- + " mHasPendingTransactions=" + mHasPendingTransactions);
+ if (!needsCallbackForBlur) {
+ return;
}
final BackgroundBlurDrawable.BlurRegion[] blurRegionsForFrame =
- needsCallbackForBlur ? mBlurRegionAggregator.getBlurRegionsCopyForRT() : null;
- final boolean hasPendingTransactions = mHasPendingTransactions;
- mHasPendingTransactions = false;
+ mBlurRegionAggregator.getBlurRegionsCopyForRT();
// The callback will run on the render thread.
- return new FrameDrawingCallback() {
+ registerRtFrameCallback((frame) -> mBlurRegionAggregator
+ .dispatchBlurTransactionIfNeeded(frame, blurRegionsForFrame, hasBlurUpdates));
+ }
+
+ private void registerCallbackForPendingTransactions() {
+ registerRtFrameCallback(new FrameDrawingCallback() {
+ @Override
+ public HardwareRenderer.FrameCommitCallback onFrameDraw(int syncResult, long frame) {
+ if ((syncResult
+ & (SYNC_LOST_SURFACE_REWARD_IF_FOUND | SYNC_CONTEXT_IS_STOPPED)) != 0) {
+ mBlastBufferQueue.applyPendingTransactions(frame);
+ return null;
+ }
+
+ return didProduceBuffer -> {
+ if (!didProduceBuffer) {
+ mBlastBufferQueue.applyPendingTransactions(frame);
+ }
+ };
+
+ }
+
@Override
public void onFrameDraw(long frame) {
}
-
- @Override
- public HardwareRenderer.FrameCommitCallback onFrameDraw(int syncResult, long frame) {
- if (DEBUG_BLAST) {
- Log.d(mTag,
- "Received frameDrawingCallback syncResult=" + syncResult + " frameNum="
- + frame + ".");
- }
-
- mRtLastAttemptedDrawFrameNum = frame;
-
- if (needsCallbackForBlur) {
- mBlurRegionAggregator.dispatchBlurTransactionIfNeeded(frame,
- blurRegionsForFrame, hasBlurUpdates);
- }
-
- if (mBlastBufferQueue == null) {
- return null;
- }
-
- if (!useBlastSync && !reportNextDraw && !hasPendingTransactions) {
- return null;
- }
-
- // If the syncResults are SYNC_LOST_SURFACE_REWARD_IF_FOUND or
- // SYNC_CONTEXT_IS_STOPPED it means nothing will draw. There's no need to set up
- // any blast sync or commit callback, and the code should directly call
- // pendingDrawFinished.
- if ((syncResult
- & (SYNC_LOST_SURFACE_REWARD_IF_FOUND | SYNC_CONTEXT_IS_STOPPED)) != 0) {
- if (reportNextDraw) {
- mHandler.postAtFrontOfQueue(() -> pendingDrawFinished());
- }
- return null;
- }
-
- if (DEBUG_BLAST) {
- Log.d(mTag, "Setting up sync and frameCommitCallback");
- }
-
- if (useBlastSync) {
- // Frame callbacks will always occur after submitting draw requests and before
- // the draw actually occurs. This will ensure that we set the next transaction
- // for the frame that's about to get drawn and not on a previous frame.
- mBlastBufferQueue.syncNextTransaction(
- t -> {
- mHandler.postAtFrontOfQueue(() -> {
- mSurfaceChangedTransaction.merge(t);
- if (blastSyncConsumer != null) {
- blastSyncConsumer.accept(mSurfaceChangedTransaction);
- }
-
- if (reportNextDraw) {
- pendingDrawFinished();
- }
- });
- });
- }
-
- return createFrameCommitCallbackForSync(useBlastSync, reportNextDraw,
- blastSyncConsumer);
- }
- };
+ });
}
- private void performDraw(boolean useBlastSync) {
+ private void performDraw() {
if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) {
return;
} else if (mView == null) {
return;
}
- final boolean fullRedrawNeeded = mFullRedrawNeeded || mReportNextDraw || useBlastSync;
+ final boolean fullRedrawNeeded = mFullRedrawNeeded || mSyncBufferCallback != null;
mFullRedrawNeeded = false;
mIsDrawing = true;
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
- FrameDrawingCallback frameDrawingCallback = createFrameDrawingCallbackIfNeeded(useBlastSync,
- mReportNextDraw);
- if (frameDrawingCallback != null) {
- mAttachInfo.mThreadedRenderer.registerRtFrameCallback(frameDrawingCallback);
- }
+ registerFrameDrawingCallbackForBlur();
addFrameCommitCallbackIfNeeded();
- boolean usingAsyncReport = isHardwareEnabled() && (useBlastSync || mReportNextDraw);
+
+ boolean usingAsyncReport = isHardwareEnabled() && mSyncBufferCallback != null;
+ if (usingAsyncReport) {
+ registerCallbacksForSync(mSyncBuffer, mSyncBufferCallback);
+ } else if (mHasPendingTransactions) {
+ // These callbacks are only needed if there's no sync involved and there were calls to
+ // applyTransactionOnDraw. These callbacks check if the draw failed for any reason and
+ // apply those transactions directly so they don't get stuck forever.
+ registerCallbackForPendingTransactions();
+ }
+ mHasPendingTransactions = false;
try {
boolean canUseAsync = draw(fullRedrawNeeded);
if (usingAsyncReport && !canUseAsync) {
mAttachInfo.mThreadedRenderer.setFrameCallback(null);
usingAsyncReport = false;
- mAttachInfo.mThreadedRenderer.unregisterRtFrameCallback(frameDrawingCallback);
}
} finally {
mIsDrawing = false;
@@ -4391,7 +4270,6 @@
}
if (mReportNextDraw) {
- mReportNextDraw = false;
// if we're using multi-thread renderer, wait for the window frame draws
if (mWindowDrawCountDown != null) {
@@ -4412,7 +4290,11 @@
}
if (mSurfaceHolder != null && mSurface.isValid()) {
- SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::postDrawFinished);
+ final SurfaceSyncer.SyncBufferCallback syncBufferCallback = mSyncBufferCallback;
+ SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() ->
+ mHandler.post(() -> syncBufferCallback.onBufferReady(null)));
+ mSyncBufferCallback = null;
+
SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
@@ -4420,9 +4302,11 @@
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mThreadedRenderer.fence();
}
- pendingDrawFinished();
}
}
+ if (mSyncBufferCallback != null && !usingAsyncReport) {
+ mSyncBufferCallback.onBufferReady(null);
+ }
if (mPerformContentCapture) {
performContentCaptureInitialReport();
}
@@ -5431,15 +5315,13 @@
private static final int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26;
private static final int MSG_UPDATE_POINTER_ICON = 27;
private static final int MSG_POINTER_CAPTURE_CHANGED = 28;
- private static final int MSG_DRAW_FINISHED = 29;
- private static final int MSG_INSETS_CHANGED = 30;
- private static final int MSG_INSETS_CONTROL_CHANGED = 31;
- private static final int MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED = 32;
- private static final int MSG_SHOW_INSETS = 34;
- private static final int MSG_HIDE_INSETS = 35;
- private static final int MSG_REQUEST_SCROLL_CAPTURE = 36;
- private static final int MSG_WINDOW_TOUCH_MODE_CHANGED = 37;
- private static final int MSG_KEEP_CLEAR_RECTS_CHANGED = 38;
+ private static final int MSG_INSETS_CONTROL_CHANGED = 29;
+ private static final int MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED = 30;
+ private static final int MSG_SHOW_INSETS = 31;
+ private static final int MSG_HIDE_INSETS = 32;
+ private static final int MSG_REQUEST_SCROLL_CAPTURE = 33;
+ private static final int MSG_WINDOW_TOUCH_MODE_CHANGED = 34;
+ private static final int MSG_KEEP_CLEAR_RECTS_CHANGED = 35;
final class ViewRootHandler extends Handler {
@@ -5494,10 +5376,6 @@
return "MSG_UPDATE_POINTER_ICON";
case MSG_POINTER_CAPTURE_CHANGED:
return "MSG_POINTER_CAPTURE_CHANGED";
- case MSG_DRAW_FINISHED:
- return "MSG_DRAW_FINISHED";
- case MSG_INSETS_CHANGED:
- return "MSG_INSETS_CHANGED";
case MSG_INSETS_CONTROL_CHANGED:
return "MSG_INSETS_CONTROL_CHANGED";
case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED:
@@ -5559,25 +5437,14 @@
break;
case MSG_RESIZED:
case MSG_RESIZED_REPORT: {
- mWillMove = false;
- mWillResize = false;
final SomeArgs args = (SomeArgs) msg.obj;
+ mInsetsController.onStateChanged((InsetsState) args.arg3);
handleResized(msg.what, args);
args.recycle();
break;
}
- case MSG_INSETS_CHANGED: {
- SomeArgs args = (SomeArgs) msg.obj;
- mWillMove = args.argi1 == 1;
- mWillResize = args.argi2 == 1;
- mInsetsController.onStateChanged((InsetsState) args.arg1);
- args.recycle();
- break;
- }
case MSG_INSETS_CONTROL_CHANGED: {
SomeArgs args = (SomeArgs) msg.obj;
- mWillMove = args.argi1 == 1;
- mWillResize = args.argi2 == 1;
// Deliver state change before control change, such that:
// a) When gaining control, controller can compare with server state to evaluate
@@ -5613,7 +5480,6 @@
break;
}
case MSG_WINDOW_MOVED:
- mWillMove = false;
if (mAdded) {
final int w = mWinFrame.width();
final int h = mWinFrame.height();
@@ -5726,9 +5592,6 @@
final boolean hasCapture = msg.arg1 != 0;
handlePointerCaptureChanged(hasCapture);
} break;
- case MSG_DRAW_FINISHED: {
- pendingDrawFinished();
- } break;
case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED: {
systemGestureExclusionChanged();
} break;
@@ -8057,7 +7920,6 @@
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
-
mRelayoutRequested = true;
float appScale = mAttachInfo.mApplicationScale;
boolean restore = false;
@@ -8083,17 +7945,66 @@
final int requestedWidth = (int) (mView.getMeasuredWidth() * appScale + 0.5f);
final int requestedHeight = (int) (mView.getMeasuredHeight() * appScale + 0.5f);
- int relayoutResult = mWindowSession.relayout(mWindow, params,
- requestedWidth, requestedHeight, viewVisibility,
- insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
- mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
- mTempControls, mRelayoutBundle);
- mSyncSeqId = mRelayoutBundle.getInt("seqid");
+ int relayoutResult = 0;
+ WindowConfiguration winConfig = getConfiguration().windowConfiguration;
+ if (LOCAL_LAYOUT) {
+ if (mFirst || viewVisibility != mViewVisibility) {
+ relayoutResult = mWindowSession.updateVisibility(mWindow, params, viewVisibility,
+ mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mTempControls);
+ if (mTranslator != null) {
+ mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
+ mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
+ }
+ mInsetsController.onStateChanged(mTempInsets);
+ mInsetsController.onControlsChanged(mTempControls);
+
+ mPendingAlwaysConsumeSystemBars =
+ (relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
+ }
+ final InsetsState state = mInsetsController.getState();
+ final Rect displayCutoutSafe = mTempRect;
+ state.getDisplayCutoutSafe(displayCutoutSafe);
+ if (mWindowAttributes.type == TYPE_APPLICATION_STARTING) {
+ // TODO(b/210378379): Remove the special logic.
+ // Letting starting window use the window bounds from the pending config is for the
+ // fixed rotation, because the config is not overridden before the starting window
+ // is created.
+ winConfig = mPendingMergedConfiguration.getMergedConfiguration()
+ .windowConfiguration;
+ }
+ mWindowLayout.computeFrames(mWindowAttributes, state, displayCutoutSafe,
+ winConfig.getBounds(), winConfig.getWindowingMode(), requestedWidth,
+ requestedHeight, mInsetsController.getRequestedVisibilities(),
+ getAttachedWindowFrame(), 1f /* compatScale */, mTmpFrames);
+
+ mWindowSession.updateLayout(mWindow, params,
+ insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mTmpFrames,
+ requestedWidth, requestedHeight);
+
+ } else {
+ relayoutResult = mWindowSession.relayout(mWindow, params,
+ requestedWidth, requestedHeight, viewVisibility,
+ insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
+ mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
+ mTempControls, mRelayoutBundle);
+ mSyncSeqId = mRelayoutBundle.getInt("seqid");
+
+ if (mTranslator != null) {
+ mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
+ mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame);
+ mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
+ mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
+ }
+ mInsetsController.onStateChanged(mTempInsets);
+ mInsetsController.onControlsChanged(mTempControls);
+
+ mPendingAlwaysConsumeSystemBars =
+ (relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
+ }
final int transformHint = SurfaceControl.rotationToBufferTransform(
(mDisplayInstallOrientation + mDisplay.getRotation()) % 4);
- final WindowConfiguration winConfig = getConfiguration().windowConfiguration;
WindowLayout.computeSurfaceSize(mWindowAttributes, winConfig.getMaxBounds(), requestedWidth,
requestedHeight, mTmpFrames.frame, mPendingDragResizing, mSurfaceSize);
@@ -8142,24 +8053,10 @@
destroySurface();
}
- mPendingAlwaysConsumeSystemBars =
- (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
-
if (restore) {
params.restore();
}
-
- if (mTranslator != null) {
- mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
- mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame);
- mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
- mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
- }
setFrame(mTmpFrames.frame);
- mWillMove = false;
- mWillResize = false;
- mInsetsController.onStateChanged(mTempInsets);
- mInsetsController.onControlsChanged(mTempControls);
return relayoutResult;
}
@@ -8592,44 +8489,37 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private void dispatchResized(ClientWindowFrames frames, boolean reportDraw,
- MergedConfiguration mergedConfiguration, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId, int seqId, int resizeMode) {
+ MergedConfiguration mergedConfiguration, InsetsState insetsState, boolean forceLayout,
+ boolean alwaysConsumeSystemBars, int displayId, int syncSeqId, int resizeMode) {
Message msg = mHandler.obtainMessage(reportDraw ? MSG_RESIZED_REPORT : MSG_RESIZED);
SomeArgs args = SomeArgs.obtain();
final boolean sameProcessCall = (Binder.getCallingPid() == android.os.Process.myPid());
- args.arg1 = sameProcessCall ? new ClientWindowFrames(frames) : frames;
- args.arg2 = sameProcessCall && mergedConfiguration != null
- ? new MergedConfiguration(mergedConfiguration) : mergedConfiguration;
- args.argi1 = forceLayout ? 1 : 0;
- args.argi2 = alwaysConsumeSystemBars ? 1 : 0;
- args.argi3 = displayId;
- args.argi4 = seqId;
- args.argi5 = resizeMode;
- msg.obj = args;
- mHandler.sendMessage(msg);
- }
-
- private void dispatchInsetsChanged(InsetsState insetsState, boolean willMove,
- boolean willResize) {
- if (Binder.getCallingPid() == android.os.Process.myPid()) {
+ if (sameProcessCall) {
insetsState = new InsetsState(insetsState, true /* copySource */);
}
if (mTranslator != null) {
mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
}
- if (insetsState != null && insetsState.getSourceOrDefaultVisibility(ITYPE_IME)) {
- ImeTracing.getInstance().triggerClientDump("ViewRootImpl#dispatchInsetsChanged",
+ if (insetsState.getSourceOrDefaultVisibility(ITYPE_IME)) {
+ ImeTracing.getInstance().triggerClientDump("ViewRootImpl#dispatchResized",
getInsetsController().getHost().getInputMethodManager(), null /* icProto */);
}
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = insetsState;
- args.argi1 = willMove ? 1 : 0;
- args.argi2 = willResize ? 1 : 0;
- mHandler.obtainMessage(MSG_INSETS_CHANGED, args).sendToTarget();
+ args.arg1 = sameProcessCall ? new ClientWindowFrames(frames) : frames;
+ args.arg2 = sameProcessCall && mergedConfiguration != null
+ ? new MergedConfiguration(mergedConfiguration) : mergedConfiguration;
+ args.arg3 = insetsState;
+ args.argi1 = forceLayout ? 1 : 0;
+ args.argi2 = alwaysConsumeSystemBars ? 1 : 0;
+ args.argi3 = displayId;
+ args.argi4 = syncSeqId;
+ args.argi5 = resizeMode;
+
+ msg.obj = args;
+ mHandler.sendMessage(msg);
}
private void dispatchInsetsControlChanged(InsetsState insetsState,
- InsetsSourceControl[] activeControls, boolean willMove, boolean willResize) {
+ InsetsSourceControl[] activeControls) {
if (Binder.getCallingPid() == android.os.Process.myPid()) {
insetsState = new InsetsState(insetsState, true /* copySource */);
if (activeControls != null) {
@@ -8649,8 +8539,6 @@
SomeArgs args = SomeArgs.obtain();
args.arg1 = insetsState;
args.arg2 = activeControls;
- args.argi1 = willMove ? 1 : 0;
- args.argi2 = willResize ? 1 : 0;
mHandler.obtainMessage(MSG_INSETS_CONTROL_CHANGED, args).sendToTarget();
}
@@ -9896,8 +9784,8 @@
}
private void reportNextDraw() {
- if (mReportNextDraw == false) {
- drawPending();
+ if (DEBUG_BLAST) {
+ Log.d(mTag, "reportNextDraw " + Debug.getCallers(5));
}
mReportNextDraw = true;
}
@@ -9908,9 +9796,14 @@
* This method is only supposed to be used to speed up the interaction from SystemUI and window
* manager when waiting for the first frame to be drawn when turning on the screen. DO NOT USE
* unless you fully understand this interaction.
+ *
+ * @param syncBuffer If true, the transaction that contains the buffer from the draw should be
+ * sent to system to be synced. If false, VRI will not try to sync the buffer,
+ * but only report back that a buffer was drawn.
* @hide
*/
- public void setReportNextDraw() {
+ public void setReportNextDraw(boolean syncBuffer) {
+ mSyncBuffer = syncBuffer;
reportNextDraw();
invalidate();
}
@@ -9988,30 +9881,22 @@
@Override
public void resized(ClientWindowFrames frames, boolean reportDraw,
- MergedConfiguration mergedConfiguration, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId, int seqId, int resizeMode) {
+ MergedConfiguration mergedConfiguration, InsetsState insetsState,
+ boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, int syncSeqId,
+ int resizeMode) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
- viewAncestor.dispatchResized(frames, reportDraw, mergedConfiguration, forceLayout,
- alwaysConsumeSystemBars, displayId, seqId, resizeMode);
- }
- }
-
- @Override
- public void insetsChanged(InsetsState insetsState, boolean willMove, boolean willResize) {
- final ViewRootImpl viewAncestor = mViewAncestor.get();
- if (viewAncestor != null) {
- viewAncestor.dispatchInsetsChanged(insetsState, willMove, willResize);
+ viewAncestor.dispatchResized(frames, reportDraw, mergedConfiguration, insetsState,
+ forceLayout, alwaysConsumeSystemBars, displayId, syncSeqId, resizeMode);
}
}
@Override
public void insetsControlChanged(InsetsState insetsState,
- InsetsSourceControl[] activeControls, boolean willMove, boolean willResize) {
+ InsetsSourceControl[] activeControls) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
- viewAncestor.dispatchInsetsControlChanged(
- insetsState, activeControls, willMove, willResize);
+ viewAncestor.dispatchInsetsControlChanged(insetsState, activeControls);
}
}
@@ -10831,37 +10716,6 @@
showControl, transformationApplied, callback);
}
- /**
- * Redirect the next draw of this ViewRoot (from the UI thread perspective)
- * to the passed in consumer. This can be used to create P2P synchronization
- * between ViewRoot's however it comes with many caveats.
- *
- * 1. You MUST consume the transaction, by either applying it immediately or
- * merging it in to another transaction. The threading model doesn't
- * allow you to hold in the passed transaction.
- * 2. If you merge it in to another transaction, this ViewRootImpl will be
- * paused until you finally apply that transaction and it receives
- * the callback from SF. If you lose track of the transaction you will
- * ANR the app.
- * 3. Only one person can consume the transaction at a time, if you already
- * have a pending consumer for this frame, the function will return false
- * 4. Someone else may have requested to consume the next frame, in which case
- * this function will return false and you will not receive a callback.
- * 5. This function does not trigger drawing so even if it returns true you
- * may not receive a callback unless there is some other UI thread work
- * to trigger drawing. If it returns true, and a draw occurs, the callback
- * will be called (Though again watch out for the null transaction case!)
- * 6. This function must be called on the UI thread. The consumer will likewise
- * be called on the UI thread.
- */
- public boolean consumeNextDraw(Consumer<SurfaceControl.Transaction> consume) {
- if (mBLASTDrawConsumer != null) {
- return false;
- }
- mBLASTDrawConsumer = consume;
- return true;
- }
-
boolean wasRelayoutRequested() {
return mRelayoutRequested;
}
@@ -10936,14 +10790,15 @@
return mWindowSession;
}
- private void registerCallbacksForSync(
+ private void registerCallbacksForSync(boolean syncBuffer,
final SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
if (!isHardwareEnabled()) {
- // TODO: correctly handle when hardware disabled
- syncBufferCallback.onBufferReady(null);
return;
}
+ if (DEBUG_BLAST) {
+ Log.d(mTag, "registerCallbacksForSync syncBuffer=" + syncBuffer);
+ }
mAttachInfo.mThreadedRenderer.registerRtFrameCallback(new FrameDrawingCallback() {
@Override
public void onFrameDraw(long frame) {
@@ -10972,7 +10827,9 @@
Log.d(mTag, "Setting up sync and frameCommitCallback");
}
- mBlastBufferQueue.syncNextTransaction(t -> syncBufferCallback.onBufferReady(t));
+ if (syncBuffer) {
+ mBlastBufferQueue.syncNextTransaction(syncBufferCallback::onBufferReady);
+ }
return didProduceBuffer -> {
if (DEBUG_BLAST) {
@@ -10986,18 +10843,40 @@
// were only set for the current draw attempt.
if (!didProduceBuffer) {
mBlastBufferQueue.syncNextTransaction(null);
+
// Gather the transactions that were sent to mergeWithNextTransaction
// since the frame didn't draw on this vsync. It's possible the frame will
// draw later, but it's better to not be sync than to block on a frame that
// may never come.
syncBufferCallback.onBufferReady(
mBlastBufferQueue.gatherPendingTransactions(frame));
+ return;
+ }
+
+ // If we didn't request to sync a buffer, then we won't get the
+ // syncNextTransaction callback. Instead, just report back to the Syncer so it
+ // knows that this sync request is complete.
+ if (!syncBuffer) {
+ syncBufferCallback.onBufferReady(null);
}
};
}
});
}
- public final SurfaceSyncer.SyncTarget mSyncTarget =
- syncBufferCallback -> registerCallbacksForSync(syncBufferCallback);
+ public final SurfaceSyncer.SyncTarget mSyncTarget = this::readyToSync;
+
+ private void readyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
+ if (mSyncBufferCallback != null) {
+ Log.d(mTag, "Already set sync for the next draw.");
+ mSyncBufferCallback.onBufferReady(null);
+ }
+ if (DEBUG_BLAST) {
+ Log.d(mTag, "Setting syncFrameCallback");
+ }
+ mSyncBufferCallback = syncBufferCallback;
+ if (!mIsInTraversal && !mTraversalScheduled) {
+ scheduleTraversals();
+ }
+ }
}
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index 9793f8c..4387701 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -171,8 +171,9 @@
public void setSystemBarsAppearance(int appearance, int mask) {
mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_APPEARANCE_CONTROLLED;
final InsetsFlags insetsFlags = mViewRoot.mWindowAttributes.insetsFlags;
- if (insetsFlags.appearance != appearance) {
- insetsFlags.appearance = (insetsFlags.appearance & ~mask) | (appearance & mask);
+ final int newAppearance = (insetsFlags.appearance & ~mask) | (appearance & mask);
+ if (insetsFlags.appearance != newAppearance) {
+ insetsFlags.appearance = newAppearance;
mViewRoot.mWindowAttributesChanged = true;
mViewRoot.scheduleTraversals();
}
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 06588b2..30ae520 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -16,6 +16,8 @@
package android.view;
+import static android.view.WindowCallbacks.RESIZE_MODE_INVALID;
+
import android.annotation.Nullable;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
@@ -82,9 +84,8 @@
private final IBinder mHostInputToken;
private final IBinder mFocusGrantToken = new Binder();
private InsetsState mInsetsState;
-
- private int mForceHeight = -1;
- private int mForceWidth = -1;
+ private final ClientWindowFrames mTmpFrames = new ClientWindowFrames();
+ private final MergedConfiguration mTmpConfig = new MergedConfiguration();
public WindowlessWindowManager(Configuration c, SurfaceControl rootSurface,
IBinder hostInputToken) {
@@ -336,6 +337,21 @@
}
@Override
+ public int updateVisibility(IWindow window, WindowManager.LayoutParams inAttrs,
+ int viewVisibility, MergedConfiguration outMergedConfiguration,
+ SurfaceControl outSurfaceControl, InsetsState outInsetsState,
+ InsetsSourceControl[] outActiveControls) {
+ // TODO(b/161810301): Finish the implementation.
+ return 0;
+ }
+
+ @Override
+ public void updateLayout(IWindow window, WindowManager.LayoutParams inAttrs, int flags,
+ ClientWindowFrames clientWindowFrames, int requestedWidth, int requestedHeight) {
+ // TODO(b/161810301): Finish the implementation.
+ }
+
+ @Override
public void prepareToReplaceWindows(android.os.IBinder appToken, boolean childrenOnly) {
}
@@ -525,7 +541,12 @@
mInsetsState = state;
for (State s : mStateForWindow.values()) {
try {
- s.mClient.insetsChanged(state, false, false);
+ mTmpFrames.frame.set(0, 0, s.mParams.width, s.mParams.height);
+ mTmpFrames.displayFrame.set(mTmpFrames.frame);
+ mTmpConfig.setConfiguration(mConfiguration, mConfiguration);
+ s.mClient.resized(mTmpFrames, false /* reportDraw */, mTmpConfig, state,
+ false /* forceLayout */, false /* alwaysConsumeSystemBars */, s.mDisplayId,
+ Integer.MAX_VALUE, RESIZE_MODE_INVALID);
} catch (RemoteException e) {
// Too bad
}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 07db91f..6fa6d39 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -3077,11 +3077,26 @@
}
/**
- * Like {@link #showAutofillDialog(View)} but for virtual views.
+ * If autofill suggestions for a
+ * <a href="{@docRoot}reference/android/service/autofill/Dataset.html#FillDialogUI">
+ * dialog-style UI</a> are available for virtual {@code view}, shows a dialog allowing the user
+ * to select a suggestion and returns {@code true}.
+ * <p>
+ * The dialog may not be shown if the autofill service does not support it, if the autofill
+ * request has not returned a response yet, if the dialog was shown previously, or if the
+ * input method is already shown.
+ * <p>
+ * It is recommended apps to call this method the first time a user focuses on
+ * an autofill-able form, and to avoid showing the input method if the dialog is shown. If
+ * this method returns {@code false}, you should then instead show the input method (assuming
+ * that is how the view normally handles the focus event). If the user re-focuses on the view,
+ * you should not call this method again so as to not disrupt usage of the input method.
*
- * @param virtualId id identifying the virtual child inside the parent view.
+ * @param view the view hosting the virtual view hierarchy which is used to show autofill
+ * suggestions.
+ * @param virtualId id identifying the virtual view inside the host view.
+ * @return {@code true} if the autofill dialog is being shown
*/
- // TODO(b/210926084): Consider whether to include the one-time show logic within this method.
public boolean showAutofillDialog(@NonNull View view, int virtualId) {
Objects.requireNonNull(view);
if (shouldShowAutofillDialog(getAutofillId(view, virtualId))) {
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 67f284b..dbfcca9 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -111,6 +111,7 @@
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
+import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -129,6 +130,9 @@
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView.Drawables;
import android.widget.TextView.OnEditorActionListener;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
+import android.window.WindowOnBackInvokedDispatcher;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.EditableInputConnection;
@@ -235,6 +239,14 @@
private boolean mSelectionControllerEnabled;
private final boolean mHapticTextHandleEnabled;
+ /** Handles OnBackInvokedCallback back dispatch */
+ private final OnBackInvokedCallback mBackCallback = new OnBackInvokedCallback() {
+ @Override
+ public void onBackInvoked() {
+ stopTextActionMode();
+ }
+ };
+ private boolean mBackCallbackRegistered;
@Nullable
private MagnifierMotionAnimator mMagnifierAnimator;
@@ -753,6 +765,35 @@
stopTextActionModeWithPreservingSelection();
mDefaultOnReceiveContentListener.clearInputConnectionInfo();
+ unregisterOnBackInvokedCallback();
+ }
+
+ private void unregisterOnBackInvokedCallback() {
+ if (!mBackCallbackRegistered) {
+ return;
+ }
+ ViewRootImpl viewRootImpl = getTextView().getViewRootImpl();
+ if (viewRootImpl != null
+ && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
+ viewRootImpl.mContext)) {
+ viewRootImpl.getOnBackInvokedDispatcher()
+ .unregisterOnBackInvokedCallback(mBackCallback);
+ mBackCallbackRegistered = false;
+ }
+ }
+
+ private void registerOnBackInvokedCallback() {
+ if (mBackCallbackRegistered) {
+ return;
+ }
+ ViewRootImpl viewRootImpl = mTextView.getViewRootImpl();
+ if (viewRootImpl != null
+ && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
+ viewRootImpl.mContext)) {
+ viewRootImpl.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
+ OnBackInvokedDispatcher.PRIORITY_DEFAULT, mBackCallback);
+ mBackCallbackRegistered = true;
+ }
}
private void discardTextDisplayLists() {
@@ -2370,6 +2411,7 @@
new TextActionModeCallback(TextActionMode.INSERTION);
mTextActionMode = mTextView.startActionMode(
actionModeCallback, ActionMode.TYPE_FLOATING);
+ registerOnBackInvokedCallback();
if (mTextActionMode != null && getInsertionController() != null) {
getInsertionController().show();
}
@@ -2485,6 +2527,7 @@
ActionMode.Callback actionModeCallback = new TextActionModeCallback(actionMode);
mTextActionMode = mTextView.startActionMode(actionModeCallback, ActionMode.TYPE_FLOATING);
+ registerOnBackInvokedCallback();
final boolean selectableText = mTextView.isTextEditable() || mTextView.isTextSelectable();
if (actionMode == TextActionMode.TEXT_LINK && !selectableText
@@ -2660,6 +2703,7 @@
// This will hide the mSelectionModifierCursorController
mTextActionMode.finish();
}
+ unregisterOnBackInvokedCallback();
}
private void stopTextActionModeWithPreservingSelection() {
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index 9c9baf3..f1dc5e7 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -16,6 +16,7 @@
package android.widget;
+import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
@@ -30,10 +31,14 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewRootImpl;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
+import android.window.WindowOnBackInvokedDispatcher;
import com.android.internal.policy.PhoneWindow;
@@ -115,6 +120,27 @@
private CharSequence mPlayDescription;
private CharSequence mPauseDescription;
private final AccessibilityManager mAccessibilityManager;
+ private boolean mBackCallbackRegistered;
+ /** Handles back invocation */
+ private final OnBackInvokedCallback mBackCallback = new OnBackInvokedCallback() {
+ @Override
+ public void onBackInvoked() {
+ hide();
+ }
+ };
+ /** Handles decor view attach state change */
+ private final OnAttachStateChangeListener mAttachStateListener =
+ new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(@NonNull View v) {
+ registerOnBackInvokedCallback();
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(@NonNull View v) {
+ unregisterOnBackInvokedCallback();
+ }
+ };
public MediaController(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -151,6 +177,7 @@
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
mDecor = mWindow.getDecorView();
mDecor.setOnTouchListener(mTouchListener);
+ mDecor.addOnAttachStateChangeListener(mAttachStateListener);
mWindow.setContentView(this);
mWindow.setBackgroundDrawableResource(android.R.color.transparent);
@@ -395,6 +422,7 @@
removeCallbacks(mFadeOut);
postDelayed(mFadeOut, timeout);
}
+ registerOnBackInvokedCallback();
}
public boolean isShowing() {
@@ -416,6 +444,7 @@
Log.w("MediaController", "already removed");
}
mShowing = false;
+ unregisterOnBackInvokedCallback();
}
}
@@ -718,6 +747,35 @@
}
}
+ private void unregisterOnBackInvokedCallback() {
+ if (!mBackCallbackRegistered) {
+ return;
+ }
+ ViewRootImpl viewRootImpl = mDecor.getViewRootImpl();
+ if (viewRootImpl != null
+ && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
+ viewRootImpl.mContext)) {
+ viewRootImpl.getOnBackInvokedDispatcher()
+ .unregisterOnBackInvokedCallback(mBackCallback);
+ }
+ mBackCallbackRegistered = false;
+ }
+
+ private void registerOnBackInvokedCallback() {
+ if (mBackCallbackRegistered) {
+ return;
+ }
+
+ ViewRootImpl viewRootImpl = mDecor.getViewRootImpl();
+ if (viewRootImpl != null
+ && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
+ viewRootImpl.mContext)) {
+ viewRootImpl.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
+ OnBackInvokedDispatcher.PRIORITY_DEFAULT, mBackCallback);
+ mBackCallbackRegistered = true;
+ }
+ }
+
public interface MediaPlayerControl {
void start();
void pause();
diff --git a/core/java/android/widget/TextViewTranslationCallback.java b/core/java/android/widget/TextViewTranslationCallback.java
index 942be21..1713d84 100644
--- a/core/java/android/widget/TextViewTranslationCallback.java
+++ b/core/java/android/widget/TextViewTranslationCallback.java
@@ -89,7 +89,7 @@
originalTranslationMethod);
}
final TransformationMethod transformation = mTranslationTransformation;
- runWithAnimation(
+ runChangeTextWithAnimationIfNeeded(
(TextView) view,
() -> {
mIsShowingTranslation = true;
@@ -122,7 +122,7 @@
if (mTranslationTransformation != null) {
final TransformationMethod transformation =
mTranslationTransformation.getOriginalTransformationMethod();
- runWithAnimation(
+ runChangeTextWithAnimationIfNeeded(
(TextView) view,
() -> {
mIsShowingTranslation = false;
@@ -232,10 +232,16 @@
* Applies a simple text alpha animation when toggling between original and translated text. The
* text is fully faded out, then swapped to the new text, then the fading is reversed.
*
- * @param runnable the operation to run on the view after the text is faded out, to change to
- * displaying the original or translated text.
+ * @param changeTextRunnable the operation to run on the view after the text is faded out, to
+ * change to displaying the original or translated text.
*/
- private void runWithAnimation(TextView view, Runnable runnable) {
+ private void runChangeTextWithAnimationIfNeeded(TextView view, Runnable changeTextRunnable) {
+ boolean areAnimatorsEnabled = ValueAnimator.areAnimatorsEnabled();
+ if (!areAnimatorsEnabled) {
+ // The animation is disabled, just change display text
+ changeTextRunnable.run();
+ return;
+ }
if (mAnimator != null) {
mAnimator.end();
// Note: mAnimator is now null; do not use again here.
@@ -269,7 +275,7 @@
@Override
public void onAnimationRepeat(Animator animation) {
- runnable.run();
+ changeTextRunnable.run();
}
});
mAnimator.start();
diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java
index 88ece5c..0110136 100644
--- a/core/java/android/window/DisplayAreaOrganizer.java
+++ b/core/java/android/window/DisplayAreaOrganizer.java
@@ -108,7 +108,6 @@
* the position and settings of the container manually. This is useful for foldable devices
* which require custom UX rules for the IME position (e.g. IME on one screen and the focused
* app on another screen).
- * @hide
*/
public static final int FEATURE_IME = FEATURE_SYSTEM_FIRST + 8;
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index 19ee1d0..a791cfa 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -104,6 +104,9 @@
private Duration mIconAnimationDuration;
private Instant mIconAnimationStart;
+ private final Rect mTmpRect = new Rect();
+ private final int[] mTmpPos = new int[2];
+
// The host activity when transfer view to it.
private Activity mHostActivity;
@@ -578,6 +581,45 @@
releaseAnimationSurfaceHost();
}
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+
+ mBrandingImageView.getDrawingRect(mTmpRect);
+ final int brandingHeight = mTmpRect.height();
+ if (brandingHeight == 0 || mIconView == null) {
+ return;
+ }
+ final int visibility = mBrandingImageView.getVisibility();
+ if (visibility != VISIBLE) {
+ return;
+ }
+ final int currentHeight = b - t;
+
+ mIconView.getLocationInWindow(mTmpPos);
+ mIconView.getDrawingRect(mTmpRect);
+ final int iconHeight = mTmpRect.height();
+
+ final ViewGroup.MarginLayoutParams params =
+ (ViewGroup.MarginLayoutParams) mBrandingImageView.getLayoutParams();
+ if (params == null) {
+ Log.e(TAG, "Unable to adjust branding image layout, layout changed?");
+ return;
+ }
+ final int marginBottom = params.bottomMargin;
+ final int remainingHeight = currentHeight - mTmpPos[1] - iconHeight;
+ final int remainingMaxMargin = remainingHeight - brandingHeight;
+ if (remainingHeight < brandingHeight) {
+ // unable to show the branding image, hide it
+ mBrandingImageView.setVisibility(GONE);
+ } else if (remainingMaxMargin < marginBottom) {
+ // shorter than original margin
+ params.bottomMargin = (int) Math.round(remainingMaxMargin / 2.0);
+ mBrandingImageView.setLayoutParams(params);
+ }
+ // nothing need to adjust
+ }
+
private void releaseAnimationSurfaceHost() {
if (mSurfaceHost != null && !mIsCopied) {
if (DEBUG) {
@@ -757,6 +799,9 @@
final Rect initialBounds = drawable.copyBounds();
final int width = initialBounds.width();
final int height = initialBounds.height();
+ if (width <= 0 || height <= 0) {
+ return null;
+ }
final Bitmap snapshot = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
final Canvas bmpCanvas = new Canvas(snapshot);
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 35c9594..f2db564 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -269,6 +269,20 @@
}
/**
+ * Used in conjunction with a shell-transition call (usually finishTransition). This is
+ * basically a message to the transition system that a particular task should NOT go into
+ * PIP even though it normally would. This is to deal with some edge-case situations where
+ * Recents will "commit" the transition to go home, but then not actually go-home.
+ * @hide
+ */
+ @NonNull
+ public WindowContainerTransaction setDoNotPip(@NonNull WindowContainerToken container) {
+ Change chg = getOrCreateChange(container.asBinder());
+ chg.mChangeMask |= Change.CHANGE_FORCE_NO_PIP;
+ return this;
+ }
+
+ /**
* Reparents a container into another one. The effect of a {@code null} parent can vary. For
* example, reparenting a stack to {@code null} will reparent it to its display.
*
@@ -790,6 +804,7 @@
public static final int CHANGE_HIDDEN = 1 << 3;
public static final int CHANGE_BOUNDS_TRANSACTION_RECT = 1 << 4;
public static final int CHANGE_IGNORE_ORIENTATION_REQUEST = 1 << 5;
+ public static final int CHANGE_FORCE_NO_PIP = 1 << 6;
private final Configuration mConfiguration = new Configuration();
private boolean mFocusable = true;
diff --git a/core/java/com/android/internal/app/BlockedAppStreamingActivity.java b/core/java/com/android/internal/app/BlockedAppStreamingActivity.java
index 31c3822..2d6c77f 100644
--- a/core/java/com/android/internal/app/BlockedAppStreamingActivity.java
+++ b/core/java/com/android/internal/app/BlockedAppStreamingActivity.java
@@ -56,7 +56,11 @@
CharSequence streamedDeviceName = intent.getCharSequenceExtra(EXTRA_STREAMED_DEVICE);
if (!TextUtils.isEmpty(streamedDeviceName)) {
- mAlertParams.mTitle = getString(R.string.app_streaming_blocked_title, appLabel);
+ mAlertParams.mTitle =
+ TextUtils.equals(activityInfo.packageName,
+ getPackageManager().getPermissionControllerPackageName())
+ ? getString(R.string.app_streaming_blocked_title_for_permission_dialog)
+ : getString(R.string.app_streaming_blocked_title, appLabel);
mAlertParams.mMessage =
getString(R.string.app_streaming_blocked_message, streamedDeviceName);
} else {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index c2e145e..96728ed 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -28,7 +28,6 @@
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
import android.app.SharedElementCallback;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionManager;
@@ -71,11 +70,9 @@
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Message;
import android.os.Parcelable;
import android.os.PatternMatcher;
-import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.UserHandle;
import android.os.UserManager;
@@ -761,25 +758,17 @@
return false;
}
- try {
- Intent delegationIntent = new Intent();
- final ComponentName delegateActivity = ComponentName.unflattenFromString(
- Resources.getSystem().getString(R.string.config_chooserActivity));
- IBinder permissionToken = ActivityTaskManager.getService()
- .requestStartActivityPermissionToken(delegateActivity);
- delegationIntent.setComponent(delegateActivity);
- delegationIntent.putExtra(Intent.EXTRA_INTENT, getIntent());
- delegationIntent.putExtra(ActivityTaskManager.EXTRA_PERMISSION_TOKEN, permissionToken);
- delegationIntent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
+ Intent delegationIntent = new Intent();
+ final ComponentName delegateActivity = ComponentName.unflattenFromString(
+ Resources.getSystem().getString(R.string.config_chooserActivity));
+ delegationIntent.setComponent(delegateActivity);
+ delegationIntent.putExtra(Intent.EXTRA_INTENT, getIntent());
+ delegationIntent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
- // Don't close until the delegate finishes, or the token will be invalidated.
- mAwaitingDelegateResponse = true;
- startActivityForResult(delegationIntent, REQUEST_CODE_RETURN_FROM_DELEGATE_CHOOSER);
- return true;
- } catch (RemoteException e) {
- Log.e(TAG, e.toString());
- }
- return false;
+ // Don't close until the delegate finishes, or the token will be invalidated.
+ mAwaitingDelegateResponse = true;
+ startActivityForResult(delegationIntent, REQUEST_CODE_RETURN_FROM_DELEGATE_CHOOSER);
+ return true;
}
@Override
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 6e76906..070d8ff 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -207,7 +207,6 @@
startActivityAsCaller(
newIntent,
/* options= */ null,
- /* permissionToken= */ null,
/* ignoreTargetSecurity= */ false,
userId);
} catch (RuntimeException e) {
@@ -231,7 +230,7 @@
return;
}
sanitizeIntent(innerIntent);
- startActivityAsCaller(intentReceived, null, null, false, getUserId());
+ startActivityAsCaller(intentReceived, null, false, getUserId());
finish();
}
@@ -251,7 +250,7 @@
sanitizeIntent(intentReceived);
intentReceived.putExtra(EXTRA_SELECTED_PROFILE, selectedProfile);
intentReceived.putExtra(EXTRA_CALLING_USER, UserHandle.of(callingUserId));
- startActivityAsCaller(intentReceived, null, null, false, userId);
+ startActivityAsCaller(intentReceived, null, false, userId);
finish();
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 5ebb148..dc68e16 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1463,7 +1463,7 @@
int userId) {
// Note: this method will be overridden in the delegate implementation to use the passed-in
// permission token.
- startActivityAsCaller(intent, options, null, false, userId);
+ startActivityAsCaller(intent, options, false, userId);
return true;
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 8901c07..4b20347 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -69,6 +69,7 @@
import android.os.connectivity.WifiActivityEnergyInfo;
import android.os.connectivity.WifiBatteryStats;
import android.provider.Settings;
+import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation.NetworkType;
import android.telephony.CellSignalStrength;
import android.telephony.CellSignalStrengthLte;
@@ -5432,7 +5433,6 @@
@GuardedBy("this")
public void noteLongPartialWakelockStart(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
- uid = mapUid(uid);
noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs);
}
@@ -5467,15 +5467,21 @@
@GuardedBy("this")
private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
+ final int mappedUid = mapUid(uid);
if (historyName == null) {
historyName = name;
}
- if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid,
- 0)) {
+ if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName,
+ mappedUid, 0)) {
return;
}
addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START,
- historyName, uid);
+ historyName, mappedUid);
+ if (mappedUid != uid) {
+ // Prevent the isolated uid mapping from being removed while the wakelock is
+ // being held.
+ incrementIsolatedUidRefCount(uid);
+ }
}
@GuardedBy("this")
@@ -5487,7 +5493,6 @@
@GuardedBy("this")
public void noteLongPartialWakelockFinish(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
- uid = mapUid(uid);
noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs);
}
@@ -5522,15 +5527,20 @@
@GuardedBy("this")
private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
+ final int mappedUid = mapUid(uid);
if (historyName == null) {
historyName = name;
}
- if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid,
- 0)) {
+ if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName,
+ mappedUid, 0)) {
return;
}
addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH,
- historyName, uid);
+ historyName, mappedUid);
+ if (mappedUid != uid) {
+ // Decrement the ref count for the isolated uid and delete the mapping if uneeded.
+ maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs);
+ }
}
@GuardedBy("this")
@@ -6821,6 +6831,27 @@
}
}
+ @RadioAccessTechnology
+ private static int mapRadioAccessNetworkTypeToRadioAccessTechnology(
+ @AccessNetworkConstants.RadioAccessNetworkType int dataType) {
+ switch (dataType) {
+ case AccessNetworkConstants.AccessNetworkType.NGRAN:
+ return RADIO_ACCESS_TECHNOLOGY_NR;
+ case AccessNetworkConstants.AccessNetworkType.EUTRAN:
+ return RADIO_ACCESS_TECHNOLOGY_LTE;
+ case AccessNetworkConstants.AccessNetworkType.UNKNOWN: //fallthrough
+ case AccessNetworkConstants.AccessNetworkType.GERAN: //fallthrough
+ case AccessNetworkConstants.AccessNetworkType.UTRAN: //fallthrough
+ case AccessNetworkConstants.AccessNetworkType.CDMA2000: //fallthrough
+ case AccessNetworkConstants.AccessNetworkType.IWLAN:
+ return RADIO_ACCESS_TECHNOLOGY_OTHER;
+ default:
+ Slog.w(TAG,
+ "Unhandled RadioAccessNetworkType (" + dataType + "), mapping to OTHER");
+ return RADIO_ACCESS_TECHNOLOGY_OTHER;
+ }
+ }
+
@GuardedBy("this")
public void noteWifiOnLocked() {
noteWifiOnLocked(mClock.elapsedRealtime(), mClock.uptimeMillis());
@@ -13712,66 +13743,7 @@
mTmpRailStats.resetCellularTotalEnergyUsed();
}
- // Proportionally smear Rx and Tx times across each RAt
- final int levelCount = CellSignalStrength.getNumSignalStrengthLevels();
- long[] perSignalStrengthActiveTimeMs = new long[levelCount];
- long totalActiveTimeMs = 0;
-
- for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) {
- final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat];
- if (ratStats == null) continue;
-
- final int freqCount = ratStats.getFrequencyRangeCount();
- for (int freq = 0; freq < freqCount; freq++) {
- for (int level = 0; level < levelCount; level++) {
- final long durationMs = ratStats.getTimeSinceMark(freq, level,
- elapsedRealtimeMs);
- perSignalStrengthActiveTimeMs[level] += durationMs;
- totalActiveTimeMs += durationMs;
- }
- }
- }
-
- if (totalActiveTimeMs != 0) {
- // Smear the provided Tx/Rx durations across each RAT, frequency, and signal
- // strength.
- for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) {
- final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat];
- if (ratStats == null) continue;
-
- final int freqCount = ratStats.getFrequencyRangeCount();
- for (int freq = 0; freq < freqCount; freq++) {
- long frequencyDurationMs = 0;
- for (int level = 0; level < levelCount; level++) {
- final long durationMs = ratStats.getTimeSinceMark(freq, level,
- elapsedRealtimeMs);
- final long totalLvlDurationMs =
- perSignalStrengthActiveTimeMs[level];
- if (totalLvlDurationMs == 0) continue;
- final long totalTxLvlDurations =
- deltaInfo.getTransmitDurationMillisAtPowerLevel(level);
- // Smear HAL provided Tx power level duration based on active modem
- // duration in a given state. (Add totalLvlDurationMs / 2 before
- // the integer division with totalLvlDurationMs for rounding.)
- final long proportionalTxDurationMs =
- (durationMs * totalTxLvlDurations
- + (totalLvlDurationMs / 2)) / totalLvlDurationMs;
- ratStats.incrementTxDuration(freq, level, proportionalTxDurationMs);
- frequencyDurationMs += durationMs;
- }
- final long totalRxDuration = deltaInfo.getReceiveTimeMillis();
- // Smear HAL provided Rx power duration based on active modem
- // duration in a given state. (Add totalActiveTimeMs / 2 before the
- // integer division with totalActiveTimeMs for rounding.)
- final long proportionalRxDurationMs =
- (frequencyDurationMs * totalRxDuration + (totalActiveTimeMs
- / 2)) / totalActiveTimeMs;
- ratStats.incrementRxDuration(freq, proportionalRxDurationMs);
- }
-
- ratStats.setMark(elapsedRealtimeMs);
- }
- }
+ incrementPerRatDataLocked(deltaInfo, elapsedRealtimeMs);
}
long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
elapsedRealtimeMs * 1000);
@@ -13922,6 +13894,100 @@
}
}
+ @GuardedBy("this")
+ private void incrementPerRatDataLocked(ModemActivityInfo deltaInfo, long elapsedRealtimeMs) {
+ final int infoSize = deltaInfo.getSpecificInfoLength();
+ if (infoSize == 1 && deltaInfo.getSpecificInfoRat(0)
+ == AccessNetworkConstants.AccessNetworkType.UNKNOWN
+ && deltaInfo.getSpecificInfoFrequencyRange(0)
+ == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Specific info data unavailable. Proportionally smear Rx and Tx times across each RAT.
+ final int levelCount = CellSignalStrength.getNumSignalStrengthLevels();
+ long[] perSignalStrengthActiveTimeMs = new long[levelCount];
+ long totalActiveTimeMs = 0;
+
+ for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) {
+ final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat];
+ if (ratStats == null) continue;
+
+ final int freqCount = ratStats.getFrequencyRangeCount();
+ for (int freq = 0; freq < freqCount; freq++) {
+ for (int level = 0; level < levelCount; level++) {
+ final long durationMs = ratStats.getTimeSinceMark(freq, level,
+ elapsedRealtimeMs);
+ perSignalStrengthActiveTimeMs[level] += durationMs;
+ totalActiveTimeMs += durationMs;
+ }
+ }
+ }
+ if (totalActiveTimeMs != 0) {
+ // Smear the provided Tx/Rx durations across each RAT, frequency, and signal
+ // strength.
+ for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) {
+ final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat];
+ if (ratStats == null) continue;
+
+ final int freqCount = ratStats.getFrequencyRangeCount();
+ for (int freq = 0; freq < freqCount; freq++) {
+ long frequencyDurationMs = 0;
+ for (int level = 0; level < levelCount; level++) {
+ final long durationMs = ratStats.getTimeSinceMark(freq, level,
+ elapsedRealtimeMs);
+ final long totalLvlDurationMs =
+ perSignalStrengthActiveTimeMs[level];
+ if (totalLvlDurationMs == 0) continue;
+ final long totalTxLvlDurations =
+ deltaInfo.getTransmitDurationMillisAtPowerLevel(level);
+ // Smear HAL provided Tx power level duration based on active modem
+ // duration in a given state. (Add totalLvlDurationMs / 2 before
+ // the integer division with totalLvlDurationMs for rounding.)
+ final long proportionalTxDurationMs =
+ (durationMs * totalTxLvlDurations
+ + (totalLvlDurationMs / 2)) / totalLvlDurationMs;
+ ratStats.incrementTxDuration(freq, level, proportionalTxDurationMs);
+ frequencyDurationMs += durationMs;
+ }
+ final long totalRxDuration = deltaInfo.getReceiveTimeMillis();
+ // Smear HAL provided Rx power duration based on active modem
+ // duration in a given state. (Add totalActiveTimeMs / 2 before the
+ // integer division with totalActiveTimeMs for rounding.)
+ final long proportionalRxDurationMs =
+ (frequencyDurationMs * totalRxDuration + (totalActiveTimeMs
+ / 2)) / totalActiveTimeMs;
+ ratStats.incrementRxDuration(freq, proportionalRxDurationMs);
+ }
+
+ }
+ }
+ } else {
+ // Specific data available.
+ for (int index = 0; index < infoSize; index++) {
+ final int rat = deltaInfo.getSpecificInfoRat(index);
+ final int freq = deltaInfo.getSpecificInfoFrequencyRange(index);
+
+ // Map RadioAccessNetworkType to course grain RadioAccessTechnology.
+ final int ratBucket = mapRadioAccessNetworkTypeToRadioAccessTechnology(rat);
+ final RadioAccessTechnologyBatteryStats ratStats = getRatBatteryStatsLocked(
+ ratBucket);
+
+ final long rxTimeMs = deltaInfo.getReceiveTimeMillis(rat, freq);
+ final int[] txTimesMs = deltaInfo.getTransmitTimeMillis(rat, freq);
+
+ ratStats.incrementRxDuration(freq, rxTimeMs);
+ final int numTxLvl = txTimesMs.length;
+ for (int lvl = 0; lvl < numTxLvl; lvl++) {
+ ratStats.incrementTxDuration(freq, lvl, txTimesMs[lvl]);
+ }
+ }
+ }
+
+ for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) {
+ final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat];
+ if (ratStats == null) continue;
+ ratStats.setMark(elapsedRealtimeMs);
+ }
+ }
+
/**
* Add modem tx power to history
* Device is said to be in high cellular transmit power when it has spent most of the transmit
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsStore.java b/core/java/com/android/internal/os/BatteryUsageStatsStore.java
index af82f40..09c9cfc 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsStore.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsStore.java
@@ -22,6 +22,7 @@
import android.os.BatteryUsageStatsQuery;
import android.os.Handler;
import android.util.AtomicFile;
+import android.util.Log;
import android.util.LongArray;
import android.util.Slog;
import android.util.TypedXmlPullParser;
@@ -47,6 +48,7 @@
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
+import java.util.concurrent.locks.ReentrantLock;
/**
* A storage mechanism for BatteryUsageStats snapshots.
@@ -73,6 +75,8 @@
private boolean mSystemReady;
private final File mStoreDir;
private final File mLockFile;
+ private final ReentrantLock mFileLock = new ReentrantLock();
+ private FileLock mJvmLock;
private final AtomicFile mConfigFile;
private final long mMaxStorageBytes;
private final Handler mHandler;
@@ -120,11 +124,11 @@
}
private void storeBatteryUsageStats(BatteryUsageStats stats) {
- try (FileLock lock = lockSnapshotDirectory()) {
+ lockSnapshotDirectory();
+ try {
if (!mStoreDir.exists()) {
if (!mStoreDir.mkdirs()) {
- Slog.e(TAG,
- "Could not create a directory for battery usage stats snapshots");
+ Slog.e(TAG, "Could not create a directory for battery usage stats snapshots");
return;
}
}
@@ -136,8 +140,8 @@
}
removeOldSnapshotsLocked();
- } catch (IOException e) {
- Slog.e(TAG, "Cannot lock battery usage stats directory", e);
+ } finally {
+ unlockSnapshotDirectory();
}
}
@@ -147,7 +151,8 @@
*/
public long[] listBatteryUsageStatsTimestamps() {
LongArray timestamps = new LongArray(100);
- try (FileLock lock = lockSnapshotDirectory()) {
+ lockSnapshotDirectory();
+ try {
for (File file : mStoreDir.listFiles()) {
String fileName = file.getName();
if (fileName.endsWith(SNAPSHOT_FILE_EXTENSION)) {
@@ -161,8 +166,8 @@
}
}
}
- } catch (IOException e) {
- Slog.e(TAG, "Cannot lock battery usage stats directory", e);
+ } finally {
+ unlockSnapshotDirectory();
}
return timestamps.toArray();
}
@@ -173,15 +178,16 @@
*/
@Nullable
public BatteryUsageStats loadBatteryUsageStats(long timestamp) {
- try (FileLock lock = lockSnapshotDirectory()) {
+ lockSnapshotDirectory();
+ try {
File file = makeSnapshotFilename(timestamp);
try {
return readXmlFileLocked(file);
} catch (Exception e) {
Slog.e(TAG, "Cannot read battery usage stats", e);
}
- } catch (IOException e) {
- Slog.e(TAG, "Cannot lock battery usage stats directory", e);
+ } finally {
+ unlockSnapshotDirectory();
}
return null;
}
@@ -192,7 +198,8 @@
*/
public void setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(long timestamp) {
Properties props = new Properties();
- try (FileLock lock = lockSnapshotDirectory()) {
+ lockSnapshotDirectory();
+ try {
try (InputStream in = mConfigFile.openRead()) {
props.load(in);
} catch (IOException e) {
@@ -209,8 +216,8 @@
mConfigFile.failWrite(out);
Slog.e(TAG, "Cannot save config file " + mConfigFile, e);
}
- } catch (IOException e) {
- Slog.e(TAG, "Cannot lock battery usage stats directory", e);
+ } finally {
+ unlockSnapshotDirectory();
}
}
@@ -220,23 +227,41 @@
*/
public long getLastBatteryUsageStatsBeforeResetAtomPullTimestamp() {
Properties props = new Properties();
- try (FileLock lock = lockSnapshotDirectory()) {
+ lockSnapshotDirectory();
+ try {
try (InputStream in = mConfigFile.openRead()) {
props.load(in);
} catch (IOException e) {
Slog.e(TAG, "Cannot load config file " + mConfigFile, e);
}
- } catch (IOException e) {
- Slog.e(TAG, "Cannot lock battery usage stats directory", e);
+ } finally {
+ unlockSnapshotDirectory();
}
return Long.parseLong(
props.getProperty(BATTERY_USAGE_STATS_BEFORE_RESET_TIMESTAMP_PROPERTY, "0"));
}
- private FileLock lockSnapshotDirectory() throws IOException {
- mLockFile.getParentFile().mkdirs();
- mLockFile.createNewFile();
- return FileChannel.open(mLockFile.toPath(), StandardOpenOption.WRITE).lock();
+ private void lockSnapshotDirectory() {
+ mFileLock.lock();
+
+ // Lock the directory from access by other JVMs
+ try {
+ mLockFile.getParentFile().mkdirs();
+ mLockFile.createNewFile();
+ mJvmLock = FileChannel.open(mLockFile.toPath(), StandardOpenOption.WRITE).lock();
+ } catch (IOException e) {
+ Log.e(TAG, "Cannot lock snapshot directory", e);
+ }
+ }
+
+ private void unlockSnapshotDirectory() {
+ try {
+ mJvmLock.close();
+ } catch (IOException e) {
+ Log.e(TAG, "Cannot unlock snapshot directory", e);
+ } finally {
+ mFileLock.unlock();
+ }
}
/**
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java
index fd8534d..e2d2505 100644
--- a/core/java/com/android/internal/policy/TransitionAnimation.java
+++ b/core/java/com/android/internal/policy/TransitionAnimation.java
@@ -101,6 +101,10 @@
private static final String DEFAULT_PACKAGE = "android";
+ // TODO (b/215515255): remove once we full migrate to shell transitions
+ private static final boolean SHELL_TRANSITIONS_ENABLED =
+ SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
+
private final Context mContext;
private final String mTag;
@@ -255,6 +259,9 @@
resId = ent.array.getResourceId(animAttr, 0);
}
}
+ if (!SHELL_TRANSITIONS_ENABLED) {
+ resId = updateToLegacyIfNeeded(resId);
+ }
resId = updateToTranslucentAnimIfNeeded(resId, transit);
if (ResourceId.isValid(resId)) {
return loadAnimationSafely(context, resId, mTag);
@@ -262,6 +269,24 @@
return null;
}
+ /**
+ * Replace animations that are not compatible with the legacy transition system with ones that
+ * are compatible with it.
+ * TODO (b/215515255): remove once we full migrate to shell transitions
+ */
+ private int updateToLegacyIfNeeded(int anim) {
+ if (anim == R.anim.activity_open_enter) {
+ return R.anim.activity_open_enter_legacy;
+ } else if (anim == R.anim.activity_open_exit) {
+ return R.anim.activity_open_exit_legacy;
+ } else if (anim == R.anim.activity_close_enter) {
+ return R.anim.activity_close_enter_legacy;
+ } else if (anim == R.anim.activity_close_exit) {
+ return R.anim.activity_close_exit_legacy;
+ }
+ return anim;
+ }
+
/** Load animation by attribute Id from a specific AnimationStyle resource. */
@Nullable
public Animation loadAnimationAttr(String packageName, int animStyleResId, int animAttr,
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 52f0fb5..fe77236 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -50,7 +50,7 @@
@Override
public void resized(ClientWindowFrames frames, boolean reportDraw,
- MergedConfiguration mergedConfiguration, boolean forceLayout,
+ MergedConfiguration mergedConfiguration, InsetsState insetsState, boolean forceLayout,
boolean alwaysConsumeSystemBars, int displayId, int seqId, int resizeMode) {
if (reportDraw) {
try {
@@ -61,12 +61,8 @@
}
@Override
- public void insetsChanged(InsetsState insetsState, boolean willMove, boolean willResize) {
- }
-
- @Override
public void insetsControlChanged(InsetsState insetsState,
- InsetsSourceControl[] activeControls, boolean willMove, boolean willResize) {
+ InsetsSourceControl[] activeControls) {
}
@Override
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 01cec77..fc5da13 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -35,7 +35,6 @@
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
-import android.media.AudioManager;
import android.os.Bundle;
import android.os.Debug;
import android.os.Parcel;
@@ -78,8 +77,6 @@
private static final boolean PROFILE_DRAWING = false;
private static final int LINE_END_ANIMATION_DURATION_MILLIS = 50;
- private static final int LINE_FADE_OUT_DURATION_MILLIS = 500;
- private static final int LINE_FADE_OUT_DELAY_MILLIS = 150;
private static final int DOT_ACTIVATION_DURATION_MILLIS = 50;
private static final int DOT_RADIUS_INCREASE_DURATION_MILLIS = 96;
private static final int DOT_RADIUS_DECREASE_DURATION_MILLIS = 192;
@@ -90,6 +87,8 @@
private final int mDotSizeActivated;
private final float mDotHitFactor;
private final int mPathWidth;
+ private final int mLineFadeOutAnimationDurationMs;
+ private final int mLineFadeOutAnimationDelayMs;
private boolean mDrawingProfilingStarted = false;
@@ -347,6 +346,11 @@
mPathWidth = getResources().getDimensionPixelSize(R.dimen.lock_pattern_dot_line_width);
mPathPaint.setStrokeWidth(mPathWidth);
+ mLineFadeOutAnimationDurationMs =
+ getResources().getInteger(R.integer.lock_pattern_line_fade_out_duration);
+ mLineFadeOutAnimationDelayMs =
+ getResources().getInteger(R.integer.lock_pattern_line_fade_out_delay);
+
mDotSize = getResources().getDimensionPixelSize(R.dimen.lock_pattern_dot_size);
mDotSizeActivated = getResources().getDimensionPixelSize(
R.dimen.lock_pattern_dot_size_activated);
@@ -769,8 +773,7 @@
}
addCellToPattern(cell);
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
- HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
- | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
return cell;
}
return null;
@@ -833,7 +836,7 @@
deactivateAnimator.setDuration(DOT_ACTIVATION_DURATION_MILLIS);
AnimatorSet set = new AnimatorSet();
set.play(deactivateAnimator)
- .after(LINE_FADE_OUT_DELAY_MILLIS + LINE_FADE_OUT_DURATION_MILLIS
+ .after(mLineFadeOutAnimationDelayMs + mLineFadeOutAnimationDurationMs
- DOT_ACTIVATION_DURATION_MILLIS * 2)
.after(activateAnimator);
return set;
@@ -864,8 +867,8 @@
private Animator createLineDisappearingAnimation() {
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.addUpdateListener(animation -> invalidate());
- valueAnimator.setStartDelay(LINE_FADE_OUT_DELAY_MILLIS);
- valueAnimator.setDuration(LINE_FADE_OUT_DURATION_MILLIS);
+ valueAnimator.setStartDelay(mLineFadeOutAnimationDelayMs);
+ valueAnimator.setDuration(mLineFadeOutAnimationDurationMs);
return valueAnimator;
}
@@ -1280,14 +1283,14 @@
float fadeAwayProgress;
if (mFadePattern) {
if (elapsedRealtime - lineFadeStart
- >= LINE_FADE_OUT_DELAY_MILLIS + LINE_FADE_OUT_DURATION_MILLIS) {
+ >= mLineFadeOutAnimationDelayMs + mLineFadeOutAnimationDurationMs) {
// Time for this segment animation is out so we don't need to draw it.
return;
}
// Set this line segment to fade away animated.
fadeAwayProgress = Math.max(
- ((float) (elapsedRealtime - lineFadeStart - LINE_FADE_OUT_DELAY_MILLIS))
- / LINE_FADE_OUT_DURATION_MILLIS, 0f);
+ ((float) (elapsedRealtime - lineFadeStart - mLineFadeOutAnimationDelayMs))
+ / mLineFadeOutAnimationDurationMs, 0f);
drawFadingAwayLineSegment(canvas, startX, startY, endX, endY, fadeAwayProgress);
} else {
mPathPaint.setAlpha(255);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b0d5fb6..0353e4b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -719,6 +719,92 @@
<protected-broadcast android:name="android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED" />
<protected-broadcast android:name="android.app.action.SHOW_NEW_USER_DISCLAIMER" />
+ <!-- Moved from packages/services/Telephony in T -->
+ <protected-broadcast android:name="android.telecom.action.CURRENT_TTY_MODE_CHANGED" />
+ <protected-broadcast android:name="android.intent.action.SERVICE_STATE" />
+ <protected-broadcast android:name="android.intent.action.RADIO_TECHNOLOGY" />
+ <protected-broadcast android:name="android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED" />
+ <protected-broadcast android:name="android.intent.action.EMERGENCY_CALL_STATE_CHANGED" />
+ <protected-broadcast android:name="android.intent.action.SIG_STR" />
+ <protected-broadcast android:name="android.intent.action.ANY_DATA_STATE" />
+ <protected-broadcast android:name="android.intent.action.DATA_STALL_DETECTED" />
+ <protected-broadcast android:name="android.intent.action.SIM_STATE_CHANGED" />
+ <protected-broadcast android:name="android.intent.action.USER_ACTIVITY_NOTIFICATION" />
+ <protected-broadcast android:name="android.telephony.action.SHOW_NOTICE_ECM_BLOCK_OTHERS" />
+ <protected-broadcast android:name="android.intent.action.ACTION_MDN_STATE_CHANGED" />
+ <protected-broadcast android:name="android.telephony.action.SERVICE_PROVIDERS_UPDATED" />
+ <protected-broadcast android:name="android.provider.Telephony.SIM_FULL" />
+ <protected-broadcast android:name="com.android.internal.telephony.carrier_key_download_alarm" />
+ <protected-broadcast android:name="com.android.internal.telephony.data-restart-trysetup" />
+ <protected-broadcast android:name="com.android.internal.telephony.data-stall" />
+ <protected-broadcast android:name="com.android.internal.telephony.provisioning_apn_alarm" />
+ <protected-broadcast android:name="android.intent.action.DATA_SMS_RECEIVED" />
+ <protected-broadcast android:name="android.provider.Telephony.SMS_RECEIVED" />
+ <protected-broadcast android:name="android.provider.Telephony.SMS_DELIVER" />
+ <protected-broadcast android:name="android.provider.Telephony.SMS_REJECTED" />
+ <protected-broadcast android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
+ <protected-broadcast android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
+ <protected-broadcast android:name="android.provider.Telephony.SMS_CB_RECEIVED" />
+ <protected-broadcast android:name="android.provider.action.SMS_EMERGENCY_CB_RECEIVED" />
+ <protected-broadcast android:name="android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED" />
+ <protected-broadcast android:name="android.provider.Telephony.SECRET_CODE" />
+ <protected-broadcast android:name="com.android.internal.stk.command" />
+ <protected-broadcast android:name="com.android.internal.stk.session_end" />
+ <protected-broadcast android:name="com.android.internal.stk.icc_status_change" />
+ <protected-broadcast android:name="com.android.internal.stk.alpha_notify" />
+ <protected-broadcast android:name="com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" />
+ <protected-broadcast android:name="com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED" />
+ <protected-broadcast android:name="com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE" />
+ <protected-broadcast android:name="com.android.internal.telephony.CARRIER_SIGNAL_RESET" />
+ <protected-broadcast android:name="com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE" />
+ <protected-broadcast android:name="com.android.internal.telephony.PROVISION" />
+ <protected-broadcast android:name="com.android.internal.telephony.ACTION_LINE1_NUMBER_ERROR_DETECTED" />
+ <protected-broadcast android:name="com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED" />
+ <protected-broadcast android:name="com.android.intent.isim_refresh" />
+ <protected-broadcast android:name="com.android.ims.ACTION_RCS_SERVICE_AVAILABLE" />
+ <protected-broadcast android:name="com.android.ims.ACTION_RCS_SERVICE_UNAVAILABLE" />
+ <protected-broadcast android:name="com.android.ims.ACTION_RCS_SERVICE_DIED" />
+ <protected-broadcast android:name="com.android.ims.ACTION_PRESENCE_CHANGED" />
+ <protected-broadcast android:name="com.android.ims.ACTION_PUBLISH_STATUS_CHANGED" />
+ <protected-broadcast android:name="com.android.ims.IMS_SERVICE_UP" />
+ <protected-broadcast android:name="com.android.ims.IMS_SERVICE_DOWN" />
+ <protected-broadcast android:name="com.android.ims.IMS_INCOMING_CALL" />
+ <protected-broadcast android:name="com.android.ims.internal.uce.UCE_SERVICE_UP" />
+ <protected-broadcast android:name="com.android.ims.internal.uce.UCE_SERVICE_DOWN" />
+ <protected-broadcast android:name="com.android.imsconnection.DISCONNECTED" />
+ <protected-broadcast android:name="com.android.intent.action.IMS_FEATURE_CHANGED" />
+ <protected-broadcast android:name="com.android.intent.action.IMS_CONFIG_CHANGED" />
+ <protected-broadcast android:name="android.telephony.ims.action.WFC_IMS_REGISTRATION_ERROR" />
+ <protected-broadcast android:name="com.android.phone.vvm.omtp.sms.REQUEST_SENT" />
+ <protected-broadcast android:name="com.android.phone.vvm.ACTION_VISUAL_VOICEMAIL_SERVICE_EVENT" />
+ <protected-broadcast android:name="com.android.internal.telephony.CARRIER_VVM_PACKAGE_INSTALLED" />
+ <protected-broadcast android:name="com.android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO" />
+ <protected-broadcast android:name="com.android.internal.telephony.ACTION_CARRIER_CERTIFICATE_DOWNLOAD" />
+ <protected-broadcast android:name="com.android.internal.telephony.action.COUNTRY_OVERRIDE" />
+ <protected-broadcast android:name="com.android.internal.telephony.OPEN_DEFAULT_SMS_APP" />
+ <protected-broadcast android:name="com.android.internal.telephony.ACTION_TEST_OVERRIDE_CARRIER_ID" />
+ <protected-broadcast android:name="android.telephony.action.SIM_CARD_STATE_CHANGED" />
+ <protected-broadcast android:name="android.telephony.action.SIM_APPLICATION_STATE_CHANGED" />
+ <protected-broadcast android:name="android.telephony.action.SIM_SLOT_STATUS_CHANGED" />
+ <protected-broadcast android:name="android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED" />
+ <protected-broadcast android:name="android.telephony.action.SUBSCRIPTION_SPECIFIC_CARRIER_IDENTITY_CHANGED" />
+ <protected-broadcast android:name="android.telephony.action.TOGGLE_PROVISION" />
+ <protected-broadcast android:name="android.telephony.action.NETWORK_COUNTRY_CHANGED" />
+ <protected-broadcast android:name="android.telephony.action.PRIMARY_SUBSCRIPTION_LIST_CHANGED" />
+ <protected-broadcast android:name="android.telephony.action.MULTI_SIM_CONFIG_CHANGED" />
+ <protected-broadcast android:name="android.telephony.action.CARRIER_SIGNAL_RESET" />
+ <protected-broadcast android:name="android.telephony.action.CARRIER_SIGNAL_PCO_VALUE" />
+ <protected-broadcast android:name="android.telephony.action.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE" />
+ <protected-broadcast android:name="android.telephony.action.CARRIER_SIGNAL_REDIRECTED" />
+ <protected-broadcast android:name="android.telephony.action.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED" />
+ <protected-broadcast android:name="com.android.phone.settings.CARRIER_PROVISIONING" />
+ <protected-broadcast android:name="com.android.phone.settings.TRIGGER_CARRIER_PROVISIONING" />
+ <protected-broadcast android:name="com.android.internal.telephony.ACTION_VOWIFI_ENABLED" />
+ <protected-broadcast android:name="android.telephony.action.ANOMALY_REPORTED" />
+ <protected-broadcast android:name="android.intent.action.SUBSCRIPTION_INFO_RECORD_ADDED" />
+ <protected-broadcast android:name="android.intent.action.ACTION_MANAGED_ROAMING_IND" />
+ <protected-broadcast android:name="android.telephony.ims.action.RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE" />
+
<!-- Added in T -->
<protected-broadcast android:name="android.safetycenter.action.REFRESH_SAFETY_SOURCES" />
<protected-broadcast android:name="android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED" />
@@ -3736,29 +3822,6 @@
<permission android:name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL"
android:protectionLevel="signature|privileged" />
- <!-- ========================================= -->
- <!-- Permissions for AdServices -->
- <!-- ========================================= -->
- <eat-comment />
-
- <!-- Allows an application to access AdServices Topics API. -->
- <permission android:name="android.permission.ACCESS_ADSERVICES_TOPICS"
- android:label="@string/permlab_accessAdServicesTopics"
- android:description="@string/permdesc_accessAdServicesTopics"
- android:protectionLevel="normal" />
-
- <!-- Allows an application to access AdServices Attribution APIs. -->
- <permission android:name="android.permission.ACCESS_ADSERVICES_ATTRIBUTION"
- android:label="@string/permlab_accessAdServicesAttribution"
- android:description="@string/permdesc_accessAdServicesAttribution"
- android:protectionLevel="normal" />
-
- <!-- Allows an application to access AdServices Custom Audiences APIs. -->
- <permission android:name="android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCES"
- android:label="@string/permlab_accessAdServicesCustomAudiences"
- android:description="@string/permdesc_accessAdServicesCustomAudiences"
- android:protectionLevel="normal" />
-
<!-- ==================================== -->
<!-- Private permissions -->
<!-- ==================================== -->
@@ -4445,21 +4508,41 @@
For more details, see <a
href="{@docRoot}about/versions/12/behavior-changes-12#exact-alarm-permission">
Exact alarm permission</a>.
- <p>Apps who hold this permission and target API level 31 or above, always stay in the
+ <p>Apps need to target API {@link android.os.Build.VERSION_CODES#S} or above to be able to
+ request this permission. Note that apps targeting lower API levels do not need this
+ permission to use exact alarm APIs.
+ <p>Apps that hold this permission, always stay in the
{@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_WORKING_SET WORKING_SET} or
lower standby bucket.
- Applications targeting API level 30 or below do not need this permission to use
- exact alarm APIs.
+ <p>If your app relies on exact alarms for core functionality, it can instead request
+ {@link android.Manifest.permission#USE_EXACT_ALARM} once it targets API
+ {@link android.os.Build.VERSION_CODES#TIRAMISU}. All apps using exact alarms for secondary
+ features (which should still be user facing) should continue using this permission.
-->
<permission android:name="android.permission.SCHEDULE_EXACT_ALARM"
android:protectionLevel="normal|appop"/>
- <!-- Allows apps to use exact alarms just like with SCHEDULE_EXACT_ALARM but without needing
- to request this permission from the user.
- <p><b>This is only for apps that rely on exact alarms for their core functionality.</b>
- App stores may enforce policies to audit and review the use of this permission. Any app that
- requests this but is found to not require exact alarms for its primary function may be
- removed from the app store.
+ <!-- Allows apps to use exact alarms just like with {@link
+ android.Manifest.permission#SCHEDULE_EXACT_ALARM} but without needing to request this
+ permission from the user.
+ <p><b> This is only intended for use by apps that rely on exact alarms for their core
+ functionality.</b> You should continue using {@code SCHEDULE_EXACT_ALARM} if your app needs
+ exact alarms for a secondary feature that users may or may not use within your app.
+ <p> Keep in mind that this is a powerful permission and app stores may enforce policies to
+ audit and review the use of this permission. Such audits may involve removal from the app
+ store if the app is found to be misusing this permission.
+ <p> Apps need to target API {@link android.os.Build.VERSION_CODES#TIRAMISU} or above to be
+ able to request this permission. Note that only one of {@code USE_EXACT_ALARM} or
+ {@code SCHEDULE_EXACT_ALARM} should be requested on a device. If your app is already using
+ {@code SCHEDULE_EXACT_ALARM} on older SDKs but need {@code USE_EXACT_ALARM} on SDK 33 and
+ above, then {@code SCHEDULE_EXACT_ALARM} should be declared with a max-sdk attribute, like:
+ <pre>
+ <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"
+ 	 android:maxSdkVersion="32" />
+ </pre>
+ <p>Apps that hold this permission, always stay in the
+ {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_WORKING_SET WORKING_SET} or
+ lower standby bucket.
-->
<permission android:name="android.permission.USE_EXACT_ALARM"
android:protectionLevel="normal"/>
@@ -6015,7 +6098,7 @@
<!-- @SystemApi Allows an application to turn on / off quiet mode.
@hide -->
<permission android:name="android.permission.MODIFY_QUIET_MODE"
- android:protectionLevel="signature|privileged|development" />
+ android:protectionLevel="signature|privileged|development|role" />
<!-- Allows internal management of the camera framework
@hide -->
@@ -6862,6 +6945,9 @@
</intent-filter>
</receiver>
+ <!-- Broadcast Receiver listen to sufficient verifier requests from Package Manager
+ when install new SDK, to verifier SDK code during installation time
+ and terminate install if SDK not compatible with privacy sandbox restrictions. -->
<receiver android:name="com.android.server.sdksandbox.SdkSandboxVerifierReceiver"
android:exported="false">
<intent-filter>
diff --git a/core/res/res/anim/activity_close_enter_legacy.xml b/core/res/res/anim/activity_close_enter_legacy.xml
new file mode 100644
index 0000000..9fa7c54
--- /dev/null
+++ b/core/res/res/anim/activity_close_enter_legacy.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <scale
+ android:fromXScale="1.1"
+ android:toXScale="1"
+ android:fromYScale="1.1"
+ android:toYScale="1"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="400"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/activity_close_exit_legacy.xml b/core/res/res/anim/activity_close_exit_legacy.xml
new file mode 100644
index 0000000..1599ae8
--- /dev/null
+++ b/core/res/res/anim/activity_close_exit_legacy.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false"
+ android:zAdjustment="top">
+ <alpha
+ android:fromAlpha="1"
+ android:toAlpha="0.0"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/linear"
+ android:startOffset="33"
+ android:duration="50"/>
+ <scale
+ android:fromXScale="1"
+ android:toXScale="0.9"
+ android:fromYScale="1"
+ android:toYScale="0.9"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="400"/>
+</set>
diff --git a/core/res/res/anim/activity_open_enter_legacy.xml b/core/res/res/anim/activity_open_enter_legacy.xml
new file mode 100644
index 0000000..38d3e8ed
--- /dev/null
+++ b/core/res/res/anim/activity_open_enter_legacy.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <alpha
+ android:fromAlpha="0"
+ android:toAlpha="1.0"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/linear"
+ android:startOffset="50"
+ android:duration="50"/>
+ <scale
+ android:fromXScale="0.85"
+ android:toXScale="1"
+ android:fromYScale="0.85"
+ android:toYScale="1"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="400"/>
+</set>
diff --git a/core/res/res/anim/activity_open_exit_legacy.xml b/core/res/res/anim/activity_open_exit_legacy.xml
new file mode 100644
index 0000000..3865d21
--- /dev/null
+++ b/core/res/res/anim/activity_open_exit_legacy.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+
+ <!-- Fade out, over a black surface, which simulates a black scrim -->
+ <alpha
+ android:fromAlpha="1"
+ android:toAlpha="0.4"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/linear"
+ android:startOffset="83"
+ android:duration="167"/>
+
+ <scale
+ android:fromXScale="1"
+ android:toXScale="1.05"
+ android:fromYScale="1"
+ android:toYScale="1.05"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fillEnabled="true"
+ android:fillBefore="true"
+ android:fillAfter="true"
+ android:interpolator="@interpolator/fast_out_extra_slow_in"
+ android:duration="400"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 8c01f4f..99d8784 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Tydelik deur jou diensverskaffer afgeskakel vir SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Kan nie selnetwerk bereik nie"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probeer die voorkeurnetwerk verander. Tik om te verander."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Noodoproepe is onbeskikbaar"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Kan nie noodoproepe oor Wi-Fi maak nie"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Noodoproepe is dalk nie beskikbaar nie"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> steun nie noodoproepe oor wi-fi nie. Tik vir besonderhede."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Opletberigte"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Oproepaanstuur"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Noodterugbel-modus"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Laat die program toe om jou tablet se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Laat die program toe om jou Android TV-toestel se oproeprekord te wysig, insluitend data oor inkomende en uitgaande oproepe. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te wysig."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Laat die program toe om jou foon se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"verkry toegang tot liggaamsensors (soos hartklopmonitors)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Toegang tot data vanaf liggaamsensors, soos polsslag, temperatuur, bloedsuurstofpersentasie, ens."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"gaan by liggaamsensors in (soos polsslagmonitors) terwyl dit op die agtergrond is"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Toegang tot data vanaf liggaamsensors, soos polsslag, temperatuur, bloedsuurstofpersentasie, ens. terwyl dit op die agtergrond is."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program gebruik word"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl dit program gebruik word."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program op agtergrond is"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl dit op die agtergrond is."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Lees kalendergebeurtenisse en -besonderhede"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Hierdie program kan alle kalendergebeurtenisse lees wat op jou tablet geberg is of jou kalenderdata stoor."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Hierdie program kan alle kalendergeleenthede wat op jou Android TV-toestel geberg is, lees of jou kalenderdata stoor."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Laat die program toe om oudiolêers in jou gedeelde berging te lees."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"lees videolêers in gedeelde berging"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Laat die program toe om videolêers in jou gedeelde berging te lees."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"lees prentlêers in gedeelde berging"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Laat die program toe om prentlêers in jou gedeelde berging te lees."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"lees prentlêers in gedeelde berging"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Laat die program toe om prentlêers in jou gedeelde berging te lees."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"verander of vee jou gedeelde berging se inhoud uit"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Laat die program toe om jou gedeelde berging se inhoud te skryf."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"maak en/of ontvang SIP-oproepe"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Druk kieslys om oop te sluit of maak noodoproep."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Druk kieslys om oop te maak."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Teken patroon om te ontsluit"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Noodoproep"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Noodgeval"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Keer terug na oproep"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Reg!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Probeer weer"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nooit"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Jy hoef nie toestemming te hê om hierdie bladsy oop te maak nie."</string>
<string name="text_copied" msgid="2531420577879738860">"Teks na knipbord gekopieër."</string>
- <string name="copied" msgid="4675902854553014676">"Gekopieer"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> het uit <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> geplak"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> het van jou knipbord af geplak"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> het teks geplak wat jy gekopieer het"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Laat \'n program toe om toestemming te vra om batteryoptimerings vir daardie program ignoreer."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"navraag oor alle pakkette"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Laat \'n program toe om alle geïnstalleerde pakette te sien."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"verkry toegang tot SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Gee \'n program toegang tot SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"kry toegang tot AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Gee ’n program toegang tot AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"kry toegang tot AdServices Attribution API\'s"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Gee ’n program toegang tot AdServices Attribution API\'s."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"kry toegang tot AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Gee ’n program toegang tot AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Klop twee keer vir zoembeheer"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Kon nie legstuk byvoeg nie."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Gaan"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Skakel tans oor na <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Meld <xliff:g id="NAME">%1$s</xliff:g> tans af …"</string>
<string name="owner_name" msgid="8713560351570795743">"Eienaar"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gas"</string>
<string name="error_message_title" msgid="4082495589294631966">"Fout"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Jou administrateur laat nie hierdie verandering toe nie"</string>
<string name="app_not_found" msgid="3429506115332341800">"Geen program gevind om hierdie handeling te hanteer nie"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DEΪNSTALLEER"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"MAAK TOG OOP"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Skadelike program is bespeur"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Stelselloglêertoegangsversoek"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Gee <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> toegang tot alle toestelloglêers?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Net hierdie keer"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Moenie toelaat nie"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> versoek stelselloglêers vir funksionele ontfouting. Hierdie loglêers bevat dalk inligting wat programme en dienste op jou toestel geskryf het."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Toestelloglêers teken aan wat op jou toestel gebeur. Programme kan hierdie loglêers gebruik om kwessies op te spoor en reg te stel.\n\nSommige loglêers bevat dalk sensitiewe inligting en daarom moet jy toegang tot alle toestelloglêers net gee aan programme wat jy vertrou. \n\nAs jy nie vir hierdie program toegang tot alle toestelloglêers gee nie, het dit steeds toegang tot sy eie loglêers, en jou toestelvervaardiger het dalk steeds toegang tot sommige loglêers of inligting op jou toestel. Kom meer te wete"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Moenie weer wys nie"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wil <xliff:g id="APP_2">%2$s</xliff:g>-skyfies wys"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Wysig"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> werk al vir \'n lang tyd op die agtergrond. Tik om na te gaan."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Gaan aktiewe programme na"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Kan nie toegang tot kamera van hierdie toestel af kry nie"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 7197216..a6b04c9c 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"ለሲም <xliff:g id="SIMNUMBER">%d</xliff:g> ለጊዜው በእርስዎ አገልግሎት አቅራቢ ጠፍቷል"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"የሞባይል አውታረ መረብን መድረስ አልተቻለም"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ተመራጭ አውታረ መረብን ለመለወጥ ይሞክሩ። ለመለወጥ መታ ያድርጉ።"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"የአደጋ ጊዜ ጥሪ አይገኝም"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"በWi‑Fi በኩል የአደጋ ጊዜ ጥሪዎችን ማድረግ አይችልም"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"የአደጋ ጊዜ ጥሪዎች ላይገኙ ይችላሉ"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> በWi-Fi ላይ የአደጋ ጊዜ ጥሪዎችን አይደግፍም። ዝርዝሮችን ለማግኘት መታ ያድርጉ።"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"ማንቂያዎች"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"ጥሪ ማስተላለፍ"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"የአደጋ ጊዜ ጥሪ ሁነታ"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የጡባዊተኮህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ።"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"መተግበሪያው ስለገቢ እና ወጪ ጥሪዎች ያለ ውሂብም ጨምሮ የእርስዎ Android TV መሣሪያ ምዝግብ ማስታወሻ እንዲቀይር ያስችለዋል። ተንኮል-አዘል መተግበሪያዎች ይህን ተጠቅመው የስልክዎን ምዝግብ ማስታወሻ ሊደመስሱ ወይም ሊቀይሩ ይችላሉ።"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የስልክህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ።"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"የሰውነት ዳሳሾችን መድረስ (እንደ የልብ ምት መከታተያዎች ያሉ)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"እንደ የልብ ምት፣ የሙቀት መጠን፣ የደም ኦክሲጅን መቶኛ፣ ወዘተ ያሉ የሰውነት ዳሳሾች ውሂብን መድረስ።"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"ከበስተጀርባ እያለ የሰውነት ዳሳሾችን (እንደ የልብ ምት መቆጣጠሪያዎች) መድረስ"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"ከበስተጀርባ እያለ እንደ የልብ ምት፣ የሙቀት መጠን፣ የደም ኦክሲጅን መቶኛ፣ ወዘተ ያሉ የሰውነት ዳሳሾች ውሂብን መድረስ።"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ስራ ላይ በሚውልበት ጊዜ እንደ የልብ ምት ያለ የሰውነት ዳሳሽ ውሂብን መድረስ"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"መተግበሪያው ስራ ላይ በሚውልበት ጊዜ እንደ የልብ ምት፣ የሙቀት መጠን እና የደም ኦክሲጅን መቶኛ ያለ የሰውነት ዳሳሽ ውሂብን እንዲደርስ ያስችለዋል።"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ከበስተጀርባ እያለ እንደ የልብ ምት ያለ የሰውነት ዳሳሽ ውሂብን መድረስ"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"መተግበሪያው ከበስተጀርባ እያለ እንደ የልብ ምት፣ የሙቀት መጠን እና የደም ኦክሲጅን መቶኛ ያለ የሰውነት ዳሳሽ ውሂብን እንዲደርስ ያስችለዋል።"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"የቀን መቁጠሪያ ክስተቶችን እና ዝርዝሮችን አንብብ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ይህ መተግበሪያ ሁሉንም በእርስዎ ጡባዊ ላይ የተከማቹ የቀን መቁጠሪያ ክስተቶችን ማንበብ ወይም የእርስዎን የቀን መቁጠሪያ ውሂብ ማስቀመጥ ይችላል።"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ይህ መተግበሪያ ሁሉንም በእርስዎ Android TV መሣሪያ ላይ የተከማቹ የቀን መቁጠሪያ ክስተቶችን ማንበብ ወይም የእርስዎን የቀን መቁጠሪያ ውሂብ ማስቀመጥ ይችላል።"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"መተግበሪያው ከእርስዎ የተጋራ ማከማቻ የድምጽ ፋይሎችን እንዲያነብ ይፈቅድለታል።"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"የቪዲዮ ፋይሎችን ከተጋራ ማከማቻ አንብብ"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"መተግበሪያው ከእርስዎ የተጋራ ማከማቻ የቪዲዮ ፋይሎችን እንዲያነብ ይፈቅድለታል።"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"ከጋራ ማከማቻ የምስል ፋይሎችን አንብብ"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"መተግበሪያው ከእርስዎ የተጋራ ማከማቻ የምስል ፋይሎችን እንዲያነብ ይፈቅድለታል።"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"ከጋራ ማከማቻ የምስል ፋይሎችን አንብብ"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"መተግበሪያው ከእርስዎ የተጋራ ማከማቻ የምስል ፋይሎችን እንዲያነብ ይፈቅድለታል።"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"የተጋራ ማከማቻዎን ይዘቶች ይቀይሩ ወይም ይሰርዙ"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"መተግበሪያው የእርስዎን የተጋራ ማከማቻ ይዘቶችን እንዲጽፍ ያስችለዋል።"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"የSIP ጥሪዎችን ያድርጉ/ይቀበሉ"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"ለመክፈት ምናሌ ተጫንወይም የአደጋ ጊዜ ጥሪ አድርግ።"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"ለመክፈት ምናሌ ተጫን"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"ለመክፈት ስርዓተ ጥለት ሳል"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"የአደጋ ጊዜ ጥሪ"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ድንገተኛ አደጋ"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"ወደ ጥሪ ተመለስ"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"ትክክል!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"እንደገና ሞክር"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"በፍፁም"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"ይህን ገጽ ለመክፈት ፈቃድ የለህም።"</string>
<string name="text_copied" msgid="2531420577879738860">"ፅሁፍ ወደ ቅንጥብ ሰሌዳ ተገልብጧል።"</string>
- <string name="copied" msgid="4675902854553014676">"ተቀድቷል"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ከ <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ተለጥፏል"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ከእርስዎ ቅንጥብ ሰሌዳ ተለጥፏል"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> እርስዎ የቀዱትን ጽሑፍ ለጥፏል"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"አንድ መተግበሪያ ለዚያ መተግበሪያ የባትሪ ማትባቶችን ችላ ለማለት እንዲጠይቅ ይፈቅድለታል።"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"ሁሉንም ጥቅሎች ይጠይቁ"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"አንድ መተግበሪያ ሁሉንም የተጫኑ ጥቅሎችን እንዲያይ ይፈቅድለታል።"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApisን ይድረሱ"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"መተግበሪያ SupplementalApisን እንዲደርስ ይፈቅዳል።"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"የAdServices ርዕሶች ኤፒአይን ይድረሱ"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"መተግበሪያ የAdServices ርዕሶች ኤፒአይን እንዲደርስ ይፈቅዳል።"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"የAdServices Attribution ኤፒአይን ይድረሱ"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"መተግበሪያ የAdServices ባለቤትነት ኤፒአይዎችን ለመድረስ ይፈቅዳል።"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"የAdServices ብጁ ታዳሚዎች ኤፒአይን ይድረሱ"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"መተግበሪያ የAdServices ብጁ ታዳሚዎች ኤፒአይን ለመድረስ ይፈቅዳል።"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ለአጉላ መቆጣጠሪያ ሁለት ጊዜ ነካ አድርግ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ምግብር ማከል አልተቻለም።"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ሂድ"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"ወደ <xliff:g id="NAME">%1$s</xliff:g> በመቀየር ላይ…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> በማውጣት ላይ…"</string>
<string name="owner_name" msgid="8713560351570795743">"ባለቤት"</string>
+ <string name="guest_name" msgid="8502103277839834324">"እንግዳ"</string>
<string name="error_message_title" msgid="4082495589294631966">"ስህተት"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ይህ ለውጥ በአስተዳዳሪዎ አይፈቀድም"</string>
<string name="app_not_found" msgid="3429506115332341800">"ይህን እርምጃ የሚያከናውን ምንም መተግበሪያ አልተገኘም"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"አራግፍ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ለማንኛውም ክፈት"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"ጎጂ መተግበሪያ ተገኝቷል"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"የስርዓት ምዝግብ ማስታወሻ መዳረሻ ጥያቄ"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ሁሉንም የመሣሪያ ምዝግብ ማስታወሻዎች እንዲደርስ ይፈቀድለት?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"አሁን ብቻ"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"አትፍቀድ"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ለተግባራዊ ስህተት ማረሚያ የስርዓት ምዝግብ ማስታወሻዎችን ይጠይቃል። እነዚህ ምዝግብ ማስታወሻዎች በመሣሪያዎ ላይ ያሉ መተግበሪያዎች እና አገልግሎቶች የጻፉትን መረጃ ሊይዙ ይችላሉ።"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"የመሣሪያ ምዝግብ ማስታወሻዎች በመሣሪያዎ ላይ ምን እንደሚከሰት ይመዘግባሉ። መተግበሪያዎች ችግሮችን ለማግኘት እና ለማስተካከል እነዚህን ምዝግብ ማስታወሻዎች መጠቀም ይችላሉ።\n\nአንዳንድ ምዝግብ ማስታወሻዎች ሚስጥራዊነት ያለው መረጃ ሊይዙ ይችላሉ፣ ስለዚህ የሚያምኗቸውን መተግበሪያዎች ብቻ ሁሉንም የመሣሪያ ምዝግብ ማስታወሻዎች እንዲደርሱ ይፍቀዱላቸው። \n\nይህ መተግበሪያ ሁሉንም የመሣሪያ ምዝግብ ማስታወሻዎች እንዲደርስ ካልፈቀዱለት አሁንም የራሱን ምዝግብ ማስታወሻዎች መድረስ ይችላል፣ እንዲሁም የእርስዎ መሣሪያ አምራች አሁንም አንዳንድ ምዝግብ ማስታወሻዎችን ወይም መረጃዎችን በመሣሪያዎ ላይ ሊደርስ ይችላል። የበለጠ መረዳት"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"ዳግም አታሳይ"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> የ<xliff:g id="APP_2">%2$s</xliff:g> ቁራጮችን ማሳየት ይፈልጋል"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"አርትዕ"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ከበስተጀርባ ለረጅም ጊዜ በማሄድ ላይ ነው። ለመገምገም መታ ያድርጉ።"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ንቁ መተግበሪያዎችን ይፈትሹ"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"ከዚህ መሣሪያ ሆኖ ካሜራን መድረስ አይቻልም"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 850c2f0..171a5a1 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -89,8 +89,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"أجرى مشغّل شبكة الجوّال إيقافًا مؤقتًا للخدمة لشريحة SIM رقم <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"يتعذّر الوصول إلى شبكة الجوّال."</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"حاول تغيير الشبكة المفضلة. انقر لتغييرها."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"لا تتوفر إمكانية الاتصال في حالات الطوارئ."</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"يتعذّر إجراء مكالمات طوارئ عبر Wi‑Fi."</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"قد لا تكون مكالمات الطوارئ متوفرة."</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"لا تعمل خدمة مكالمات الطوارئ على شبكة Wi-Fi في <xliff:g id="SPN">%s</xliff:g>. يُرجى النقر للحصول على التفاصيل."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"التنبيهات"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"إعادة توجيه المكالمة"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"وضع معاودة الاتصال بالطوارئ"</string>
@@ -429,10 +429,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"للسماح للتطبيق بتعديل سجل مكالمات الجهاز اللوحي، بما في ذلك البيانات عن المكالمات الواردة والصادرة. وربما تستخدم التطبيقات الضارة هذا لمسح سجل المكالمات أو تعديله."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"للسماح للتطبيق بتعديل سجلّ مكالمات جهاز Android TV، بما في ذلك البيانات عن المكالمات الواردة والصادرة. وقد تستخدم التطبيقات الضارة هذا الإعداد لمحو سجلّ المكالمات أو تعديله."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"للسماح للتطبيق بتعديل سجل مكالمات الهاتف، بما في ذلك البيانات عن المكالمات الواردة والصادرة. وربما تستخدم التطبيقات الضارة هذا لمحو سجل المكالمات أو تعديله."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"الوصول إلى أجهزة استشعار الجسم (مثل شاشات معدل ضربات القلب)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"الوصول إلى البيانات من أجهزة استشعار الجسم، مثلاً معدّل نبضات القلب ودرجة الحرارة ونسبة الأكسجين في الدم وما إلى ذلك"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"الوصول إلى أجهزة استشعار الجسم (مثلاً شاشات معدّل ضربات القلب في الخلفية)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"الوصول إلى البيانات من أجهزة استشعار الجسم، مثلاً معدّل نبضات القلب ودرجة الحرارة ونسبة الأكسجين في الدم وما إلى ذلك في الخلفية"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"تمكين التطبيق عند استخدامه من الوصول لبيانات استشعار الجسم، مثل معدل نبضات القلب"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"يتيح هذا الإذن للتطبيق الوصول إلى بيانات أجهزة استشعار الجسم، مثل معدّل نبضات القلب ودرجة الحرارة ونسبة الأكسجين في الدم، وذلك عندما يكون التطبيق قيد الاستخدام."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"تمكين التطبيق في الخلفية من الوصول لبيانات استشعار الجسم، مثل معدل نبضات القلب"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"يتيح هذا الإذن للتطبيق الوصول إلى بيانات أجهزة استشعار الجسم، مثل معدّل نبضات القلب ودرجة الحرارة ونسبة الأكسجين في الدم، وذلك عند استخدام التطبيق في الخلفية."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"قراءة أحداث التقويم والتفاصيل"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"يمكن لهذا التطبيق قراءة جميع أحداث التقويم المخزَّنة على الجهاز اللوحي ومشاركة بيانات التقويم أو حفظها."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"يمكن لهذا التطبيق قراءة جميع أحداث التقويم المخزَّنة على جهاز Android TV ومشاركة بيانات التقويم أو حفظها."</string>
@@ -693,8 +693,10 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"يسمح للتطبيق بقراءة الملفات الصوتية من مساحة التخزين المشتركة."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"قراءة ملفات الفيديو من مساحة التخزين المشتركة"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"يسمح للتطبيق بقراءة ملفات الفيديو من مساحة التخزين المشتركة."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"قراءة الصور من مساحة التخزين المشتركة"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"يسمح للتطبيق بقراءة ملفات الصور من مساحة التخزين المشتركة."</string>
+ <!-- no translation found for permlab_readMediaImages (4057590631020986789) -->
+ <skip />
+ <!-- no translation found for permdesc_readMediaImages (5836219373138469259) -->
+ <skip />
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"تعديل محتوى مساحة التخزين المشتركة أو حذفه"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"للسماح للتطبيق بالكتابة إلى محتوى مساحة التخزين المشتركة."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"إجراء/تلقي مكالمات SIP"</string>
@@ -916,7 +918,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"اضغط على \"القائمة\" لإلغاء التأمين أو إجراء اتصال بالطوارئ."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"اضغط على \"القائمة\" لإلغاء التأمين."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"رسم نقش لإلغاء التأمين"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"مكالمة طوارئ"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"الطوارئ"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"العودة إلى الاتصال"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"صحيح!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"أعد المحاولة"</string>
@@ -1055,7 +1057,6 @@
<string name="save_password_never" msgid="6776808375903410659">"مطلقًا"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"ليس لديك إذن بفتح هذه الصفحة."</string>
<string name="text_copied" msgid="2531420577879738860">"تم نسخ النص إلى الحافظة."</string>
- <string name="copied" msgid="4675902854553014676">"تم النسخ."</string>
<string name="pasted_from_app" msgid="5627698450808256545">"تم لصق محتوى في <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> من <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>."</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"لصَق تطبيق <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> محتوىً من الحافظة."</string>
<string name="pasted_text" msgid="4298871641549173733">"لصق تطبيق <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> النص الذي نسخته."</string>
@@ -1456,8 +1457,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"للسماح للتطبيق بطلب الإذن لتجاهل تحسينات البطارية في هذا التطبيق."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"البحث في كل الحِزم"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"يسمح هذا الإذن للتطبيق بعرض كل الحِزم المثبّتة."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"الوصول إلى SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"السماح لأحد التطبيقات بالوصول إلى SupplementalApis"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"الوصول إلى واجهة AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"يتيح هذا الإذن للتطبيق الوصول إلى واجهة AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"الوصول إلى واجهات AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"يتيح هذا الإذن للتطبيق الوصول إلى واجهات AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"الوصول إلى واجهة AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"يتيح هذا الإذن للتطبيق الوصول إلى واجهة AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"اضغط مرتين للتحكم في التكبير أو التصغير"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"تعذرت إضافة أداة."</string>
<string name="ime_action_go" msgid="5536744546326495436">"تنفيذ"</string>
@@ -1720,6 +1725,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"جارٍ التبديل إلى <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"جارٍ الخروج <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"المالك"</string>
+ <string name="guest_name" msgid="8502103277839834324">"ضيف"</string>
<string name="error_message_title" msgid="4082495589294631966">"خطأ"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"لا يسمح المشرف بإجراء هذا التغيير"</string>
<string name="app_not_found" msgid="3429506115332341800">"لم يتم العثور على تطبيق يمكنه التعامل مع هذا الإجراء."</string>
@@ -2031,10 +2037,11 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"إلغاء التثبيت"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"الفتح على أي حال"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"تم العثور على تطبيق ضار"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"طلب الوصول إلى سجّل النظام"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"هل تريد السماح لتطبيق <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> بالوصول إلى جميع سجلّات الجهاز؟"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"هذه المرَّة فقط"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"عدم السماح"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"يطلب تطبيق <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> سجّلات النظام لعملية تصحيح أخطاء وظيفية. قد تحتوي هذه السجّلات على معلومات تمت كتابتها من خلال التطبيقات والخدمات المتاحة على جهازك."</string>
+ <!-- no translation found for log_access_confirmation_body (4483075525611652922) -->
+ <skip />
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"عدم الإظهار مرة أخرى"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"يريد تطبيق <xliff:g id="APP_0">%1$s</xliff:g> عرض شرائح تطبيق <xliff:g id="APP_2">%2$s</xliff:g>."</string>
<string name="screenshot_edit" msgid="7408934887203689207">"تعديل"</string>
@@ -2269,4 +2276,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"يعمل تطبيق <xliff:g id="APP">%1$s</xliff:g> في الخلفية لفترة طويلة. انقر لمراجعة الإعدادات."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"التحقّق من التطبيقات النشطة"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"لا يمكن الوصول إلى الكاميرا من هذا الجهاز."</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 4e6a317..0d3f78d 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"আপোনাৰ বাহকে <xliff:g id="SIMNUMBER">%d</xliff:g> ছিমৰ বাবে সাময়িকভাৱে অফ কৰিছে"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ম’বাইল নেটৱৰ্কৰ লগত সংযোগ কৰিব পৰা নাই"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"পচন্দৰ নেটৱৰ্ক সলনি কৰি চেষ্টা কৰি চাওক। সলনি কৰিবলৈ টিপক।"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"জৰুৰীকালীন কল কৰাৰ সুবিধা উপলব্ধ নহয়"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"ৱাই-ফাইৰ জৰিয়তে জৰুৰীকালীন কল কৰিব নোৱাৰি"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"জৰুৰীকালীন কল কৰাৰ সুবিধাটো উপলব্ধ নহ’ব পাৰে"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g>এ ৱাই-ফাইৰ জৰিয়তে জৰুৰীকালীন কল কৰাটো সমৰ্থন নকৰে। সবিশেষ জানিবলৈ টিপক।"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"সতৰ্কবাণীসমূহ"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"কল ফৰৱাৰ্ডিং"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"জৰুৰীকালীন ক\'লবেক ম\'ড"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"অন্তৰ্গামী আৰু বহিৰ্গামী কলৰ ডেটাকে ধৰি আপোনাৰ টেবলেটৰ কল লগ সংশোধন কৰিবলৈ এপক অনুমতি দিয়ে। ক্ষতিকাৰক এপবোৰে আপোনাৰ কল লগ মচিবলৈ বা সংশোধন কৰিবলৈ ইয়াক ব্যৱহাৰ কৰিব পাৰে।"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"এপ্টোৱে অন্তৰ্গামী আৰু বহিৰ্গামী কলৰ ডেটাকে ধৰি আপোনাৰ Android TV ডিভাইচৰ কল লগ সংশোধন কৰিবলৈ অনুমতি দিয়ে। ক্ষতিকাৰক এপ্সমূহে আপোনাৰ কল লগ মচিবলৈ বা সংশোধন কৰিবলৈ এইটো ব্যৱহাৰ কৰিব পাৰে।"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"অন্তৰ্গামী আৰু বহিৰ্গামী কলৰ ডেটাকে ধৰি আপোনাৰ ফ\'নৰ কল লগ সংশোধন কৰিবলৈ এপক অনুমতি দিয়ে। ক্ষতিকাৰক এপবোৰে আপোনাৰ কল লগ মচিবলৈ বা সংশোধন কৰিবলৈ ইয়াক ব্যৱহাৰ কৰিব পাৰে।"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"শৰীৰৰ ছেন্সৰসমূহ (যেনে হৃদপিণ্ডৰ গতিৰ হাৰ নিৰীক্ষক) ব্যৱহাৰ কৰিব পাৰে"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"শৰীৰৰ ছেন্সৰৰ পৰা হৃদস্পন্দনৰ হাৰ, উষ্ণতা, তেজত অক্সিজেনৰ শতকৰা হাৰ ইত্যাদিৰ দৰে ডেটাৰ এক্সেছ পাওক।"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"নেপথ্যত থকাৰ সময়ত শৰীৰৰ ছেন্সৰ (উদাহৰণস্বৰূপে, হৃদস্পন্দনৰ হাৰ নিৰীক্ষক)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"নেপথ্যত থকাৰ সময়ত শৰীৰৰ ছেন্সৰৰ পৰা হৃদস্পন্দনৰ হাৰ, উষ্ণতা, তেজত অক্সিজেনৰ শতকৰা হাৰ ইত্যাদিৰ দৰে ডেটাৰ এক্সেছ পাওক।"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ব্যৱহাৰ কৰি থকাৰ সময়ত হৃদস্পন্দনৰ হাৰৰ দৰে শৰীৰৰ ছেন্সৰৰ ডেটা এক্সেছ কৰক"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"এপ্টো ব্যৱহাৰ কৰি থকাৰ সময়ত এপ্টোক হৃদস্পন্দনৰ হাৰ, উষ্ণতা আৰু তেজত অক্সিজেনৰ শতকৰা হাৰৰ দৰে শৰীৰৰ ছেন্সৰৰ ডেটা এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"নেপথ্যত থকাৰ সময়ত হৃদস্পন্দনৰ হাৰৰ দৰে শৰীৰৰ ছেন্সৰৰ ডেটা এক্সেছ কৰক"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"এপ্টো নেপথ্যত থকাৰ সময়ত এপ্টোক হৃদস্পন্দনৰ হাৰ, উষ্ণতা আৰু তেজত অক্সিজেনৰ শতকৰা হাৰৰ দৰে শৰীৰৰ ছেন্সৰৰ ডেটা এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"কেলেণ্ডাৰৰ কাৰ্যক্ৰম আৰু সবিশেষ পঢ়িব পাৰে"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"এই এপ্টোৱে আপোনাৰ টেবলেটটোত সংৰক্ষিত আটাইবোৰ কেলেণ্ডাৰ কাৰ্যক্ৰম পঢ়িব পাৰে আৰু আপোনাৰ কেলেণ্ডাৰৰ ডেটা শ্বেয়াৰ বা ছেভ কৰিব পাৰে।"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"এই এপ্টোৱে আপোনাৰ Android TV ডিভাইচটোত ষ্ট’ৰ কৰি ৰখা আটাইবোৰ কেলেণ্ডাৰৰ অনুষ্ঠান পঢ়িব পাৰে আৰু আপোনাৰ কেলেণ্ডাৰৰ ডেটা শ্বেয়াৰ অথবা ছেভ কৰিব পাৰে।"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"আপোনাৰ শ্বেয়াৰ কৰি ৰখা ষ্ট’ৰেজৰ পৰা অডিঅ’ ফাইল পঢ়িবলৈ এপ্টোক অনুমতি দিয়ে।"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"শ্বেয়াৰ কৰি ৰখা ষ্ট’ৰেজৰ পৰা ভিডিঅ’ ফাইল পঢ়ক"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"আপোনাৰ শ্বেয়াৰ কৰি ৰখা ষ্ট’ৰেজৰ পৰা ভিডিঅ’ ফাইল পঢ়িবলৈ এপ্টোক অনুমতি দিয়ে।"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"শ্বেয়াৰ কৰি ৰখা ষ্ট’ৰেজৰ পৰা প্ৰতিচ্ছবিৰ ফাইল পঢ়ক"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"আপোনাৰ শ্বেয়াৰ কৰি ৰখা ষ্ট’ৰেজৰ পৰা প্ৰতিচ্ছবিৰ ফাইল পঢ়িবলৈ এপ্টোক অনুমতি দিয়ে।"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"শ্বেয়াৰ কৰি ৰখা ষ্ট’ৰেজৰ পৰা প্ৰতিচ্ছবিৰ ফাইল পঢ়ক"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"আপোনাৰ শ্বেয়াৰ কৰি ৰখা ষ্ট’ৰেজৰ পৰা প্ৰতিচ্ছবিৰ ফাইল পঢ়িবলৈ এপ্টোক অনুমতি দিয়ে।"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"আপোনাৰ শ্বেয়াৰ কৰি ৰখা ষ্ট’ৰেজৰ সমল সংশোধন কৰিব বা মচিব পাৰে"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"আপোনাৰ শ্বেয়াৰ কৰি ৰখা ষ্ট’ৰেজৰ সমল লিখিবলৈ এপ্টোক অনুমতি দিয়ে।"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP কল কৰা/পোৱা"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"আনলক কৰিবলৈ বা জৰুৰীকালীন কল কৰিবলৈ মেনু টিপক।"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"আনলক কৰিবলৈ মেনু টিপক।"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"আনলক কৰিবলৈ আর্হি আঁকক"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"জৰুৰীকালীন কল"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"জৰুৰীকালীন"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"কললৈ উভতি যাওক"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"শুদ্ধ!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"আকৌ চেষ্টা কৰক"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"কেতিয়াও মনত নাৰাখিব"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"এই পৃষ্ঠাটো খুলিবলৈ আপোনাৰ অনুমতি নাই।"</string>
<string name="text_copied" msgid="2531420577879738860">"ক্লিপব\'র্ডলৈ বাৰ্তা প্ৰতিলিপি কৰা হ’ল।"</string>
- <string name="copied" msgid="4675902854553014676">"প্ৰতিলিপি কৰা হ’ল"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>ৰ পৰা <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> পে’ষ্ট কৰা হৈছে"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>এ আপোনাৰ ক্লিপব’ৰ্ডৰ পৰা পে’ষ্ট কৰিছে"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>এ আপুনি প্ৰতিলিপি কৰা সমল পে’ষ্ট কৰিছে"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"কোনো এপক সেই এপ্টোৰ বাবে বেটাৰী অপ্টিমাইজেশ্বন উপেক্ষা কৰিবলৈ অনুমতি বিচাৰিবলৈ দিয়ে।"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"আটাইবোৰ পেকেজত প্ৰশ্ন সোধক"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"এপক আটাইবোৰ ইনষ্টল কৰি থোৱা পেকেজ চাবলৈ দিয়ে।"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis এক্সেছ কৰক"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"কোনো এপ্লিকেশ্বনক SupplementalApis এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API এক্সেছ কৰে"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"এটা এপ্লিকেশ্বনক AdServices Topics API এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API এক্সেছ কৰে"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"এটা এপ্লিকেশ্বনক AdServices Attribution API এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API এক্সেছ কৰে"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"এটা এপ্লিকেশ্বনক AdServices Custom Audiences API এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"জুম নিয়ন্ত্ৰণ কৰিবলৈ দুবাৰ টিপক"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ৱিজেট যোগ কৰিব পৰা নগ\'ল।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"যাওক"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>লৈ সলনি কৰি থকা হৈছে…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>ৰ পৰা লগ আউট কৰি থকা হৈছে…"</string>
<string name="owner_name" msgid="8713560351570795743">"গৰাকী"</string>
+ <string name="guest_name" msgid="8502103277839834324">"অতিথি"</string>
<string name="error_message_title" msgid="4082495589294631966">"আসোঁৱাহ"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"আপোনাৰ প্ৰশাসকে এই অৱস্থাটো সলনি কৰিবলৈ অনুমতি নিদিয়ে"</string>
<string name="app_not_found" msgid="3429506115332341800">"এই কাৰ্যটো পৰিচালনা কৰিবলৈ কোনো এপ্লিকেশ্বন পোৱা নগ\'ল"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"আনইনষ্টল কৰক"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"যিহ\'লেও খোলক"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"ক্ষতিকাৰক এপ্ চিনাক্ত কৰা হৈছে"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"ছিষ্টেমৰ লগ এক্সেছ কৰাৰ অনুৰোধ"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>ক আটাইবোৰ ডিভাইচৰ লগ এক্সেছ কৰাৰ অনুমতি প্ৰদান কৰিবনে?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"কেৱল এইবাৰৰ বাবে"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"অনুমতি নিদিব"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>এ কাৰ্যক্ষম ডিবাগিঙৰ বাবে ছিষ্টেমৰ লগসমূহ অনুৰোধ কৰে। এই লগসমূহত আপোনাৰ ডিভাইচত থকা এপ্ আৰু সেৱাসমূহে লিখা তথ্য থাকিব পাৰে।"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"আপোনাৰ ডিভাইচত কি কি ঘটে সেয়া ডিভাইচ লগে ৰেকৰ্ড কৰে। এপে সমস্যা বিচাৰিবলৈ আৰু সমাধান কৰিবলৈ এইসমূহ লগ ব্যৱহাৰ কৰিব পাৰে।\n\nকিছুমান লগত সংবেদনশীল তথ্য থাকিব পাৰে, গতিকে কেৱল আপুনি বিশ্বাস কৰা এপকহে আটাইবোৰ ডিভাইচ লগৰ এক্সেছৰ অনুমতি দিয়া উচিত। \n\nআপুনি যদি এই এপ্টোক আটাইবোৰ ডিভাইচৰ লগ এক্সেছ কৰাৰ অনুমতি নিদিয়ে, তেতিয়াও ই নিজৰ লগসমূহ এক্সেছ কৰিব পাৰিব আৰু আপোনাৰ ডিভাইচৰ নিৰ্মাতাই আপোনাৰ ডিভাইচটোত কিছু লগ অথবা তথ্য এক্সেছ কৰিবলৈ সক্ষম হ’ব। অধিক জানক"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"পুনৰ নেদেখুৱাব"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>এ <xliff:g id="APP_2">%2$s</xliff:g>ৰ অংশ দেখুওৱাব খুজিছে"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"সম্পাদনা কৰক"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> নেপথ্যত দীৰ্ঘ সময় ধৰি চলি আছে। পৰ্যালোচনা কৰিবলৈ টিপক।"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"সক্ৰিয় এপ্সমূহ পৰীক্ষা কৰক"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"এইটো ডিভাইচৰ পৰা কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index c8089dc..905a215 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> üçün operator tərəfindən müvəqqəti olaraq deaktiv edildi"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobil şəbəkəyə daxil olmaq mümkün deyil"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tərcih edilən şəbəkəni dəyişin. Dəyişmək üçün klikləyin."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Təcili zəng əlçatan deyil"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi‑Fi vasitəsilə təcili zənglər etmək mümkün deyil"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Təcili zənglər əlçatan olmaya bilər"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi üzərindən təcili zəngləri dəstəkləmir. Detallar üçün toxunun."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Siqnallar"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Zəng yönləndirmə"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Təcili geriyə zəng rejimi"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Tətbiqə planşetinizdəki zəng jurnalını, həmçinin gedən və gələn zənglərin siyahısını dəyişməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək, zəng jurnalınıza dəyişiklik edə bilər."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Gələn və gedən zənglərlə bağlı məlumatlar daxil olmaqla tətbiqə Android TV cihazının zəng siyahısını dəyişdirmək icazəsi verir. Zərərli proqramlar zəng siyahısını silmək və ya dəyişdirmək üçün bundan istifadə edə bilər."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Tətbiqə sizin daxil olan və gedən zənglər daxil olmaqla telefon zəngi loqlarınızı redaktə etmək icazəsi verir. Zərərli tətbiqlər bundan telefon loqlarınızı silmək və ya redaktə etmək üçün istifadə edə bilər."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"bədən sensorlarına (ürək döyüntüsü monitorları kimi) giriş"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Ürək döyüntüsü, temperatur, qanda oksigen faizi kimi bədən sensorlarından əldə edilən məlumatlara giriş."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"arxa fonda işləyərkən bədən sensorlarına (ürək döyüntüsü nəzarətləri kimi) giriş"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Arxa fonda işləyərkən ürək döyüntüsü, temperatur, qanda oksigen faizi kimi bədən sensorlarından əldə edilən məlumatlara giriş."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"İstifadə zamanı ürək döyüntüsü kimi bədən sensoru datasına giriş"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Tətbiqə istifadə zamanı ürək döyüntüsü, temperatur və qanda oksigen faizi kimi bədən sensoru datasına giriş icazəsi verir."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Arxa fonda olarkən ürək döyüntüsü kimi bədən sensoru datasına giriş"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Tətbiqə arxa fonda olarkən ürək döyüntüsü, temperatur və qanda oksigen faizi kimi bədən sensoru datasına giriş icazəsi verir."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Təqvim təqdirləri və detallarını oxuyun"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Bu tətbiq planşetdə yerləşdirilmiş və təqvim datasında yadda saxlanmış bütün təqvim tədbirlərini oxuya bilər."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Bu tətbiq Android TV cihazında saxlanılan bütün təqvim tədbirlərini oxuya, həmçinin təqvim datasını paylaşa və ya yadda saxlaya bilər."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Tətbiqə paylaşılan yaddaşdakı audio faylları oxumaq imkanı verir."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"paylaşılan yaddaşdakı video fayllarını oxumaq"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Tətbiqə paylaşılan yaddaşdakı video fayllarını oxumaq imkanı verir."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"paylaşılan yaddaşdakı şəkil fayllarını oxumaq"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Tətbiqə paylaşılan yaddaşdakı şəkil fayllarını oxumaq imkanı verir."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"paylaşılan yaddaşdakı şəkil fayllarını oxumaq"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Tətbiqə paylaşılan yaddaşdakı şəkil fayllarını oxumaq imkanı verir."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"paylaşılan yaddaşdakı kontenti dəyişmək və ya silmək"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Tətbiqə paylaşılan yaddaşdakı kontenti yazmaq imkanı verir."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP çağrıları göndərin/qəbul edin"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Təcili zəng kilidini açmaq və ya yerləşdirmək üçün Menyu düyməsinə basın."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Kilidi açmaq üçün Menyu düyməsinə basın."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Kilidi açmaq üçün model çəkin"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Təcili zəng"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Təcili"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Zəngə qayıt"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Düzdür!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Bir də cəhd edin"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Heç vaxt"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Bu səhifəni açmaq üçün icazəniz yoxdur."</string>
<string name="text_copied" msgid="2531420577879738860">"Mətn panoya kopyalandı."</string>
- <string name="copied" msgid="4675902854553014676">"Kopyalandı"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> tətbiqindən əlavə edilib"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> datanı panodan əlavə edib"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> kopyaladığınız mətni əlavə etdi"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Tatareya optimallaşdırılmasını o tətbiq üçün iqnor edilməsinə icazə vermək məqsədilə soruşmağa tətbiqə icazə verilir."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"bütün paketlər üçün sorğu göndərin"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Tətbiqə bütün quraşdırılmış paketləri görmək icazəsi verir."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis\'ə giriş"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Tətbiqə SupplementalApis\'ə giriş icazəsi verir."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API\'ə giriş"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Tətbiqə AdServices Topics API\'ə giriş icazəsi verir."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API\'ə giriş"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Tətbiqə AdServices Attribution API\'ə giriş icazəsi verir."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API\'ə giriş"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Tətbiqə AdServices Custom Audiences API\'ə giriş icazəsi verir."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Zoom kontrolu üçün iki dəfə toxunun"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget əlavə edilə bilmədi."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Get"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adına keçirilir…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> çıxır..."</string>
<string name="owner_name" msgid="8713560351570795743">"Sahib"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Qonaq"</string>
<string name="error_message_title" msgid="4082495589294631966">"Xəta"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Bu dəyişikliyə admin tərəfindən icazə verilmir"</string>
<string name="app_not_found" msgid="3429506115332341800">"Bu əməliyyatı idarə etmək üçün heç bir tətbiq tapılmadı."</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"SİSTEMDƏN SİLİN"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"İSTƏNİLƏN HALDA AÇIN"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Zərərli tətbiq aşkarlandı"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Sistem qeydinə giriş sorğusu"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> tətbiqinin bütün cihaz qeydlərinə girişinə icazə verilsin?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Yalnız bu dəfə"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"İcazə verməyin"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> funksional sazlama üçün sistem qeydlərini tələb edir. Bu qeydlərə cihazınızda tətbiqlər və xidmətlərin yazdığı məlumatlar daxil ola bilər."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Cihaz qeydləri cihazınızda baş verənləri qeyd edir. Tətbiqlər problemləri tapmaq və həll etmək üçün bu qeydlərdən istifadə edə bilər.\n\nBəzi qeydlərdə həssas məlumatlar ola bilər, ona görə də yalnız etibar etdiyiniz tətbiqlərin bütün cihaz qeydlərinə giriş etməsinə icazə verin. \n\nBu tətbiqin bütün cihaz qeydlərinə girişinə icazə verməsəniz, o, hələ də öz qeydlərinə giriş edə bilər və cihaz istehsalçınız hələ də cihazınızda bəzi qeydlərə və ya məlumatlara giriş edə bilər. Ətraflı məlumat"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Daha göstərməyin"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> <xliff:g id="APP_2">%2$s</xliff:g> tətbiqindən bölmələr göstərmək istəyir"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Redaktə edin"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> uzun müddət arxa fonda işləyir. Nəzərdən keçirmək üçün toxunun."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Aktiv tətbiqləri yoxlayın"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Bu cihazdan kameraya giriş mümkün deyil"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 1741287..f31a884 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -86,8 +86,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Privremeno je isključio mobilni operater za SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Povezivanje sa mobilnom mrežom nije uspelo"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probajte da promenite željenu mrežu. Dodirnite da biste promenili."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi nisu dostupni"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Ne možete da upućujete hitne pozive preko Wi‑Fi-ja"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Hitni pozivi možda nisu dostupni"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ne podržava hitne pozive preko WiFi-ja. Dodirnite za detalje."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Obaveštenja"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmeravanje poziva"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Režim za hitan povratni poziv"</string>
@@ -426,10 +426,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Dozvoljava aplikaciji da menja evidenciju poziva na tabletu, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamerne aplikacije mogu ovo da koriste da bi brisale ili menjale evidenciju poziva."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Dozvoljava aplikaciji da menja evidenciju poziva na Android TV uređaju, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamerne aplikacije mogu ovo da koriste za brisanje ili menjanje evidencije poziva."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Dozvoljava aplikaciji da menja evidenciju poziva na telefonu, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamerne aplikacije mogu ovo da koriste da bi brisale ili menjale evidenciju poziva."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"pristup senzorima na telu (poput monitora za praćenje pulsa)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Pristup podacima senzora za telo, poput pulsa, temperature, procenat kiseonika u krvi itd."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"pristup senzorima na telu (npr. monitori za praćenje pulsa) tokom rada u pozadini"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Pristup podacima senzora za telo, poput pulsa, temperature, procenat kiseonika u krvi itd, tokom rada u pozadini."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Pristup podacima senzora za telo, kao što je puls, u toku korišćenja"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Dozvoljava aplikaciji da pristupa podacima senzora za telo, kao što su puls, temperatura i procenat kiseonika u krvi dok se aplikacija koristi."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pristup podacima senzora za telo, kao što je puls, u pozadini"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Dozvoljava aplikaciji da pristupa podacima senzora za telo, kao što su puls, temperatura i procenat kiseonika u krvi dok je aplikacija u pozadini."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Čitanje događaja i podataka iz kalendara"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na tabletu, kao i da deli ili čuva podatke iz kalendara."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na Android TV uređaju, kao i da deli ili čuva podatke iz kalendara."</string>
@@ -690,8 +690,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Omogućava aplikaciji da čita audio fajlove iz deljenog memorijskog prostora."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"čitanje video fajlova iz deljenog memorijskog prostora"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Omogućava aplikaciji da čita video fajlove iz deljenog memorijskog prostora."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"čitanje fajlova slika iz deljenog memorijskog prostora"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Omogućava aplikaciji da čita fajlove slika iz deljenog memorijskog prostora."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"čitanje fajlova slika iz deljenog memorijskog prostora"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Omogućava aplikaciji da čita fajlove slika iz deljenog memorijskog prostora."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"menjanje ili brisanje sadržaja deljenog memorijskog prostora"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Dozvoljava aplikaciji da upisuje sadržaj deljenog memorijskog prostora."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"upućivanje/prijem SIP poziva"</string>
@@ -913,7 +913,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Pritisnite „Meni“ da biste otključali telefon ili uputite hitan poziv."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Pritisnite „Meni“ za otključavanje."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Unesite šablon za otključavanje"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Hitan poziv"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Hitne službe"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Nazad na poziv"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Tačno!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Probajte ponovo"</string>
@@ -1052,7 +1052,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nikad"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nemate dozvolu da otvorite ovu stranicu."</string>
<string name="text_copied" msgid="2531420577879738860">"Tekst je kopiran u privremenu memoriju."</string>
- <string name="copied" msgid="4675902854553014676">"Kopirano je"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila podatke iz aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prelepio/la iz privremene memorije"</string>
<string name="pasted_text" msgid="4298871641549173733">"Aplikacija<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je nalepila tekst koji ste kopirali"</string>
@@ -1453,8 +1452,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Dozvoljava aplikaciji da traži dozvolu za ignorisanje optimizacija baterije za tu aplikaciju."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"slanje upita za sve pakete"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Dozvoljava aplikaciji da vidi sve instalirane pakete."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"pristup stavci SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Dozvoljava aplikaciji da pristupa stavci SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"pristup API-ju za teme usluga oglasa"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Dozvoljava aplikaciji da pristupa API-ju za teme usluga oglasa."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"pristup API-jima za pripisivanje usluga oglasa"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Dozvoljava aplikaciji da pristupa API-jima za distribuciju usluga oglasa."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"pristup API-ju za prilagođene publike usluga oglasa"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Dozvoljava aplikaciji da pristupa API-ju za prilagođene publike usluga oglasa."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dodirnite dvaput za kontrolu zumiranja"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nije moguće dodati vidžet."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Idi"</string>
@@ -1717,6 +1720,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Odjavljuje se <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Vlasnik"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gost"</string>
<string name="error_message_title" msgid="4082495589294631966">"Greška"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Administrator nije dozvolio ovu promenu"</string>
<string name="app_not_found" msgid="3429506115332341800">"Nije pronađena nijedna aplikacija koja bi mogla da obavi ovu radnju"</string>
@@ -2028,10 +2032,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DEINSTALIRAJ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"IPAK OTVORI"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Otkrivena je štetna aplikacija"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Zahtev za pristup sistemskoj evidenciji"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Želite da dozvolite aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> da pristupa svim evidencijama uređaja?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Samo ovaj put"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ne dozvoli"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> zahteva evidencije sistema radi otklanjanja grešaka u funkcijama. Te evidencije mogu da sadrže informacije koje su aplikacije i usluge na uređaju zapisale."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Evidencije uređaja registruju šta se dešava na uređaju. Aplikacije mogu da koriste te evidencije da bi pronašle i rešile probleme.\n\nNeke evidencije mogu da sadrže osetljive informacije, pa pristup svim evidencijama uređaja treba da dozvoljavate samo aplikacijama u koje imate poverenja. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim evidencijama uređaja, ona i dalje može da pristupa sopstvenim evidencijama, a proizvođač uređaja će možda i dalje moći da pristupa nekim evidencijama ili informacijama na uređaju. Saznajte više"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikazuj ponovo"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi da prikazuje isečke iz aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Izmeni"</string>
@@ -2266,4 +2270,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je predugo pokrenuta u pozadini. Dodirnite da biste pregledali."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Proverite aktivne aplikacije"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Ne možete da pristupite kameri sa ovog uređaja"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 85ddf07..4b61b0d 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -87,8 +87,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Часова адключана для SIM <xliff:g id="SIMNUMBER">%d</xliff:g> аператарам сувязі"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Сетка мабільнай сувязі недаступная"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Націсніце, каб выбраць іншую сетку."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Экстранныя выклікі недаступныя"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Экстранныя выклікі ў сетцы Wi‑Fi недаступныя"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Экстранныя выклікі могуць быць недаступнымі"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> не падтрымлівае экстранныя выклікі праз Wi-Fi. Націсніце, каб убачыць больш інфармацыі."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Абвесткі"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Пераадрасацыя выкліку"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Рэжым экстранных зваротных выклікаў"</string>
@@ -427,10 +427,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Дазваляе прыкладанню змяняць гiсторыю выклiкаў планшэта, у тым лiку дадзеныя пра ўваходныя i зыходныя выклiкi. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб выдаляць або змяняць гiсторыю выклікаў."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Дазваляе праграме змяняць журнал выклікаў прылады Android TV, у тым ліку даныя пра ўваходныя і выходныя выклікі. Шкодныя праграмы могуць злоўжыць гэтым і сцерці ці змяніць даныя ў журнале выклікаў."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Дазваляе прыкладанням змяняць гiсторыю выклiкаў тэлефону, у тым лiку дадзеныя пра ўваходныя і зыходныя выклiкi. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб выдаляць або змяняць гiсторыю выклікаў."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"атрымліваць доступ да датчыкаў цела (напрыклад, пульсометраў)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Доступ да даных з датчыкаў цела, такіх як пульс, тэмпература, працэнт утрымання ў крыві кіслароду і г. д."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"атрымліваць у фонавым рэжыме доступ да датчыкаў цела (напрыклад, пульсометраў)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Доступ у фонавым рэжыме да даных з датчыкаў цела, такіх як пульс, тэмпература, працэнт утрымання ў крыві кіслароду і г. д."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Доступ да даных датчыкаў цела, такіх як пульс, у час выкарыстання"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Праграма ў час яе выкарыстання будзе мець доступ да даных датчыкаў цела, такіх як пульс, тэмпература і працэнт утрымання ў крыві кіслароду."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Доступ да даных датчыкаў цела, такіх як пульс, у фонавым рэжыме"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Праграма ў час яе працы ў фонавым рэжыме будзе мець доступ да даных датчыкаў цела, такіх як пульс, тэмпература і працэнт утрымання ў крыві кіслароду."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Чытаць падзеі календара і падрабязныя звесткі"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Гэта праграма можа чытаць усе падзеі календара, захаваныя на вашым планшэце, і абагульваць ці захоўваць даныя календара."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Гэта праграма можа счытваць усе падзеі календара, захаваныя на прыладзе Android TV, і абагульваць ці захоўваць яго даныя."</string>
@@ -691,8 +691,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Праграма зможа счытваць аўдыяфайлы з абагуленага сховішча."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"счытваць відэафайлы з абагуленага сховішча"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Праграма зможа счытваць відэафайлы з абагуленага сховішча."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"счытваць файлы відарысаў з абагуленага сховішча"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Праграма зможа счытваць файлы відарысаў з абагуленага сховішча."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"счытваць файлы відарысаў з абагуленага сховішча"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Праграма зможа счытваць файлы відарысаў з абагуленага сховішча."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"змяненне або выдаленне змесціва абагуленага сховішча"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Дазваляе праграме запісваць змесціва абагуленага сховішча."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"ажыццяўленне/прыманне выклікаў SIP"</string>
@@ -914,7 +914,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Націсніце \"Меню\", каб разблакаваць, або зрабіце экстраны выклік."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Націсніце \"Меню\", каб разблакаваць."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Намалюйце камбінацыю разблакоўкі, каб разблакаваць"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Экстранны выклік"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Экстранны выклік"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Вярнуцца да выкліку"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Правільна!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Паўтарыце спробу"</string>
@@ -1053,7 +1053,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Ніколі"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"У вас няма дазволу на адкрыццё гэтай старонкі."</string>
<string name="text_copied" msgid="2531420577879738860">"Тэкст скапіраваны ў буфер абмену."</string>
- <string name="copied" msgid="4675902854553014676">"Скапіравана"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Праграма \"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>\" была ўстаўлена з праграмы \"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>\""</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Праграма \"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>\" уставіла даныя з буфера абмену"</string>
<string name="pasted_text" msgid="4298871641549173733">"Скапіраваны вамі тэкст устаўлены праграмай \"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>\""</string>
@@ -1454,8 +1453,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Дазваляе праграме запытваць дазвол на ігнараванне аптымізацыі акумулятара для гэтай праграмы."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"запыт усіх пакетаў"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Дазваляе праграме выяўляць усе ўсталяваныя пакеты."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"доступ да SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Дазваляе праграме мець доступ да SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"доступ да AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Дазваляе праграме мець доступ да AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"доступ да AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Дазваляе праграме мець доступ да AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"доступ да AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Дазваляе праграме мець доступ да AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Націсніце двойчы, каб кіраваць маштабаваннем"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Немагчыма дадаць віджэт."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Пачаць"</string>
@@ -1718,6 +1721,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Пераход у рэжым \"<xliff:g id="NAME">%1$s</xliff:g>\"..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> выходзіць з сістэмы…"</string>
<string name="owner_name" msgid="8713560351570795743">"Уладальнік"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Госць"</string>
<string name="error_message_title" msgid="4082495589294631966">"Памылка"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Ваш адміністратар не дазваляе гэту змену"</string>
<string name="app_not_found" msgid="3429506115332341800">"Прыкладанне для гэтага дзеяння не знойдзенае"</string>
@@ -2029,10 +2033,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ВЫДАЛІЦЬ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"УСЁ РОЎНА АДКРЫЦЬ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Выяўлена шкодная праграма"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Запыт на доступ да сістэмных журналаў"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Дазволіць праграме \"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>\" мець доступ да ўсіх журналаў прылады?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Толькі ў гэты раз"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Не дазваляць"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> запытвае доступ да сістэмных журналаў з мэтай функцыянальнай адладкі. У гэтых журналах можа ўтрымлівацца інфармацыя, запісаная праграмамі і сэрвісамі вашай прылады."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Журналы прылад запісваюць усё, што адбываецца на вашай прыладзе. Праграмы выкарыстоўваюць гэтыя журналы для пошуку і выпраўлення памылак.\n\nУ некаторых журналах можа ўтрымлівацца канфідэнцыяльная інфармацыя, таму давайце доступ да ўсіх журналаў прылады толькі тым праграмам, якім вы давяраеце. \n\nКалі вы не дасце гэтай праграме доступу да ўсіх журналаў прылад, у яе ўсё роўна застанецца доступ да ўласных журналаў і для вытворцы вашай прылады будуць даступнымі некаторыя журналы і інфармацыя на вашай прыладзе. Даведацца больш"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Больш не паказваць"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Праграма <xliff:g id="APP_0">%1$s</xliff:g> запытвае дазвол на паказ зрэзаў праграмы <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Рэдагаваць"</string>
@@ -2267,4 +2271,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> працуе ў фонавым рэжыме працяглы час. Націсніце, каб праглядзець."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Праверце актыўныя праграмы"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"З гэтай прылады няма доступу да камеры."</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index dc393a3..34d330c 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Временно е изключено от оператора ви за SIM карта <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Не може да се установи връзка с мобилната мрежа"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Изберете друга предпочитана мрежа. Докоснете за промяна."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Няма достъп до спешните обаждания"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Не може да се извършват спешни обаждания през Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Спешните обаждания може да не са налице"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> не поддържа спешните обаждания през Wi-Fi. Докоснете за подробности."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Сигнали"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Пренасочване на обаждания"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим на обратно обаждане при спешност"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Разрешава на приложението да променя списъка с обаждания на таблета ви, включително данните за входящите и изходящите обаждания. Злонамерените приложения могат да използват това, за да изтрият или променят този списък."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Дава възможност на приложението да променя списъка с обажданията на устройството ви с Android TV, включително данните за входящите и изходящите обаждания. Злонамерените приложения може да използват разрешението, за да изтрият или променят този списък."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Разрешава на приложението да променя списъка с обаждания на телефона ви, включително данните за входящите и изходящите обаждания. Злонамерените приложения могат да използват това, за да изтрият или променят този списък."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"достъп до телесните сензори (напр. пулсомери)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Достъп до данните от сензорите за тяло, като например сърдечен ритъм, температура, процент на кислорода в кръвта и др."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"достъп до сензорите за тяло (напр. пулсомери), докато е на заден план"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Достъп до данните от сензорите за тяло, като например сърдечен ритъм, температура, процент на кислорода в кръвта и др., докато е на заден план."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Достъп до данните от сензорите за тяло (напр. за сърдечен ритъм) при използване"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Разрешава на приложението да осъществява достъп до данните от сензорите за тяло, като например тези за сърдечен ритъм, температура и процент на кислорода в кръвта, докато то се използва."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Достъп до данните от сензорите за тяло (напр. за сърдечен ритъм) на заден план"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Разрешава на приложението да осъществява достъп до данните от сензорите за тяло, като например тези за сърдечен ритъм, температура и процент на кислорода в кръвта, докато то се изпълнява на заден план."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Четене на събития и подробности от календара"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Това приложение може да чете всички съхранявани на таблета ви събития в календара и да споделя или запазва данни в календара ви."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Това приложение може да чете всички съхранявани на устройството ви с Android TV събития в календара и да споделя или запазва данни в календара ви."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Разрешава на приложението да чете аудиофайлове от споделеното ви хранилище."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"да чете видеофайлове от споделеното хранилище"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Разрешава на приложението да чете видеофайлове от споделеното ви хранилище."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"да чете графични файлове от споделеното хранилище"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Разрешава на приложението да чете графични файлове от споделеното ви хранилище."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"да чете графични файлове от споделеното хранилище"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Разрешава на приложението да чете графични файлове от споделеното ви хранилище."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"промяна или изтрив. на съдърж. от сподел. ви хранил."</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Разрешава на прил. да записва съдърж. от сподел. ви хранил."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"извършване/получаване на обаждания чрез SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Натиснете „Меню“, за да отключите или да извършите спешно обаждане."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Натиснете „Меню“, за да отключите."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Нарисувайте фигура, за да отключите"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Спешно обаждане"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Спешни случаи"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Назад към обаждането"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Правилно!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Опитайте отново"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Никога"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Нямате разрешение да отворите тази страница."</string>
<string name="text_copied" msgid="2531420577879738860">"Текстът е копиран в буферната памет."</string>
- <string name="copied" msgid="4675902854553014676">"Копирано"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> постави данни от <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> постави данни от буферната памет"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> постави копиран от вас текст"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Разрешава на дадено приложение да иска разрешение за пренебрегване на свързаните с него оптимизации на батерията."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"заявка за всички пакети"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Разрешава на приложението да вижда всички инсталирани пакети."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"достъп до SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Позволява на приложението достъп до SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"достъп до API за теми в AdServices"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Позволява на приложението достъп до API за теми в AdServices."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"достъп до API за приписване в AdServices"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Позволява на приложението достъп до API за приписване в AdServices."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"достъп до API за персонализирани аудитории в AdServices"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Позволява на приложението достъп до API за персонализирани аудитории в AdServices."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Докоснете двукратно за управление на промяната на мащаба"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Приспособлението не можа да бъде добавено."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Старт"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Превключва се към: <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> излиза…"</string>
<string name="owner_name" msgid="8713560351570795743">"Собственик"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Гост"</string>
<string name="error_message_title" msgid="4082495589294631966">"Грешка"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Тази промяна не е разрешена от администратора ви"</string>
<string name="app_not_found" msgid="3429506115332341800">"Няма намерено приложение за извършване на това действие"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ДЕИНСТАЛИРАНЕ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ОТВАРЯНЕ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Открито е опасно приложение"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Заявка за достъп до сист. рег. файлове"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Да се разреши ли на <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> достъп до всички регистрационни файлове за устройството?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Само този път"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Забраняване"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> иска достъп до системните регистрационни файлове с цел отстраняване на грешки с функциите. Тези файлове трябва да съдържат информация, записана от приложенията и услугите на устройството ви."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"В регистрационните файлове за устройството се записва какво се извършва на него. Приложенията могат да използват тези регистрационни файлове, за да откриват и отстраняват проблеми.\n\nНякои регистрационни файлове за устройството може да съдържат поверителна информация, затова разрешавайте достъп до всички тях само на приложения, на които имате доверие. \n\nАко не разрешите на това приложение достъп до всички регистрационни файлове за устройството, то пак може да осъществява достъп до собствените си регистрационни файлове и производителят на устройството пак може да има достъп до някои регистрационни файлове или информация на устройството ви. Научете повече"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Да не се показва пак"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> иска да показва части от <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Редактиране"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> работи на заден план от дълго време. Докоснете за преглед."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверете активните приложения"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Не може да се осъществи достъп до камерата от това устройство"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index a213c4d..f08c4a6 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"আপনার পরিষেবা প্রদানকারী <xliff:g id="SIMNUMBER">%d</xliff:g> সিমটি অস্থায়ীভাবে বন্ধ করেছে"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"মোবাইল নেটওয়ার্কে কানেক্ট করা যাচ্ছে না"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"পছন্দের নেটওয়ার্ক পরিবর্তন করে দেখুন। অন্য নেটওয়ার্ক বেছে নিতে ট্যাপ করুন।"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"জরুরি কল করা যাবে না"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"ওয়াই-ফাইয়ের মাধ্যমে জরুরি কল করা যাবে না"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"জরুরি কল উপলভ্য নাও হতে পারে"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g>-এ ওয়াই-ফাইয়ের মাধ্যমে জরুরি কল কাজ করে না। বিশদ বিবরণের জন্য ট্যাপ করুন।"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"সতর্কতা"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"কল ফরওয়ার্ড করা"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"জরুরি কলব্যাক মোড"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ইনকামিং ও আউটগোয়িং কলগুলি সম্পর্কিত ডেটা সহ আপনার ট্যাবলেটের কল লগ পরিবর্তন করতে দেয়৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি এটিকে আপনার কল লগ মুছে দিতে বা পরিবর্তন করতে ব্যবহার করতে পারে৷"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"অ্যাপটিকে ইনকামিং ও আউটগোয়িং কল সহ আপনার Android TV ডিভাইসের কল লগে পরিবর্তন করার অনুমতি দেয়। ক্ষতিকারক অ্যাপ এটিকে কাজে লাগিয়ে আপনার কল লগে পরিবর্তন করতে পারে বা সেটি মুছে ফেলতে পারে।"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ইনকামিং ও আউটগোয়িং কলগুলি সম্পর্কিত ডেটা সহ আপনার ফোনের কল লগ পরিবর্তন করতে দেয়৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি এটিকে আপনার কল লগ মুছে দিতে বা পরিবর্তন করতে ব্যবহার করতে পারে৷"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"শরীরের সেন্সর (হার্ট রেট মনিটারের মত) অ্যাক্সেস করুন"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"বডি সেন্সর ডেটাতে যেমন হার্ট রেট, তাপমাত্রা, রক্তে অক্সিজেনের শতাংশ ইত্যাদিতে অ্যাক্সেস।"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"ব্যাকগ্রাউন্ডে থাকার সময়ে বডি সেন্সর ডেটাতে (যেমন হার্ট রেট মনিটর) অ্যাক্সেস"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"ব্যাকগ্রাউন্ডে থাকার সময়ে বডি সেন্সর ডেটা যেমন হার্ট রেট, তাপমাত্রা, রক্তে অক্সিজেনের শতাংশ ইত্যাদিতে অ্যাক্সেস।"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"অ্যাপ ব্যবহার করার সময়, হার্ট রেটের মতো বডি সেন্সর ডেটার অ্যাক্সেস দিন"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"এই অ্যাপ ব্যবহার করার সময় বডি সেন্সর ডেটা অ্যাক্সেস করার অনুমতি দেওয়া হয়। এর মধ্যে হার্ট রেট, তাপমাত্রা এবং রক্তে অক্সিজেনের পরিমাণের শতাংশ সম্পর্কিত তথ্যও আছে।"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"অ্যাপ ব্যাকগ্রাউন্ডে চলার সময়, হার্ট রেটের মতো বডি সেন্সর ডেটার অ্যাক্সেস দিন"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"এই অ্যাপ ব্যাকগ্রাউন্ডে চলার সময় বডি সেন্সর ডেটা অ্যাক্সেস করার অনুমতি দেওয়া হয়। এর মধ্যে হার্ট রেট, তাপমাত্রা এবং রক্তে অক্সিজেনের পরিমাণের শতাংশ সম্পর্কিত তথ্যও আছে।"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"ক্যালেন্ডারের ইভেন্ট এবং বিশদ বিবরণ পড়ুন"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"এই অ্যাপটি আপনার ট্যাবলেটে সংরক্ষিত সমস্ত ক্যালেন্ডার ইভেন্ট পড়তে এবং আপনার ক্যালেন্ডারের ডেটা শেয়ার বা সংরক্ষণ করতে পারে৷"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"এই অ্যাপ আপনার Android TV ডিভাইসে সেভ করা সব ক্যালেন্ডার ইভেন্ট পড়তে পারে এবং আপনার ক্যালেন্ডারের ডেটা শেয়ার বা সেভ করতে পারে।"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"আপনার শেয়ার করা স্টোরেজ থেকে অডিও ফাইল রিড করার জন্য অ্যাপকে অনুমতি দিন।"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"শেয়ার করা স্টোরেজ থেকে ভিডিও ফাইল রিড করুন"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"আপনার শেয়ার করা স্টোরেজ থেকে ভিডিও ফাইল রিড করতে অ্যাপকে অনুমতি দিন।"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"শেয়ার করা স্টোরেজ থেকে ছবির ফাইল রিড করুন"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"আপনার শেয়ার করা স্টোরেজ থেকে ছবির ফাইল রিড করার জন্য অ্যাপকে অনুমতি দিন।"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"শেয়ার করা স্টোরেজ থেকে ছবির ফাইল রিড করা"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"আপনার শেয়ার করা স্টোরেজ থেকে ছবির ফাইল রিড করার জন্য অ্যাপকে অনুমতি দেয়।"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"শেয়ার করা স্টোরেজের কন্টেন্ট মুছে ফেলুন বা পরিবর্তন করুন"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"শেয়ার করা স্টোরেজের কন্টেন্ট লেখার জন্য অ্যাপটিকে অনুমতি দিন।"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP কল করুন/গ্রহণ করুন"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"আনলক করতে বা জরুরি কল করতে মেনু টিপুন৷"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"আনলক করতে মেনু টিপুন৷"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"আনলক করতে প্যাটার্ন আঁকুন"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"জরুরি কল"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"জরুরী"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"কলে ফিরুন"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"সঠিক!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"আবার চেষ্টা করুন"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"কখনই নয়"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"এই পৃষ্ঠাটি খোলার জন্য আপনার কাছে অনুমতি নেই৷"</string>
<string name="text_copied" msgid="2531420577879738860">"ক্লিপবোর্ডে পাঠ্য অনুলিপি করা হয়েছে৷"</string>
- <string name="copied" msgid="4675902854553014676">"কপি করা হয়েছে"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> থেকে কপি করা ডেটা <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-এ পেস্ট করা হয়েছে"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"আপনার ক্লিপবোর্ড থেকে <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> পেস্ট করা হয়েছে"</string>
<string name="pasted_text" msgid="4298871641549173733">"আপনার কপি করা টেক্সট <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> অ্যাপ পেস্ট করেছে"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"কোনো অ্যাপের জন্য ব্যাটারি অপ্টিমাইজেশন উপেক্ষা করতে সেটিকে অনুমতির চাওয়ার মঞ্জুরি দেয়৷"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"অন্যান্য সব প্যাকেজের তথ্য সম্পর্কিত কোয়েরি দেখুন"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"এটি কোনও অ্যাপকে সর্বদা ইনস্টল করা সব প্যাকেজ দেখতে অনুমতি দেয়।"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis অ্যাক্সেস করুন"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"SupplementalApis অ্যাক্সেস করতে অ্যাপে অনুমতি দেয়।"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API অ্যাক্সেস করুন"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"এর মাধ্যমে কোনও অ্যাপ AdServices Custom Topics APIs অ্যাক্সেস করার অনুমতি পায়।"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution APIs অ্যাক্সেস করুন"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"এর মাধ্যমে কোনও অ্যাপ AdServices Attribution APIs অ্যাক্সেস করার অনুমতি পায়।"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API অ্যাক্সেস করুন"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"এর মাধ্যমে কোনও অ্যাপ AdServices Custom Attribution APIs অ্যাক্সেস করার অনুমতি পায়।"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"জুম নিয়ন্ত্রণের জন্য দুবার ট্যাপ করুন"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"উইজেট যোগ করা যায়নি৷"</string>
<string name="ime_action_go" msgid="5536744546326495436">"যান"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"ব্যবহারকারী পরিবর্তন করে <xliff:g id="NAME">%1$s</xliff:g> করা হচ্ছে…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>কে লগ-আউট করা হচ্ছে..."</string>
<string name="owner_name" msgid="8713560351570795743">"মালিক"</string>
+ <string name="guest_name" msgid="8502103277839834324">"অতিথি"</string>
<string name="error_message_title" msgid="4082495589294631966">"ত্রুটি"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"এই পরিবর্তনটি আপনার প্রশাসক দ্বারা অনুমোদিত নয়"</string>
<string name="app_not_found" msgid="3429506115332341800">"এই ক্রিয়াটিকে চালনা করার জন্য কোনো অ্যাপ্লিকেশান পাওয়া যায়নি"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"আন-ইনস্টল করুন"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"যাই হোক, খুলতে চাই"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"ক্ষতিকর অ্যাপ শনাক্ত করা হয়েছে"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"সিস্টেম লগ অ্যাক্সেস করার অনুরোধ"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> অ্যাপকে ডিভাইসের সব লগ অ্যাক্সেসের অনুমতি দিতে চান?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"শুধুমাত্র এখন"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"অনুমতি দেবেন না"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"ফাংশনাল ডিবাগিংয়ের জন্য <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> সিস্টেম লগ অ্যাক্সেস করার অনুরোধ জানিয়েছে। আপনার ডিভাইসে থাকা অ্যাপ এবং পরিষেবার থেকে আসা বিভিন্ন তথ্য এইসব লগে লেখা থাকতে পারে।"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"ডিভাইস লগে আপনার ডিভাইসে করা অ্যাক্টিভিটি রেকর্ড করা হয়। অ্যাপ সমস্যা খুঁজে তা সমাধান করতে এইসব লগ ব্যবহার করতে পারে।\n\nকিছু লগে সংবেদনশীল তথ্য থাকতে পারে, তাই বিশ্বাস করেন শুধুমাত্র এমন অ্যাপকেই সব ডিভাইসের লগ অ্যাক্সেসের অনুমতি দিন। \n\nআপনি এই অ্যাপকে ডিভাইসের সব লগ অ্যাক্সেস করার অনুমতি না দিলেও, এটি নিজের লগ অ্যাক্সেস করতে পারবে। এছাড়া, ডিভাইস প্রস্তুতকারকও আপনার ডিভাইসের কিছু লগ বা তথ্য হয়ত অ্যাক্সেস করতে পারবে। আরও জানুন"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"আর দেখতে চাই না"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> অ্যাপটি <xliff:g id="APP_2">%2$s</xliff:g> এর অংশ দেখাতে চায়"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"এডিট করুন"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> অনেকক্ষণ ধরে ব্যাকগ্রাউন্ডে চলছে। পর্যালোচনা করতে ট্যাপ করুন।"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"অ্যাক্টিভ অ্যাপ চেক করুন"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"এই ডিভাইস থেকে ক্যামেরা অ্যাক্সেস করা যাচ্ছে না"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 9dc386c..a2af26c 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -86,8 +86,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Privremeno isključio mobilni operater za SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nije moguće dosegnuti mobilnu mrežu"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Pokušajte promijeniti preferiranu mrežu. Dodirnite za promjenu."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi su nedostupni"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Nije moguće uspostaviti hitne pozive putem Wi‑Fi mreže"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Hitni pozivi možda nisu dostupni"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ne podržava hitne pozive putem WiFi-ja. Dodirnite za detalje."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozorenja"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Prosljeđivanje poziva"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Način rada za hitni povratni poziv"</string>
@@ -426,10 +426,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Omogućava aplikaciji da izmijeni zapisnik poziva sa vašeg tableta, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije mogu to iskoristiti za brisanje ili izmjenu vašeg zapisnika poziva."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Omogućava aplikaciji izmjenu zapisnika poziva Android TV uređaja, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije to mogu iskoristiti za brisanje ili izmjenu zapisnika poziva."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Omogućava aplikaciji da izmijeni zapisnik poziva sa vašeg telefona, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije mogu to iskoristiti za brisanje ili izmjenu vašeg zapisnika poziva."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"pristup tjelesnim senzorima (poput monitora za puls)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Pristup podacima s tjelesnih senzora kao što su puls, temperatura, saturacija kisikom, itd."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"pristup tjelesnim senzorima (poput monitora za puls) dok je aplikacija u pozadini"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Pristup podacima s tjelesnih senzora kao što su puls, temperatura, saturacija kisikom, itd. dok je aplikacija u pozadini."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Pristup podacima tjelesnih senzora, kao što je puls, dok se koristi"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Dozvoljava aplikaciji dok se koristi da pristupa podacima tjelesnih senzora kao što su puls, temperatura i postotak kisika u krvi."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pristup podacima tjelesnih senzora, kao što je puls, dok je u pozadini"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Dozvoljava aplikaciji dok je u pozadini da pristupa podacima tjelesnih senzora kao što su puls, temperatura i postotak kisika u krvi."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Čitanje događaja kalendara i detalja"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ova aplikacija može čitati sve događaje u kalendaru pohranjene na vašem tabletu i sačuvati podatke kalendara."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ova aplikacija može čitati sve događaje u kalendaru na vašem Android TV uređaju i dijeliti ili sačuvati podatke kalendara."</string>
@@ -690,8 +690,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Omogućava aplikaciji da čita audio fajlove iz vaše dijeljene pohrane."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"čitanje fajlova videozapisa iz dijeljene pohrane"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Omogućava aplikaciji da čita fajlove videozapisa iz vaše dijeljene pohrane."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"čitanje fajlova slika iz dijeljene pohrane"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Omogućava aplikaciji da čita fajlove slika iz vaše dijeljene pohrane."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"čitanje fajlova slika iz dijeljene pohrane"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Omogućava aplikaciji da čita fajlove slika iz vaše dijeljene pohrane."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"mijenja ili briše sadržaj vaše dijeljene pohrane"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Omogućava aplikaciji da piše sadržaj vaše dijeljene pohrane."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"Uputi/primi SIP pozive"</string>
@@ -913,7 +913,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Pritisnite dugme Meni kako biste otključali uređaj ili obavili hitni poziv."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Pritisnite dugme Meni za otključavanje uređaja."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Nacrtajte uzorak za otključavanje"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Hitni poziv"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Hitno"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Povratak na poziv"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Ispravno!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Pokušajte ponovo"</string>
@@ -1052,7 +1052,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nikad"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nemate odobrenje za otvaranje ove stranice."</string>
<string name="text_copied" msgid="2531420577879738860">"Tekst kopiran u međumemoriju."</string>
- <string name="copied" msgid="4675902854553014676">"Kopirano"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je zalijepljena iz aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je zalijepila sadržaj iz međumemorije"</string>
<string name="pasted_text" msgid="4298871641549173733">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je zalijepila kopirani tekst"</string>
@@ -1453,8 +1452,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Omogućava aplikaciji da traži odobrenje za zanemarivanje optimizacije baterije za tu aplikaciju."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"upit za sve pakete"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Omogućava aplikaciji da pregleda sve instalirane pakete."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"pristup za SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Dozvoljava aplikaciji pristup za SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"pristupi AdServices Topics API-ju"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Dozvoljava aplikaciji da pristupi AdServices Topics API-ju."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"pristupi AdServices Attribution API-ovima"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Dozvoljava aplikaciji da pristupi AdServices Attribution API-ovima."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"pristupi AdServices Custom Audiences API-ju"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Dozvoljava aplikaciji da pristupi AdServices Custom Audiences API-ju."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dodirnite dvaput za kontrolu uvećanja"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Dodavanje vidžeta nije uspjelo."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Započni"</string>
@@ -1717,6 +1720,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Odjava korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Vlasnik"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gost"</string>
<string name="error_message_title" msgid="4082495589294631966">"Greška"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Vaš administrator ne dozvoljava ovu promjenu"</string>
<string name="app_not_found" msgid="3429506115332341800">"Nije pronađena aplikacija koja će upravljati ovom akcijom."</string>
@@ -2028,10 +2032,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DEINSTALIRAJ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"IPAK OTVORI"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Otkrivena je štetna aplikacija"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Zahtjev za pristup sistemskom zapisniku"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Dozvoliti aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> da pristupa svim zapisnicima uređaja?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Samo ovaj put"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nemoj dozvoliti"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"Aplikacija <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> traži zapisnike sistema za funkcionalno otklanjanje grešaka. Ti zapisnici mogu sadržavati informacije koje su zabilježile aplikacije i usluge na vašem uređaju."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Zapisnici uređaja bilježe šta se dešava na uređaju. Aplikacije mogu koristiti te zapisnike da pronađu i isprave probleme.\n\nNeki zapisnici mogu sadržavati osjetljive podatke. Zato pristup svim zapisnicima uređaja dozvolite samo aplikacijama kojima vjerujete. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim zapisnicima uređaja, ona i dalje može pristupati svojim zapisnicima i proizvođač uređaja će možda i dalje biti u stanju pristupiti nekim zapisnicima ili podacima na uređaju. Saznajte više"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikazuj ponovo"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi prikazati isječke aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Uredi"</string>
@@ -2266,4 +2270,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> dugo radi u pozadini. Dodirnite da pregledate."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Provjerite aktivne aplikacije"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nije moguće pristupiti kameri s ovog uređaja"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index a02b412..4791579 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"L\'operador de telefonia mòbil ho ha desactivat temporalment per a la SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"No es pot accedir a la xarxa mòbil"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prova de canviar de xarxa preferent. Toca per canviar-la."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Les trucades d\'emergència no estan disponibles"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"No es poden fer trucades d\'emergència per Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"És possible que les trucades d\'emergència no estiguin disponibles"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> no admet les trucades d\'emergència per Wi‑Fi. Toca per obtenir informació."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertes"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Desviació de trucades"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mode de devolució de trucada d\'emergència"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permet que l\'aplicació modifiqui el registre de trucades de la teva tauleta, incloses les dades de les trucades entrants i sortints. És possible que les aplicacions malicioses ho utilitzin per eliminar o per modificar el teu registre de trucades."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permet que l\'aplicació modifiqui el registre de trucades del dispositiu Android TV, incloses les dades de les trucades entrants i sortints. És possible que les aplicacions malicioses ho utilitzin per suprimir o per modificar el teu registre de trucades."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permet que l\'aplicació modifiqui el registre de trucades del teu telèfon, incloses les dades de les trucades entrants i sortints. És possible que les aplicacions malicioses ho utilitzin per eliminar o per modificar el teu registre de trucades."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"accedir a sensors corporals (p. ex., monitors de freqüència cardíaca)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Accés a les dades dels sensors corporals com la freqüència cardíaca, la temperatura, el percentatge d\'oxigen a la sang, etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"accedir a sensors corporals (com els monitors de freqüència cardíaca) en segon pla"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Accés a les dades dels sensors corporals, com ara la freqüència cardíaca, la temperatura o el percentatge d\'oxigen a la sang, en segon pla."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Accedir a dades del sensor corporal, com la freqüència cardíaca, en utilitzar-se"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet que l\'aplicació accedeixi a les dades del sensor corporal, com ara la freqüència cardíaca, la temperatura i el percentatge d\'oxigen a la sang, mentre s\'utilitza."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accedir a dades del sensor corporal, com la freqüència cardíaca, en segon pla"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet que l\'aplicació accedeixi a les dades del sensor corporal, com ara la freqüència cardíaca, la temperatura i el percentatge d\'oxigen a la sang, mentre es troba en segon pla."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Aquesta aplicació pot llegir els esdeveniments i la informació del calendari"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aquesta aplicació pot llegir tots els esdeveniments del calendari emmagatzemats a la tauleta i compartir o desar les dades del teu calendari."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aquesta aplicació pot llegir tots els esdeveniments del calendari emmagatzemats al dispositiu Android TV i compartir o desar les dades del calendari."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permet que l\'aplicació llegeixi fitxers d\'àudio de l\'emmagatzematge compartit."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"llegir fitxers de vídeo de l\'emmagatzematge compartit"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permet que l\'aplicació llegeixi fitxers de vídeo de l\'emmagatzematge compartit."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"llegir fitxers d\'imatge de l\'emmagatzematge compartit"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Permet que l\'aplicació llegeixi fitxers d\'imatge de l\'emmagatzematge compartit."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"llegir fitxers d\'imatge de l\'emmagatzematge compartit"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permet que l\'aplicació llegeixi fitxers d\'imatge de l\'emmagatzematge compartit."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"editar o suprimir cont. d\'emmagatzematge compartit"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"L\'app pot editar contingut de l\'emmagatzematge compartit."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"Fer i rebre trucades de SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Premeu Menú per desbloquejar-lo o per fer una trucada d\'emergència."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Premeu Menú per desbloquejar."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Dibuixeu el patró de desbloqueig"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Trucada d\'emergència"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergència"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Torna a la trucada"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correcte!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Torna-ho a provar"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Mai"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"No tens permís per obrir aquesta pàgina."</string>
<string name="text_copied" msgid="2531420577879738860">"Text copiat al Porta-retalls."</string>
- <string name="copied" msgid="4675902854553014676">"S\'ha copiat"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha enganxat dades de: <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha enganxat dades del porta-retalls"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha enganxat text que has copiat"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permet que una aplicació demani permís per ignorar les optimitzacions de bateria per a l\'aplicació."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"consultar tots els paquets"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permet que una aplicació vegi els paquets instal·lats."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"accedir a SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Permet que una aplicació accedeixi a SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"accedir a l\'API AdServices Topics"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Permet que una aplicació accedeixi a l\'API AdServices Topics."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"accedir a les API AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Permet que una aplicació accedeixi a les API AdServices Attribution."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"accedir a l\'API AdServices Custom Audiences"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Permet que una aplicació accedeixi a l\'API AdServices Custom Audiences."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Piqueu dos cops per controlar el zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"No s\'ha pogut afegir el widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ves"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"S\'està canviant a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"S\'està tancant la sessió de l\'usuari <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Propietari"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Convidat"</string>
<string name="error_message_title" msgid="4082495589294631966">"Error"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"L\'administrador no permet aquest canvi"</string>
<string name="app_not_found" msgid="3429506115332341800">"No s\'ha trobat cap aplicació per processar aquesta acció"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DESINSTAL·LA"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OBRE IGUALMENT"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"S\'ha detectat una aplicació perjudicial"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Sol·licitud d\'accés a registre del sistema"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vols permetre que <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> accedeixi a tots els registres del dispositiu?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Només aquesta vegada"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"No permetis"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> sol·licita registres del sistema per dur a terme una depuració funcional. Aquests registres poden contenir informació escrita per les aplicacions i els serveis del teu dispositiu."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Els registres del dispositiu inclouen informació sobre tot allò que passa al teu dispositiu. Les aplicacions poden utilitzar aquests registres per detectar i corregir problemes.\n\nÉs possible que alguns registres continguin informació sensible; per això només has de donar-hi accés a les aplicacions de confiança. \n\nEncara que no permetis que aquesta aplicació pugui accedir a tots els registres del dispositiu, podrà accedir als seus propis registres. A més, és possible que el fabricant del dispositiu també tingui accés a alguns registres o a informació del teu dispositiu. Més informació"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"No tornis a mostrar"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> vol mostrar porcions de l\'aplicació <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edita"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Fa molta estona que <xliff:g id="APP">%1$s</xliff:g> s\'està executant en segon pla. Toca per revisar-ho."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consulta les aplicacions actives"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"No es pot accedir a la càmera des d\'aquest dispositiu"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 960eb82..dfe5dc8 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -87,8 +87,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Dočasně vypnuto operátorem (SIM karta <xliff:g id="SIMNUMBER">%d</xliff:g>)"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilní síť není dostupná"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Zkuste změnit preferovanou síť. Změníte ji klepnutím."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Tísňová volání jsou nedostupná"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Přes Wi‑Fi nelze uskutečňovat tísňová volání"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Tísňové volání může být nedostupné"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"Operátor <xliff:g id="SPN">%s</xliff:g> nepodporuje tísňové volání přes Wi-Fi. Podrobnosti zobrazíte klepnutím."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozornění"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Přesměrování hovorů"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Režim tísňového zpětného volání"</string>
@@ -427,10 +427,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Umožňuje aplikaci upravovat seznam hovorů vašeho tabletu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Umožňuje aplikaci upravovat seznam hovorů na zařízení Android TV, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Umožňuje aplikaci upravovat seznam hovorů vašeho telefonu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"přístup k tělesným senzorům (např. snímače tepu)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Přístup k datům z tělesných senzorů, jako jsou senzory tepové frekvence, teploty, procenta nasycení krve kyslíkem apod."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"přístup k tělesným senzorům (např. k senzorům tepu) při běhu na pozadí"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Přístup k datům z tělesných senzorů, jako jsou senzory tepové frekvence, teploty, procenta nasycení krve kyslíkem apod., při běhu na pozadí."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Přístup k datům z tělesných senzorů, jako je tepová frekvence, během používání"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Poskytuje aplikaci přístup k datům z tělesných senzorů, jako je tepová frekvence, teplota a procento nasycení krve kyslíkem, během používání aplikace."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Přístup k datům z tělesných senzorů, jako je tepová frekvence, při běhu na pozadí"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Poskytuje aplikaci přístup k datům z tělesných senzorů, jako je tepová frekvence, teplota a procento nasycení krve kyslíkem, při běhu na pozadí."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Čtení událostí v kalendáři včetně podrobností"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Tato aplikace může číst všechny události v kalendáři uložené v tabletu a sdílet či ukládat data kalendáře."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Tato aplikace může číst všechny události v kalendáři uložené v zařízení Android TV a sdílet či ukládat data kalendáře."</string>
@@ -691,8 +691,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Umožňuje aplikaci čtení zvukových souborů ze sdíleného úložiště."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"čtení videosouborů ze sdíleného úložiště"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Umožňuje aplikaci čtení videosouborů ze sdíleného úložiště."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"čtení obrázkových souborů ze sdíleného úložiště"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Umožňuje aplikaci čtení obrázkových souborů ze sdíleného úložiště."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"čtení obrázkových souborů ze sdíleného úložiště"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Umožňuje aplikaci číst obrázkové soubory ze sdíleného úložiště."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"úprava nebo mazání obsahu sdíleného úložiště"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Umožňuje aplikaci zápis obsahu do sdíleného úložiště."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"uskutečňování/příjem volání SIP"</string>
@@ -914,7 +914,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Chcete-li odemknout telefon nebo provést tísňové volání, stiskněte Menu."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Telefon odemknete stisknutím tlačítka Menu."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Odblokujte pomocí gesta"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Tísňové volání"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Stav nouze"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Zavolat zpět"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Správně!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Zkusit znovu"</string>
@@ -1053,7 +1053,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nikdy"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nemáte povolení otevřít tuto stránku."</string>
<string name="text_copied" msgid="2531420577879738860">"Text byl zkopírován do schránky."</string>
- <string name="copied" msgid="4675902854553014676">"Zkopírováno"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Aplikace <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vložila data z aplikace <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Aplikace <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vložila obsah ze schránky"</string>
<string name="pasted_text" msgid="4298871641549173733">"Aplikace <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vložila zkopírovaný text"</string>
@@ -1454,8 +1453,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Povoluje aplikaci požádat o oprávnění ignorovat optimalizaci využití baterie, která pro ni je nastavena."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"zjistit všechny balíčky"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Umožňuje aplikaci načíst všechny nainstalované balíčky."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"přístup k rozhraním SupplementalApi"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Umožňuje aplikaci přístup k rozhraním SupplementalApi."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"přístup k rozhraní AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Umožňuje aplikaci přístup k rozhraní AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"přístup k rozhraním AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Umožňuje aplikaci přístup k rozhraním AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"přístup k rozhraní AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Umožňuje aplikaci přístup k rozhraní AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Poklepáním můžete ovládat přiblížení"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget nelze přidat."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Přejít"</string>
@@ -1718,6 +1721,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Přepínání na uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Odhlašování uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Vlastník"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Host"</string>
<string name="error_message_title" msgid="4082495589294631966">"Chyba"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Administrátor tuto změnu zakázal"</string>
<string name="app_not_found" msgid="3429506115332341800">"Aplikace potřebná k provedení této akce nebyla nalezena"</string>
@@ -2029,10 +2033,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ODINSTALOVAT"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"PŘESTO OTEVŘÍT"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Byla zjištěna škodlivá aplikace"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Žádost o přístup k systémovým protokolům"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Povolit aplikaci <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> přístup ke všem protokolům zařízení?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Pouze tentokrát"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nepovolovat"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"Aplikace <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> k funkčnímu ladění požaduje systémové protokoly. Tyto protokoly mohou zahrnovat informace zapsané do zařízení aplikacemi a službami."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Do protokolů zařízení se zaznamenává, co se na zařízení děje. Aplikace tyto protokoly mohou používat k vyhledání a odstranění problémů.\n\nNěkteré protokoly mohou zahrnovat citlivé údaje. Přístup k protokolům zařízení proto povolte pouze aplikacím, kterým důvěřujete. \n\nI když této aplikaci nepovolíte přístup ke všem protokolům zařízení, bude mít přístup ke svým vlastním protokolům a k některým protokolům nebo zařízením může mít přístup také výrobce zařízení. Další informace"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Příště nezobrazovat"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Aplikace <xliff:g id="APP_0">%1$s</xliff:g> chce zobrazovat ukázky z aplikace <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Upravit"</string>
@@ -2267,4 +2271,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikace <xliff:g id="APP">%1$s</xliff:g> je už dlouhou dobu spuštěna na pozadí. Klepnutím ji zkontrolujete."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Zkontrolujte aktivní aplikace"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Z tohoto zařízení nelze získat přístup k fotoaparátu"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ddd4254..2a9b4910 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Midlertidigt deaktiveret af dit mobilselskab for SIM-kortet <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Der er ingen forbindelse til mobilnetværket"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prøv at skifte dit foretrukne netværk. Tryk for skifte."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Det er ikke muligt at foretage nødopkald"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Det er ikke muligt at foretage nødopkald via Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Der kan muligvis ikke foretages nødopkald"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> understøtter ikke nødopkald via Wi-Fi. Tryk for at få flere oplysninger."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Underretninger"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Viderestilling af opkald"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Nødtilbagekaldstilstand"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Tillader, at appen ændrer din tablets opkaldshistorik, f.eks. data om indgående og udgående opkald. Ondsindede apps kan bruge dette til at slette eller ændre din opkaldshistorik."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Tillader, at appen ændrer din Android TV-enheds opkaldshistorik, bl.a. data om indgående og udgående opkald. Skadelige apps kan bruge dette til at rydde eller ændre din opkaldshistorik."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Tillader, at appen ændrer telefonens opkaldshistorik, f.eks. data om indgående og udgående opkald. Ondsindede apps kan bruge dette til at slette eller ændre din opkaldshistorik."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"få adgang til kropssensorer (f.eks. pulsmålere)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Adgang til data fra kropssensorer såsom puls, temperatur, procentdelen af ilt i blodet m.m."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"tilgå kropssensorer (f.eks. pulsmålere), mens appen kører i baggrunden."</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Adgang til data fra kropssensorer såsom puls, temperatur, procentdelen af ilt i blodet m.m., mens appen kører i baggrunden."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Få adgang til kropssensordata, f.eks. pulsen, mens appen er i brug"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Tillader, at appen kan få adgang til kropssensordata, f.eks. pulsen, temperaturen og iltmætningen af blodet, mens appen er i brug."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Få adgang til kropssensordata, f.eks. pulsen, mens appen er i baggrunden"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Tillader, at appen kan få adgang til kropssensordata, f.eks. pulsen, temperaturen og iltmætningen af blodet, mens appen er i baggrunden."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Læs kalenderbegivenheder og -info"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Denne app kan læse alle kalenderbegivenheder, der er gemt på din tablet, og dele eller gemme dine kalenderdata."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Denne app kan læse alle kalenderbegivenheder, der er gemt på din Android TV-enhed, og dele eller gemme dine kalenderdata."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Tillader, at appen læser lydfiler fra din delte lagerplads."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"Læse videofiler fra den delte lagerplads"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Tillader, at appen læser videofiler fra din fælles lagerplads."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"Læse billedfiler fra den delte lagerplads"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Tillader, at appen læser billedfiler fra din delte lagerplads."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"Læse billedfiler fra den delte lagerplads"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Tillader, at appen læser billedfiler fra din delte lagerplads."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"ændre eller slette indholdet af din delte lagerplads"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Tillader, at appen kan skrive indholdet af din delte lagerplads."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"foretage/modtage SIP-opkald"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Tryk på Menu for at låse op eller foretage et nødopkald."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Tryk på Menu for at låse op."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Tegn oplåsningsmønster"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Nødopkald"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Nødsituation"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Tilbage til opkald"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Rigtigt!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Prøv igen"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Aldrig"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Du har ikke tilladelse til at åbne denne side."</string>
<string name="text_copied" msgid="2531420577879738860">"Teksten er kopieret til udklipsholderen."</string>
- <string name="copied" msgid="4675902854553014676">"Kopieret"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> indsatte indhold fra <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> indsatte indhold fra din udklipsholder"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> indsatte tekst, som du har kopieret"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Gør det muligt for en app at bede om tilladelse til at ignorere batterioptimeringer for den pågældende app."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"forespørg om alle pakker"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Giver en app tilladelse til at se alle installerede pakker."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"adgang til SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Giver en app adgang til SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"få adgang til AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Tillader, at en app får adgang til AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"få adgang til AdServices Attribution API\'er"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Tillader, at en app får adgang til AdServices Attribution API\'er."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"få adgang til Services Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Tillader, at en app får adgang til AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tryk to gange for zoomkontrol"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget kunne ikke tilføjes."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Gå"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Skifter til <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> logges ud…"</string>
<string name="owner_name" msgid="8713560351570795743">"Ejer"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gæst"</string>
<string name="error_message_title" msgid="4082495589294631966">"Fejl"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Din administrator har ikke givet tilladelse til at foretage denne ændring"</string>
<string name="app_not_found" msgid="3429506115332341800">"Der blev ikke fundet nogen applikation, der kan håndtere denne handling"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"AFINSTALLER"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ÅBN ALLIGEVEL"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Der er registreret en skadelig app"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Anmodning om adgang til systemlogs"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vil du give <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> adgang til alle enhedslogs?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Kun denne gang"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Tillad ikke"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> anmoder om adgang til systemlogs med henblik på funktionel fejlretning. Disse logs indeholder muligvis oplysninger, som apps og tjenester på din enhed har genereret."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Enhedslogs registrerer, hvad der sker på din enhed. Apps kan bruge disse logs til at finde og løse problemer.\n\nNogle logs kan indeholde følsomme oplysninger, så giv kun apps, du har tillid til, adgang til alle enhedslogs. \n\nHvis du ikke giver denne app adgang til alle enhedslogs, kan den stadig tilgå sine egne logs, og producenten af din enhed kan muligvis fortsat tilgå visse logs eller oplysninger på din enhed. Få flere oplysninger"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Vis ikke igen"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> anmoder om tilladelse til at vise eksempler fra <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Rediger"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> har kørt i baggrunden i lang tid. Tryk for at gennemgå."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tjek aktive apps"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Kameraet kan ikke tilgås fra denne enhed"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 7e2e6c7..46d662e 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Von deinem Mobilfunkanbieter für SIM <xliff:g id="SIMNUMBER">%d</xliff:g> vorübergehend deaktiviert"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilfunknetz nicht erreichbar"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Versuche, das bevorzugte Netzwerk zu ändern. Tippe, um ein anderes auszuwählen."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Notrufe nicht möglich"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Notrufe über WLAN nicht möglich"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Notrufe sind eventuell nicht verfügbar"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> unterstützt keine Notrufe über WLAN. Weitere Informationen."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Warnmeldungen"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Anrufweiterleitung"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Notfallrückrufmodus"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Ermöglicht der App, die Anrufliste deines Tablets zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so die Einträge in der Anrufliste löschen oder sie ändern."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Ermöglicht der App, die Anrufliste deines Android TV-Geräts zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Du solltest wissen, dass dies von schädlichen Apps genutzt werden kann, um Einträge in der Anrufliste zu löschen oder zu ändern."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Ermöglicht der App, die Anrufliste deines Telefons zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so die Einträge in der Anrufliste löschen oder sie ändern."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"Auf Körpersensoren wie z. B. Pulsmesser zugreifen"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Zugriff auf Daten von Körpersensoren, wie z. B. Herzfrequenz, Temperatur und Sauerstoffsättigung."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"Auf im Hintergrund aktive Körpersensoren (z. B. Herzfrequenzmesser) zugreifen"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Zugriff auf Daten von Körpersensoren, wie z. B. Herzfrequenz, Temperatur und Sauerstoffsättigung, während sie im Hintergrund aktiv sind."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Zugriff auf Daten des Körpersensors, etwa Herzfrequenz, wenn in Benutzung"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ermöglicht der App den Zugriff auf Daten des Körpersensors, etwa solche zur Herzfrequenz, zur Temperatur und zum Blutsauerstoffanteil, während die App in Benutzung ist."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Zugriff auf Daten des Körpersensors, etwa Herzfrequenz, wenn im Hintergrund"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ermöglicht der App den Zugriff auf Daten des Körpersensors, etwa solche zur Herzfrequenz, zur Temperatur und zum Blutsauerstoffanteil, während die App im Hintergrund ist."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Kalendertermine und Details lesen"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Diese App kann alle auf deinem Tablet gespeicherten Kalendertermine lesen und deine Kalenderdaten teilen oder speichern."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Diese App kann alle auf deinem Android TV-Gerät gespeicherten Kalendertermine lesen und die Kalenderdaten teilen oder speichern."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Gewährt der App Lesezugriff auf Audiodateien in deinem freigegebenen Speicher."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"Lesezugriff auf Videodateien im freigegebenen Speicher"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Gewährt der App Lesezugriff auf Videodateien in deinem freigegebenen Speicher."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"Lesezugriff auf Bilddateien im freigegebenen Speicher"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Gewährt der App Lesezugriff auf Bilddateien in deinem freigegebenen Speicher."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"Lesezugriff auf Bilddateien im freigegebenen Speicher"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Gewährt der App Lesezugriff auf Bilddateien in deinem freigegebenen Speicher."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"Inhalte deines freigegebenen Speichers ändern oder löschen"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"So kann die App Inhalte deines freigegebenen Speichers erstellen."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP-Anrufe tätigen/empfangen"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Drücke die Menütaste, um das Telefon zu entsperren oder einen Notruf zu tätigen."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Zum Entsperren die Menütaste drücken"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Muster zum Entsperren zeichnen"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Notruf"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Notruf"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Zurück zum Anruf"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Korrekt!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Erneut versuchen"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nie"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Du bist nicht zum Öffnen dieser Seite berechtigt."</string>
<string name="text_copied" msgid="2531420577879738860">"Text in Zwischenablage kopiert."</string>
- <string name="copied" msgid="4675902854553014676">"Kopiert"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> hat etwas von <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> eingefügt"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> hat Informationen aus der Zwischenablage eingefügt"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> hat einen von dir kopierten Text eingefügt"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Erlaubt einer App, nach der Berechtigung zum Ignorieren der Akku-Leistungsoptimierungen zu fragen."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"Alle Pakete abfragen"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Ermöglicht der App, alle installierten Pakete zu sehen."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"Auf SupplementalApis zugreifen"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Ermöglicht einer App den Zugriff auf SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"Zugriff auf die AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Ermöglicht einer App den Zugriff auf die AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"Zugriff auf AdServices Attribution APIs"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Ermöglicht einer App den Zugriff auf AdServices Attribution APIs."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"Zugriff auf die AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Ermöglicht einer App den Zugriff auf die AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Für Zoomeinstellung zweimal berühren"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget konnte nicht hinzugefügt werden."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Los"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Wechseln zu <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> wird abgemeldet…"</string>
<string name="owner_name" msgid="8713560351570795743">"Eigentümer"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gast"</string>
<string name="error_message_title" msgid="4082495589294631966">"Fehler"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Dein Administrator lässt diese Änderung nicht zu"</string>
<string name="app_not_found" msgid="3429506115332341800">"Für diese Aktion wurde keine App gefunden."</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DEINSTALLIEREN"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"TROTZDEM ÖFFNEN"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Schädliche App erkannt"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Zugriffsanforderung für Systemprotokolle"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> den Zugriff auf alle Geräteprotokolle erlauben?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Nur dieses Mal"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nicht zulassen"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> fordert Systemprotokolle für die funktionale Fehlerbehebung an. Diese Protokolle können Informationen enthalten, die von Apps und Diensten auf deinem Gerät gespeichert wurden."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"In Geräteprotokollen wird aufgezeichnet, welche Aktionen auf deinem Gerät ausgeführt werden. Apps können diese Protokolle verwenden, um Probleme zu finden und zu beheben.\n\nEinige Protokolle enthalten unter Umständen vertrauliche Informationen. Daher solltest du nur vertrauenswürdigen Apps den Zugriff auf alle Geräteprotokolle gewähren. \n\nWenn du dieser App keinen Zugriff auf alle Geräteprotokolle gewährst, kann sie trotzdem auf ihre eigenen Protokolle zugreifen. Dein Gerätehersteller hat möglicherweise auch Zugriff auf einige Protokolle oder Informationen auf deinem Gerät. Weitere Informationen"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Nicht mehr anzeigen"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> möchte Teile von <xliff:g id="APP_2">%2$s</xliff:g> anzeigen"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Bearbeiten"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> wird schon längere Zeit im Hintergrund ausgeführt. Zum Prüfen tippen."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Aktive Apps prüfen"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Von diesem Gerät aus ist kein Zugriff auf die Kamera möglich"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index c6589c5..6eccbd6 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Απενεργοποιήθηκε προσωρινά από την εταιρεία κινητής τηλεφωνίας σας για τον αριθμό SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Δεν είναι δυνατή η σύνδεση στο δίκτυο κινητής τηλεφωνίας"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Δοκιμάστε να αλλάξετε το προτιμώμενο δίκτυο. Πατήστε για αλλαγή."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Οι κλήσεις έκτακτης ανάγκης δεν είναι διαθέσιμες"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Δεν είναι δυνατή η πραγματοποίηση κλήσεων έκτακτης ανάγκης μέσω Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Οι κλήσεις έκτακτης ανάγκης μπορεί να μην είναι διαθέσιμες."</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"H εταιρεία <xliff:g id="SPN">%s</xliff:g> δεν υποστηρίζει κλήσεις έκτακτης ανάγκης μέσω Wi-Fi. Πατήστε για λεπτομέρειες."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Ειδοποιήσεις"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Προώθηση κλήσης"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Λειτουργία επιστροφής κλήσης έκτακτης ανάγκης"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Επιτρέπει στην εφαρμογή να τροποποιεί το αρχείο καταγραφής κλήσεων του tablet σας, συμπεριλαμβανομένων των δεδομένων σχετικά με τις εισερχόμενες και τις εξερχόμενες κλήσεις. Οι κακόβουλες εφαρμογές μπορεί να το χρησιμοποιήσουν για να διαγράψουν ή να τροποποιήσουν το αρχείο καταγραφής κλήσεων."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Επιτρέπει στην εφαρμογή να τροποποιεί το αρχείο καταγραφής κλήσεων της συσκευής σας Android TV, συμπεριλαμβανομένων των δεδομένων σχετικά με τις εισερχόμενες και τις εξερχόμενες κλήσεις. Οι κακόβουλες εφαρμογές μπορεί να εκμεταλλευτούν αυτή την άδεια για να διαγράψουν ή να τροποποιήσουν το αρχείο καταγραφής κλήσεων."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Επιτρέπει στην εφαρμογή να τροποποιεί το αρχείο καταγραφής κλήσεων του τηλεφώνου σας, συμπεριλαμβανομένων των δεδομένων σχετικά με τις εισερχόμενες και τις εξερχόμενες κλήσεις. Οι κακόβουλες εφαρμογές μπορεί να το χρησιμοποιήσουν για να διαγράψουν ή να τροποποιήσουν το αρχείο καταγραφής κλήσεων."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"πρόσβαση στους αισθητήρες λειτουργιών (π.χ. παρακολούθηση καρδιακού παλμού)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Πρόσβαση σε δεδομένα από αισθητήρες σώματος όπως καρδιακού ρυθμού, θερμοκρασίας, ποσοστού οξυγόνου στο αίμα κ.λπ."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"πρόσβαση σε αισθητήρες σώματος (π.χ. καρδιακού ρυθμού) στο παρασκήνιο"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Πρόσβαση σε δεδομένα από αισθητήρες σώματος όπως καρδιακού ρυθμού, θερμοκρασίας, ποσοστού οξυγόνου στο αίμα κ.λπ. κατά την εκτέλεση στο παρασκήνιο."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Πρόσβαση σε δεδομένα αισθητήρων σώματος, όπως καρδιακό ρυθμό, κατά τη χρήση"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Επιτρέπει στην εφαρμογή να αποκτά πρόσβαση σε δεδομένα αισθητήρων σώματος, όπως καρδιακό ρυθμό, θερμοκρασία και ποσοστό οξυγόνου στο αίμα, ενώ η εφαρμογή χρησιμοποιείται."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Πρόσβαση σε δεδομένα αισθητήρων σώματος, όπως καρδιακό ρυθμό, στο παρασκήνιο"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Επιτρέπει στην εφαρμογή να αποκτά πρόσβαση σε δεδομένα αισθητήρων σώματος, όπως καρδιακό ρυθμό, θερμοκρασία και ποσοστό οξυγόνου στο αίμα, ενώ η εφαρμογή βρίσκεται στο παρασκήνιο."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Ανάγνωση συμβάντων ημερολογίου και λεπτομερειών"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Αυτή η εφαρμογή μπορεί να διαβάσει όλα τα συμβάντα ημερολογίου που είναι αποθηκευμένα στο tablet που χρησιμοποιείτε και να μοιραστεί ή να αποθηκεύσει τα δεδομένα ημερολογίου σας."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Αυτή η εφαρμογή μπορεί να διαβάσει όλα τα συμβάντα ημερολογίου που είναι αποθηκευμένα στη συσκευή Android TV και να μοιραστεί ή να αποθηκεύσει τα δεδομένα ημερολογίου σας."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Επιτρέπει στην εφαρμογή την ανάγνωση αρχείων ήχου από τον κοινόχρηστο αποθηκευτικό σας χώρο."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"ανάγνωση αρχείων βίντεο από τον κοινόχρηστο αποθηκευτικό χώρο"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Επιτρέπει στην εφαρμογή την ανάγνωση αρχείων βίντεο από τον κοινόχρηστο αποθηκευτικό σας χώρο."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"ανάγνωση αρχείων εικόνας από τον κοινόχρηστο αποθηκευτικό χώρο"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Επιτρέπει στην εφαρμογή την ανάγνωση αρχείων εικόνας από τον κοινόχρηστο αποθηκευτικό σας χώρο."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"ανάγνωση αρχείων εικόνας από τον κοινόχρηστο αποθηκευτικό χώρο"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Επιτρέπει στην εφαρμογή την ανάγνωση αρχείων εικόνας από τον κοινόχρηστο αποθηκευτικό σας χώρο."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"τροποποιεί ή διαγράφει το περιεχόμενο του κοινόχρηστου αποθηκευτικού χώρου σας"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Επιτρέπει στην εφαρμογή την εγγραφή του περιεχομένου του κοινόχρηστου αποθηκευτικού χώρου σας."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"πραγματοποιεί/λαμβάνει κλήσεις SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Πατήστε \"Menu\" για ξεκλείδωμα ή για κλήση έκτακτης ανάγκης."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Πατήστε \"Μενού\" για ξεκλείδωμα."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Σχεδιασμός μοτίβου για ξεκλείδωμα"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Κλήση έκτακτης ανάγκης"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Κλήση έκτακτης ανάγκης"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Επιστροφή στην κλήση"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Σωστό!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Προσπαθήστε ξανά"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Ποτέ"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Δεν έχετε άδεια για να ανοίξετε αυτήν τη σελίδα."</string>
<string name="text_copied" msgid="2531420577879738860">"Το κείμενο αντιγράφηκε στο πρόχειρο."</string>
- <string name="copied" msgid="4675902854553014676">"Αντιγράφηκε"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> έκανε επικόλληση από την εφαρμογή <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> επικόλλησε δεδομένα από το πρόχειρο"</string>
<string name="pasted_text" msgid="4298871641549173733">"Η εφαρμογή <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> επικόλλησε το κείμενο που αντιγράψατε"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Επιτρέπει σε μια εφαρμογή να ζητήσει άδεια για την αγνόηση βελτιστοποιήσεων της μπαταρίας για τη συγκεκριμένη εφαρμογή."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"υποβολή ερωτήματος σε όλα τα πακέτα"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Επιτρέπει σε μια εφαρμογή να βλέπει όλα τα εγκατεστημένα πακέτα."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"πρόσβαση στο SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Επιτρέπει σε μια εφαρμογή να έχει πρόσβαση στο SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"πρόσβαση σε API θεμάτων AdServices."</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Επιτρέπει σε μια εφαρμογή να αποκτήσει πρόσβαση σε API θεμάτων AdServices."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"πρόσβαση σε API απόδοσης AdServices"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Επιτρέπει σε μια εφαρμογή να αποκτήσει πρόσβαση σε API απόδοσης AdServices."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"πρόσβαση σε API προσαρμοσμένων κοινών AdServices"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Επιτρέπει σε μια εφαρμογή να αποκτήσει πρόσβαση σε API προσαρμοσμένων κοινών AdServices."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Πατήστε δύο φορές για έλεγχο εστίασης"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Δεν ήταν δυνατή η προσθήκη του γραφικού στοιχείου."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Μετάβαση"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Εναλλαγή σε <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Αποσύνδεση <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Κάτοχος"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Επισκέπτης"</string>
<string name="error_message_title" msgid="4082495589294631966">"Σφάλμα"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Αυτή η αλλαγή δεν επιτρέπεται από το διαχειριστή σας"</string>
<string name="app_not_found" msgid="3429506115332341800">"Δεν υπάρχει εφαρμογή για τη διαχείριση αυτής της ενέργειας"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ΑΠΕΓΚΑΤΑΣΤΑΣΗ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ΑΝΟΙΓΜΑ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Εντοπίστηκε επιβλαβής εφαρμογή"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Αίτημα πρόσβ. σε αρχ. καταγρ. συστήματος"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Να επιτρέπεται στην εφαρμογή <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> η πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής;"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Μόνο αυτήν τη φορά"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Να μην επιτραπεί"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"Η εφαρμογή <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ζητάει τα αρχεία καταγραφής συστήματος για τον εντοπισμό σφαλμάτων λειτουργικότητας. Αυτά τα αρχεία καταγραφής ενδέχεται να περιέχουν πληροφορίες που έχουν γράψει οι εφαρμογές και οι υπηρεσίες στη συσκευή σας."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Τα αρχεία καταγραφής συσκευής καταγράφουν ό,τι συμβαίνει στη συσκευή σας. Οι εφαρμογές μπορούν να χρησιμοποιούν αυτά τα αρχεία καταγραφής για να εντοπίζουν και να διορθώνουν ζητήματα.\n\nΟρισμένα αρχεία καταγραφής ενδέχεται να περιέχουν ευαίσθητες πληροφορίες, επομένως, επιτρέψτε την πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής μόνο στις εφαρμογές που εμπιστεύεστε. \n\nΑν δεν επιτρέψετε σε αυτήν την εφαρμογή την πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής, εξακολουθεί να έχει πρόσβαση στα δικά της αρχεία καταγραφής, ενώ ο κατασκευαστής της συσκευής σας ενδέχεται να εξακολουθεί να έχει πρόσβαση σε ορισμένα αρχεία καταγραφής ή πληροφορίες στη συσκευή σας. Μάθετε περισσότερα"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Να μην εμφανισ. ξανά"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Η εφαρμογή <xliff:g id="APP_0">%1$s</xliff:g> θέλει να εμφανίζει τμήματα της εφαρμογής <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Επεξεργασία"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> εκτελείται στο παρασκήνιο για πολύ ώρα. Πατήστε για έλεγχο."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Έλεγχος ενεργών εφαρμογών"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Δεν είναι δυνατή η πρόσβαση στην κάμερα από αυτήν τη συσκευή."</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index d417a07..96369c4 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Temporarily turned off by your operator for SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Can’t reach mobile network"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Try changing preferred network. Tap to change."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Emergency calling unavailable"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Can’t make emergency calls over Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Emergency calls may be unavailable"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> doesn\'t support emergency calls over Wi-Fi. Tap for details."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerts"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Call forwarding"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Emergency callback mode"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Allows the app to modify your Android TV device\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to delete or modify your call log."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"access body sensors (like heart rate monitors)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Access to data from body sensors, such as heart rate, temperature, blood oxygen percentage, etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"access body sensors (like heart rate monitors) while in the background"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Access to data from body sensors, such as heart rate, temperature, blood oxygen percentage, etc. while in the background."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Access body sensor data, like heart rate, while in use"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in use."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in the background."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Allows the app to read audio files from your shared storage."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"read video files from shared storage"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Allows the app to read video files from your shared storage."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"read image files from shared storage"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Allows the app to read image files from your shared storage."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"read image files from shared storage"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Allows the app to read image files from your shared storage."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modify or delete the contents of your shared storage"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Allows the app to write the contents of your shared storage."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"make/receive SIP calls"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Press Menu to unlock or place emergency call."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Press Menu to unlock."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Draw pattern to unlock"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Emergency call"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergency"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Return to call"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correct!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Try again"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Never"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"You don\'t have permission to open this page."</string>
<string name="text_copied" msgid="2531420577879738860">"Text copied to clipboard."</string>
- <string name="copied" msgid="4675902854553014676">"Copied"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from your clipboard"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted text that you copied"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Allows an app to ask for permission to ignore battery optimisations for that app."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"query all packages"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Allows an app to see all installed packages."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"access SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Allows an application to access SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"access AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Allows an application to access AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"access AdServices Attribution APIs"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Allows an application to access AdServices Attribution APIs."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"access AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Allows an application to access AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tap twice for zoom control"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Couldn\'t add widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Go"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Owner"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Guest"</string>
<string name="error_message_title" msgid="4082495589294631966">"Error"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"This change isn\'t allowed by your admin"</string>
<string name="app_not_found" msgid="3429506115332341800">"No application found to handle this action"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"UNINSTALL"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPEN ANYWAY"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Harmful app detected"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"System log access request"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> requests system logs for functional debugging. These logs might contain information that apps and services on your device have written."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs and your device manufacturer may still be able to access some logs or info on your device. Learn more"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Cannot access camera from this device"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 309f09e..5dfbd28 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Temporarily turned off by your operator for SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Can’t reach mobile network"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Try changing preferred network. Tap to change."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Emergency calling unavailable"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Can’t make emergency calls over Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Emergency calls may be unavailable"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> doesn\'t support emergency calls over Wi-Fi. Tap for details."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerts"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Call forwarding"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Emergency callback mode"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Allows the app to modify your Android TV device\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to delete or modify your call log."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"access body sensors (like heart rate monitors)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Access to data from body sensors, such as heart rate, temperature, blood oxygen percentage, etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"access body sensors (like heart rate monitors) while in the background"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Access to data from body sensors, such as heart rate, temperature, blood oxygen percentage, etc. while in the background."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Access body sensor data, like heart rate, while in use"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in use."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in the background."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Allows the app to read audio files from your shared storage."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"read video files from shared storage"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Allows the app to read video files from your shared storage."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"read image files from shared storage"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Allows the app to read image files from your shared storage."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"read image files from shared storage"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Allows the app to read image files from your shared storage."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modify or delete the contents of your shared storage"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Allows the app to write the contents of your shared storage."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"make/receive SIP calls"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Press Menu to unlock or place emergency call."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Press Menu to unlock."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Draw pattern to unlock"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Emergency call"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergency"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Return to call"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correct!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Try again"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Never"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"You don\'t have permission to open this page."</string>
<string name="text_copied" msgid="2531420577879738860">"Text copied to clipboard."</string>
- <string name="copied" msgid="4675902854553014676">"Copied"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from your clipboard"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted text that you copied"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Allows an app to ask for permission to ignore battery optimisations for that app."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"query all packages"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Allows an app to see all installed packages."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"access SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Allows an application to access SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"access AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Allows an application to access AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"access AdServices Attribution APIs"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Allows an application to access AdServices Attribution APIs."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"access AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Allows an application to access AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tap twice for zoom control"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Couldn\'t add widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Go"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Owner"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Guest"</string>
<string name="error_message_title" msgid="4082495589294631966">"Error"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"This change isn\'t allowed by your admin"</string>
<string name="app_not_found" msgid="3429506115332341800">"No application found to handle this action"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"UNINSTALL"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPEN ANYWAY"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Harmful app detected"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"System log access request"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> requests system logs for functional debugging. These logs might contain information that apps and services on your device have written."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs and your device manufacturer may still be able to access some logs or info on your device. Learn more"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Cannot access camera from this device"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 9b4a7a8..9b79587 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Temporarily turned off by your operator for SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Can’t reach mobile network"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Try changing preferred network. Tap to change."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Emergency calling unavailable"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Can’t make emergency calls over Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Emergency calls may be unavailable"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> doesn\'t support emergency calls over Wi-Fi. Tap for details."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerts"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Call forwarding"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Emergency callback mode"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Allows the app to modify your Android TV device\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to delete or modify your call log."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"access body sensors (like heart rate monitors)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Access to data from body sensors, such as heart rate, temperature, blood oxygen percentage, etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"access body sensors (like heart rate monitors) while in the background"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Access to data from body sensors, such as heart rate, temperature, blood oxygen percentage, etc. while in the background."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Access body sensor data, like heart rate, while in use"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in use."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in the background."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Allows the app to read audio files from your shared storage."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"read video files from shared storage"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Allows the app to read video files from your shared storage."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"read image files from shared storage"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Allows the app to read image files from your shared storage."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"read image files from shared storage"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Allows the app to read image files from your shared storage."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modify or delete the contents of your shared storage"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Allows the app to write the contents of your shared storage."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"make/receive SIP calls"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Press Menu to unlock or place emergency call."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Press Menu to unlock."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Draw pattern to unlock"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Emergency call"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergency"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Return to call"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correct!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Try again"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Never"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"You don\'t have permission to open this page."</string>
<string name="text_copied" msgid="2531420577879738860">"Text copied to clipboard."</string>
- <string name="copied" msgid="4675902854553014676">"Copied"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from your clipboard"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted text that you copied"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Allows an app to ask for permission to ignore battery optimisations for that app."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"query all packages"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Allows an app to see all installed packages."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"access SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Allows an application to access SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"access AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Allows an application to access AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"access AdServices Attribution APIs"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Allows an application to access AdServices Attribution APIs."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"access AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Allows an application to access AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tap twice for zoom control"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Couldn\'t add widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Go"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Owner"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Guest"</string>
<string name="error_message_title" msgid="4082495589294631966">"Error"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"This change isn\'t allowed by your admin"</string>
<string name="app_not_found" msgid="3429506115332341800">"No application found to handle this action"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"UNINSTALL"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPEN ANYWAY"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Harmful app detected"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"System log access request"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> requests system logs for functional debugging. These logs might contain information that apps and services on your device have written."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs and your device manufacturer may still be able to access some logs or info on your device. Learn more"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Cannot access camera from this device"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 34f5337..cef7480 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Temporarily turned off by your operator for SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Can’t reach mobile network"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Try changing preferred network. Tap to change."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Emergency calling unavailable"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Can’t make emergency calls over Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Emergency calls may be unavailable"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> doesn\'t support emergency calls over Wi-Fi. Tap for details."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerts"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Call forwarding"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Emergency callback mode"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Allows the app to modify your Android TV device\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to delete or modify your call log."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"access body sensors (like heart rate monitors)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Access to data from body sensors, such as heart rate, temperature, blood oxygen percentage, etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"access body sensors (like heart rate monitors) while in the background"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Access to data from body sensors, such as heart rate, temperature, blood oxygen percentage, etc. while in the background."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Access body sensor data, like heart rate, while in use"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in use."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in the background."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Allows the app to read audio files from your shared storage."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"read video files from shared storage"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Allows the app to read video files from your shared storage."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"read image files from shared storage"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Allows the app to read image files from your shared storage."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"read image files from shared storage"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Allows the app to read image files from your shared storage."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modify or delete the contents of your shared storage"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Allows the app to write the contents of your shared storage."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"make/receive SIP calls"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Press Menu to unlock or place emergency call."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Press Menu to unlock."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Draw pattern to unlock"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Emergency call"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergency"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Return to call"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correct!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Try again"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Never"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"You don\'t have permission to open this page."</string>
<string name="text_copied" msgid="2531420577879738860">"Text copied to clipboard."</string>
- <string name="copied" msgid="4675902854553014676">"Copied"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from your clipboard"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted text that you copied"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Allows an app to ask for permission to ignore battery optimisations for that app."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"query all packages"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Allows an app to see all installed packages."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"access SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Allows an application to access SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"access AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Allows an application to access AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"access AdServices Attribution APIs"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Allows an application to access AdServices Attribution APIs."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"access AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Allows an application to access AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tap twice for zoom control"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Couldn\'t add widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Go"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Owner"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Guest"</string>
<string name="error_message_title" msgid="4082495589294631966">"Error"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"This change isn\'t allowed by your admin"</string>
<string name="app_not_found" msgid="3429506115332341800">"No application found to handle this action"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"UNINSTALL"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPEN ANYWAY"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Harmful app detected"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"System log access request"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> requests system logs for functional debugging. These logs might contain information that apps and services on your device have written."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs and your device manufacturer may still be able to access some logs or info on your device. Learn more"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Cannot access camera from this device"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 3da96a9..4f91ab0 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Temporarily turned off by your carrier for SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Can’t reach mobile network"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Try changing preferred network. Tap to change."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Emergency calling unavailable"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Can’t make emergency calls over Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Emergency calls may be unavailable"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> doesn\'t support emergency calls over Wi-Fi. Tap for details."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerts"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Call forwarding"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Emergency callback mode"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Allows the app to modify your Android TV device\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"access body sensors (like heart rate monitors)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Access to data from body sensors such as heart rate, temperature, blood oxygen percentage, etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"access body sensors (like heart rate monitors) while in the background"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Access to data from body sensors such as heart rate, temperature, blood oxygen percentage, etc. while in the background."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Access body sensor data, like heart rate, while in use"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in use."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in the background."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Allows the app to read audio files from your shared storage."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"read video files from shared storage"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Allows the app to read video files from your shared storage."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"read image files from shared storage"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Allows the app to read image files from your shared storage."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"read image files from shared storage"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Allows the app to read image files from your shared storage."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modify or delete the contents of your shared storage"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Allows the app to write the contents of your shared storage."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"make/receive SIP calls"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Press Menu to unlock or place emergency call."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Press Menu to unlock."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Draw pattern to unlock"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Emergency call"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergency"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Return to call"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correct!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Try again"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Never"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"You don\'t have permission to open this page."</string>
<string name="text_copied" msgid="2531420577879738860">"Text copied to clipboard."</string>
- <string name="copied" msgid="4675902854553014676">"Copied"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted from your clipboard"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pasted text you copied"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Allows an app to ask for permission to ignore battery optimizations for that app."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"query all packages"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Allows an app to see all installed packages."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"access SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Allows an application to access SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"access AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Allows an application to access AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"access AdServices Attribution APIs"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Allows an application to access AdServices Attribution APIs."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"access AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Allows an application to access AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tap twice for zoom control"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Couldn\'t add widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Go"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Owner"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Guest"</string>
<string name="error_message_title" msgid="4082495589294631966">"Error"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"This change isn\'t allowed by your admin"</string>
<string name="app_not_found" msgid="3429506115332341800">"No application found to handle this action"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"UNINSTALL"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPEN ANYWAY"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Harmful app detected"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"System log access request"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> requests system logs for functional debugging. These logs might contain information that apps and services on your device have written."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs and your device manufacturer may still be able to access some logs or info on your device. Learn more"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Cannot access camera from this device"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f965231..fb27592 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"El proveedor desactivó temporalmente el servicio para la SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"No se puede acceder a la red móvil"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Presiona para cambiar la red preferida."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Servicio de llamadas de emergencia no disponible"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"No se pueden hacer llamadas de emergencia mediante Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Es posible que las llamadas de emergencia no estén disponibles"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> no admite llamadas de emergencia por Wi-Fi. Presiona para ver más detalles"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Desvío de llamada"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modo de devolución de llamada de emergencia"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permite que la aplicación modifique el registro de llamadas de la tablet, incluidos los datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permite que la app modifique el registro de llamadas del dispositivo Android TV, incluidos datos sobre llamadas entrantes y salientes. Las apps maliciosas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permite que la aplicación modifique el registro de llamadas del dispositivo, incluidos los datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"acceder a los sensores corporales (como los monitores de frecuencia cardíaca)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Acceso a datos de sensores corporales, como el ritmo cardíaco, la temperatura, el porcentaje de oxígeno en sangre, etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"acceso a sensores corporales (p. ej., ritmo cardíaco) en segundo plano"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Acceso en segundo plano a datos de sensores corporales, como el ritmo cardíaco, la temperatura, el porcentaje de oxígeno en sangre, etc."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Accede a datos del sensor corporal, como el ritmo cardíaco, mientras está en uso"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que la app acceda a datos del sensor corporal, como el ritmo cardíaco, la temperatura y el porcentaje de oxígeno en sangre, mientras la app está en uso."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accede a datos del sensor corporal, como el ritmo cardíaco, en segundo plano"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que la app acceda a datos del sensor corporal, como el ritmo cardíaco, la temperatura y el porcentaje de oxígeno en sangre, mientras la app está en segundo plano."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Leer eventos y detalles del calendario"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta app puede leer todos los eventos del calendario de tu tablet y compartir o guardar los datos correspondientes."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta app puede leer todos los eventos del calendario guardados en el dispositivo Android TV, así como compartir o almacenar los datos correspondientes."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permite que la app lea los archivos de audio del almacenamiento compartido."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"leer los archivos de video del almacenamiento compartido"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permite que la app lea los archivos de video del almacenamiento compartido."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"leer los archivos de imagen del almacenamiento compartido"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Permite que la app lea los archivos de imagen del almacenamiento compartido."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"leer los archivos de imagen del almacenamiento compartido"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permite que la app lea los archivos de imagen del almacenamiento compartido."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"cambiar o borrar contenido de almacenamiento compartido"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Editar almacen. compartido"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"realizar/recibir llamadas SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Presiona el Menú para desbloquear o realizar una llamada de emergencia."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Presionar Menú para desbloquear."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Dibujar el patrón de desbloqueo"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Llamada de emergencia"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergencia"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Regresar a llamada"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correcto"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Vuelve a intentarlo."</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nunca"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"No tienes permiso para abrir esta página."</string>
<string name="text_copied" msgid="2531420577879738860">"Texto copiado en el portapapeles."</string>
- <string name="copied" msgid="4675902854553014676">"Copiado"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegó contenido de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegó información del portapapeles"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> accedió a texto del portapapeles"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite que una app solicite permiso para ignorar las optimizaciones de la batería."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"Búsqueda de todos los paquetes"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permite que una app vea todos los paquetes que se instalaron."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"Acceder a SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Permite que una aplicación acceda a SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"acceder a la API de AdServices Topics"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Permite que una aplicación acceda a la API de AdServices Topics."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"acceder a las APIs de AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Permite que una aplicación acceda a las APIs de AdServices Attribution."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"acceder a la API de AdServices Custom Audiences"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Permite que una aplicación acceda a la API de AdServices Custom Audiences."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Presiona dos veces para obtener el control del zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"No se pudo agregar el widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Saliendo de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Propietario"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Invitado"</string>
<string name="error_message_title" msgid="4082495589294631966">"Error"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Tu administrador no permite este cambio"</string>
<string name="app_not_found" msgid="3429506115332341800">"No se encontró una aplicación para manejar esta acción."</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DESINSTALAR"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR DE TODOS MODOS"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Se detectó una app dañina"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Solicitud de acceso a registro de sist."</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"¿Quieres permitir que <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acceda a todos los registros del dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Solo esta vez"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"No permitir"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> requiere registros del sistema para una depuración correcta. Es posible que estos registros contengan información que hayan escrito apps y servicios en tu dispositivo."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Los registros del dispositivo permiten documentar lo que sucede en él. Las apps pueden usar estos registros para encontrar y solucionar problemas.\n\nEs posible que algunos registros del dispositivo contengan información sensible, por lo que solo permitimos que accedan a todos ellos apps de tu confianza. \n\nSi no permites que esta app acceda a todos los registros del dispositivo, aún puede acceder a sus propios registros. Además, es posible que el fabricante del dispositivo acceda a algunos registros o información en tu dispositivo. Más información"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"No volver a mostrar"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quiere mostrar fragmentos de <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Hace mucho tiempo que <xliff:g id="APP">%1$s</xliff:g> se está ejecutando en segundo plano. Presiona para revisar esta actividad."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consulta las apps activas"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"No se puede acceder a la cámara desde este dispositivo"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 8231b01b..d0568e0 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Tu operador ha desactivado el servicio de la SIM <xliff:g id="SIMNUMBER">%d</xliff:g> de forma temporal"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"No se puede establecer conexión con la red móvil"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Toca para cambiar la red preferida."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Servicio de llamadas de emergencia no disponible"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"No se pueden hacer llamadas de emergencia por Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Las llamadas de emergencia pueden no estar disponibles"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> no permite hacer llamadas de emergencia por Wi-Fi. Toca para ver información detallada."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Desvío de llamadas"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modo de devolución de llamada de emergencia"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permite que la aplicación modifique el registro de llamadas del tablet, incluidos datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permite que la aplicación edite el registro de llamadas de tu dispositivo Android TV, incluidos sus datos sobre llamadas entrantes y salientes. Las aplicaciones maliciosas pueden usar este permiso para borrar o editar el registro de llamadas."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permite que la aplicación modifique el registro de llamadas del teléfono, incluidos datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"sensores corp. (como monitores frec. cardíaca)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Acceso a datos de sensores corporales, como la frecuencia cardiaca, la temperatura, el porcentaje de oxígeno en sangre, etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"acceso a sensores corporales (como monitores de frec. cardiaca) en segundo plano"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Acceso a datos de sensores corporales, como la frecuencia cardiaca, la temperatura, el porcentaje de oxígeno en sangre, etc., en segundo plano."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Acceso mientras se usa a datos del sensor corporal, como la frecuencia cardiaca"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que la aplicación acceda a datos del sensor corporal, como la frecuencia cardiaca, la temperatura y el porcentaje de oxígeno en sangre, mientras se usa."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acceso en segundo plano a datos del sensor corporal, como la frecuencia cardiaca"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que la aplicación acceda a datos del sensor corporal, como la frecuencia cardiaca, la temperatura y el porcentaje de oxígeno en sangre, mientras está en segundo plano."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Leer eventos y detalles del calendario"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta aplicación puede leer los eventos de calendario almacenados en tu tablet y compartir o guardar los datos de tu calendario."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta aplicación puede ver los eventos de calendario almacenados en tu dispositivo Android TV y compartir o guardar los datos de tu calendario."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permite que la aplicación lea archivos de audio desde tu almacenamiento compartido."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"leer archivos de vídeo desde el almacenamiento compartido"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permite que la aplicación lea archivos de vídeo desde tu almacenamiento compartido."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"leer archivos de imagen desde el almacenamiento compartido"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Permite que la aplicación lea archivos de imagen desde tu almacenamiento compartido."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"leer archivos de imagen desde el almacenamiento compartido"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permite que la aplicación lea archivos de imagen desde tu almacenamiento compartido."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"editar/eliminar contenido de almacenamiento compartido"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Permite que app edite contenido de almacenamiento compartido."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"hacer/recibir llamadas SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Pulsa la tecla de menú para desbloquear el teléfono o realizar una llamada de emergencia."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Pulsa la tecla de menú para desbloquear la pantalla."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Dibujar patrón de desbloqueo"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Llamada de emergencia"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergencia"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Volver a llamada"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correcto"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Vuelve a intentarlo"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nunca"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"No tienes permiso para abrir esta página."</string>
<string name="text_copied" msgid="2531420577879738860">"Texto copiado al portapapeles."</string>
- <string name="copied" msgid="4675902854553014676">"Copiado"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha pegado contenido de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha pegado contenido desde el portapapeles"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha pegado texto que has copiado"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite que una aplicación solicite permiso para ignorar las optimizaciones de la batería."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"consultar todos los paquetes"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permite que una aplicación vea todos los paquetes instalados."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"acceder a SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Permite que una aplicación acceda a SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"acceder a la API AdServices Topics"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Permite que una aplicación acceda a la API AdServices Topics."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"acceder a las APIs AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Permite que una aplicación acceda a las APIs AdServices Attribution."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"acceder a la API AdServices Custom Audiences"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Permite que una aplicación acceda a la API AdServices Custom Audiences."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Da dos toques para acceder al control de zoom."</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"No se ha podido añadir el widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Cerrando la sesión de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Propietario"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Invitado"</string>
<string name="error_message_title" msgid="4082495589294631966">"Error"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"El administrador no permite realizar este cambio"</string>
<string name="app_not_found" msgid="3429506115332341800">"No se ha encontrado ninguna aplicación que pueda realizar esta acción."</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DESINSTALAR"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR IGUALMENTE"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Se ha detectado una aplicación dañina"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Solicitud de acceso a registro del sistema"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"¿Permitir que <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acceda a todos los registros del dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Solo esta vez"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"No permitir"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> necesita los registros del sistema para hacer depuraciones funcionales. Es posible que estos registros contengan información introducida por las aplicaciones y los servicios de tu dispositivo."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Los registros del dispositivo documentan lo que sucede en tu dispositivo. Las aplicaciones pueden usar estos registros para encontrar y solucionar problemas.\n\nComo algunos registros pueden contener información sensible, es mejor que solo permitas que accedan a ellos las aplicaciones en las que confíes. \n\nAunque no permitas que esta aplicación acceda a todos los registros del dispositivo, aún podrá acceder a sus propios registros. Además, es posible que el fabricante del dispositivo pueda acceder a algunos registros o información de tu dispositivo. Más información"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"No volver a mostrar"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quiere mostrar fragmentos de <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> lleva mucho tiempo ejecutándose en segundo plano. Toca para revisarlo."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consultar aplicaciones activas"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"No se puede acceder a la cámara desde este dispositivo"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index a3bdfc9..7b14c95 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Operaator on SIM-kaardi <xliff:g id="SIMNUMBER">%d</xliff:g> puhul ajutiselt välja lülitanud"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobiilsidevõrguga ei saa ühendust"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Proovige eelistatud võrku vahetada. Puudutage muutmiseks."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hädaabikõned pole saadaval"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"WiFi kaudu ei saa hädaabikõnesid teha"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Hädaabikõned ei pruugi saadaval olla"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ei toeta WiFi kaudu hädaabikõnede tegemist. Puudutage üksikasjade nägemiseks."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Teatised"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Kõnede suunamine"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Hädaolukorra tagasihelistusrežiim"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Lubab rakendusel muuta tahvelarvuti kõnelogi, sh sissetulevate ja väljaminevate kõnede andmeid. Pahatahtlikud rakendused võivad kasutada seda kõnelogi kustutamiseks või muutmiseks."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Lubab rakendusel muuta teie Android TV seadme kõnelogi, sh sissetulevate ja väljaminevate kõnede andmeid. Pahatahtlikud rakendused võivad kasutada seda kõnelogi kustutamiseks või muutmiseks."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Lubab rakendusel muuta telefoni kõnelogi, sh sissetulevate ja väljaminevate kõnede andmeid. Pahatahtlikud rakendused võivad kasutada seda kõnelogi kustutamiseks või muutmiseks."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"juurdepääs kehaanduritele (nt pulsilugeja)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Juurdepääs kehaandurite andmetele, nagu pulss, temperatuur, vere hapnikusisalduse protsent jne."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"taustal töötades juurdepääs kehaanduritele (nt pulsilugeja)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Taustal töötades juurdepääs kehaandurite andmetele, nagu pulss, temperatuur, vere hapnikusisalduse protsent jne."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Juurdepääs kehaanduri andmetele, nagu pulss, kui rakendust kasutatakse"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Lubab rakendusel pääseda juurde kehaanduri andmetele, nagu pulss, temperatuur ja vere hapnikusisaldus, kui rakendust kasutatakse."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Juurdepääs kehaanduri andmetele, nagu pulss, kui rakendus töötab taustal"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Lubab rakendusel pääseda juurde kehaanduri andmetele, nagu pulss, temperatuur ja vere hapnikusisaldus, kui rakendus töötab taustal."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Kalendrisündmuste ja üksikasjade lugemine"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"See rakendus saab kõiki teie tahvelarvutisse salvestatud kalendrisündmusi lugeda ja teie kalendriandmeid jagada või salvestada."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"See rakendus saab kõiki teie Android TV seadmesse salvestatud kalendrisündmusi lugeda ja teie kalendriandmeid jagada või salvestada."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Võimaldab rakendusel lugeda teie jagatud salvestusruumis olevaid helifaile."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"lugeda teie jagatud salvestusruumis olevaid videofaile"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Võimaldab rakendusel lugeda teie jagatud salvestusruumis olevaid videofaile."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"lugeda teie jagatud salvestusruumis olevaid pildifaile"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Võimaldab rakendusel lugeda teie jagatud salvestusruumis olevaid pildifaile."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"lugeda teie jagatud salvestusruumis olevaid pildifaile"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Võimaldab rakendusel lugeda teie jagatud salvestusruumis olevaid pildifaile."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"Jagatud salvestusruumi sisu muutmine või kustutamine"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Lubab rakendusel kirjutada jagatud salvestusruumi sisu."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP-kõnede tegemine/vastuvõtmine"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Vajutage avamiseks või hädaabikõne tegemiseks menüünuppu"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Vajutage avamiseks menüüklahvi."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Avamiseks joonistage muster"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Hädaabikõne"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Hädaabi"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Kõne juurde tagasi"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Õige."</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Proovige uuesti"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Mitte kunagi"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Teil pole luba selle lehe avamiseks."</string>
<string name="text_copied" msgid="2531420577879738860">"Lõikelauale kopeeritud tekst."</string>
- <string name="copied" msgid="4675902854553014676">"Kopeeritud"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> kleepis rakendusest <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> kleepis teie lõikelaualt"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> kleepis teie kopeeritud teksti"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Lubab rakendusel küsida luba rakenduse aku optimeerimise eiramiseks."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"päringute esitamine kõikide pakettide kohta"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Võimaldab rakendusel näha kõiki installitud pakette."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"juurdepääs üksusele SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Annab rakendusele juurdepääsu üksusele SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"juurdepääs AdServices Topics API-dele"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Annab rakendusele juurdepääsu AdServices Topics API-dele."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"juurdepääs AdServices Attribution API-dele"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Annab rakendusele juurdepääsu AdServices Attribution API-dele."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"juurdepääs AdServices Custom Audiences API-dele"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Annab rakendusele juurdepääsu AdServices Custom Audiences API-dele."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Suumi kasutamiseks koputage kaks korda"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Vidinat ei saanud lisada."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Mine"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Üleminek kasutajale <xliff:g id="NAME">%1$s</xliff:g> ..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Kasutaja <xliff:g id="NAME">%1$s</xliff:g> väljalogimine …"</string>
<string name="owner_name" msgid="8713560351570795743">"Omanik"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Külaline"</string>
<string name="error_message_title" msgid="4082495589294631966">"Viga"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Administraator on selle muudatuse keelanud"</string>
<string name="app_not_found" msgid="3429506115332341800">"Selle toimingu käsitlemiseks ei leitud ühtegi rakendust"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DESINSTALLI"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"AVA IKKA"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Tuvastati kahjulik rakendus"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Süsteemilogi juurdepääsutaotlus"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Kas anda rakendusele <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> juurdepääs kõigile seadmelogidele?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Ainult see kord"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ära luba"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> taotleb funktsionaalseks silumiseks süsteemilogisid. Need logid võivad sisaldada teavet, mille teie seadmes olevad rakendused ja teenused on kirjutanud."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Seadmelogid jäädvustavad, mis teie seadmes toimub. Rakendused saavad neid logisid kasutada probleemide tuvastamiseks ja lahendamiseks.\n\nMõned logid võivad sisaldada tundlikku teavet, seega lubage juurdepääs kõigile seadmelogidele ainult rakendustele, mida usaldate. \n\nKui te ei luba sellel rakendusel kõigile seadmelogidele juurde pääseda, pääseb see siiski juurde oma logidele. Samuti võib teie seadme tootja teie seadmes siiski teatud logidele või teabele juurde pääseda. Lisateave"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ära kuva uuesti"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Rakendus <xliff:g id="APP_0">%1$s</xliff:g> soovib näidata rakenduse <xliff:g id="APP_2">%2$s</xliff:g> lõike"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Muuda"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> on taustal töötanud kaua aega. Puudutage ülevaatamiseks."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vaadake aktiivseid rakendusi"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Sellest seadmest ei pääse kaamerale juurde"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index b0097b4..af1de86 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Operadoreak <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela desaktibatu egin du aldi baterako"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Ezin da konektatu sare mugikorrera"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Aldatu sare hobetsia. Sakatu aldatzeko."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Ezin da egin larrialdi-deirik"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Ezin duzu egin larrialdi-deirik Wi-Fi bidez"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Baliteke larrialdi-deiak erabilgarri ez egotea"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> hornitzaileak ez du onartzen larrialdi-deiak wifi bidez egitea. Sakatu hau xehetasunak ikusteko."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertak"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Dei-desbideratzea"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Larrialdi-zerbitzuen deiak jasotzeko modua"</string>
@@ -291,7 +291,7 @@
<string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Erabilerraztasun-hobespenak"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ari da bateria erabiltzen"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikazio ari dira bateria erabiltzen"</string>
- <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Sakatu bateria eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
+ <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Sakatu bateria eta datu-erabilerari buruzko xehetasunak ikusteko"</string>
<string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="8974401416068943888">"Modu segurua"</string>
<string name="android_system_label" msgid="5974767339591067210">"Android sistema"</string>
@@ -392,7 +392,7 @@
<string name="permlab_runInBackground" msgid="541863968571682785">"exekutatu atzeko planoan"</string>
<string name="permdesc_runInBackground" msgid="4344539472115495141">"Atzeko planoan exekuta liteke aplikazioa eta horrek bizkorrago agor lezake bateria."</string>
<string name="permlab_useDataInBackground" msgid="783415807623038947">"erabili datuak atzeko planoan"</string>
- <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Aplikazioak datuak erabil litzake atzeko planoan eta horrek datuen erabilera areago lezake."</string>
+ <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Aplikazioak datuak erabil litzake atzeko planoan eta horrek datu-erabilera areago lezake."</string>
<string name="permlab_persistentActivity" msgid="464970041740567970">"izan aplikazioa beti abian"</string>
<string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Beren zati batzuk memoria modu iraunkorrean ezartzeko baimena ematen die aplikazioei. Horrela, beste aplikazioek erabilgarri duten memoria murritz daiteke eta tableta motel daiteke."</string>
<string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Beren zati batzuk memorian modu iraunkorrean ezartzeko baimena ematen die aplikazioei. Ondorioz, beste aplikazioek memoria gutxiago izan lezakete erabilgarri, eta Android TV gailuak motelago funtziona lezake."</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Tabletaren deien erregistroa aldatzeko baimena ematen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Asmo txarreko aplikazioek deien erregistroa ezabatzeko edo aldatzeko erabil dezakete."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Android TV gailuko deien erregistroa aldatzeko baimena ematen die aplikazioei, jasotako eta egindako deiei buruzko datuak barne. Baliteke asmo txarreko aplikazioek deien erregistroa ezabatzea edo aldatzea."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Telefonoaren deien erregistroa aldatzeko baimena ematen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Asmo txarreko aplikazioek deien erregistroa ezabatzeko edo aldatzeko erabil dezakete."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"Atzitu gorputzaren sentsoreak (adibidez, bihotz-maiztasunarenak)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Gorputz-sentsoreen datuak atzitzeko baimena; esate baterako, bihotz-maiztasuna, tenperatura, odolean dagoen oxigenoaren ehunekoa, etab."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"atzitu atzeko planoan gorputz-sentsoreak (adibidez, bihotz-maiztasunaren neurgailuak)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Atzeko planoan gorputz-sentsoreen datuak atzitzeko baimena; esate baterako, bihotz-maiztasuna, tenperatura, odolean dagoen oxigenoaren ehunekoa, etab."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Atzitu gorputz-sentsoreen datuak (esaterako, bihotz-maiztasuna) aplikazioa erabili bitartean"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Aplikazioak erabiltzen diren bitartean, gorputz-sentsoreen datuak (besteak beste, bihotz-maiztasuna, tenperatura eta odolean dagoen oxigenoaren ehunekoa) atzitzeko baimena ematen die aplikazio horiei."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Atzitu gorputz-sentsoreen datuak (esaterako, bihotz-maiztasuna) aplikazioa atzeko planoan dagoen bitartean"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Aplikazioak atzeko planoan egon bitartean, gorputz-sentsoreen datuak (besteak beste, bihotz-maiztasuna, tenperatura eta odolean dagoen oxigenoaren ehunekoa) atzitzeko baimena ematen die aplikazio horiei."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"irakurri egutegiko gertaerak eta xehetasunak"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aplikazioak tabletan gordetako egutegiko gertaerak irakur ditzake eta egutegiko datuak parteka eta gorde ditzake."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aplikazioak Android TV gailuan gordeta dituzun egutegiko gertaerak irakur ditzake, baita egutegiko datuak partekatu eta gorde ere."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Biltegi partekatuko audio-fitxategiak irakurtzeko baimena ematen die aplikazioei."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"irakurri biltegi partekatuko bideo-fitxategiak"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Biltegi partekatuko bideo-fitxategiak irakurtzeko baimena ematen die aplikazioei."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"irakurri biltegi partekatuko irudi-fitxategiak"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Biltegi partekatuko irudi-fitxategiak irakurtzeko baimena ematen die aplikazioei."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"irakurri biltegi partekatuko irudi-fitxategiak"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Biltegi partekatuko irudi-fitxategiak irakurtzeko baimena ematen die aplikazioei."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"aldatu edo ezabatu biltegi partekatuko edukia"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Biltegi partekatuko edukian idazteko baimena ematen die aplikazioei."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"egin/jaso SIP deiak"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Desblokeatzeko edo larrialdi-deia egiteko, sakatu Menua."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Desblokeatzeko, sakatu Menua."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Desblokeatzeko, marraztu eredua"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Larrialdi-deia"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Larrialdi-deiak"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Itzuli deira"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Eredua zuzena da!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Saiatu berriro"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Inoiz ez"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Ez duzu orri hau irekitzeko baimenik."</string>
<string name="text_copied" msgid="2531420577879738860">"Testua arbelean kopiatu da."</string>
- <string name="copied" msgid="4675902854553014676">"Kopiatu da"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> aplikaziotik itsatsi da <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> aplikazioak arbeleko edukia itsatsi du"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> aplikazioak kopiatu duzun testua itsatsi du"</string>
@@ -1066,7 +1065,7 @@
<string name="menu_sym_shortcut_label" msgid="4037566049061218776">"Sym +"</string>
<string name="menu_function_shortcut_label" msgid="2367112760987662566">"Funtzioa +"</string>
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"zuriunea tekla"</string>
- <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"sartu tekla"</string>
+ <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"\"sartu\" tekla"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ezabatu"</string>
<string name="search_go" msgid="2141477624421347086">"Bilatu"</string>
<string name="search_hint" msgid="455364685740251925">"Bilatu…"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Bateriaren optimizazioei ez ikusi egiteko baimena eskatzea baimentzen die aplikazioei."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"Kontsultatu pakete guztiak"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Instalatutako pakete guztiak ikusteko baimena ematen dio aplikazioari."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"atzitu SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"SupplementalApis direlakoak (API osagarriak) atzitzeko baimena ematen die aplikazioei."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics APIa atzitu"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"AdServices Topics APIa atzitzeko baimena ematen die aplikazioei."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution APIak atzitu"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"AdServices Attribution APIak atzitzeko baimena ematen die aplikazioei."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences APIa atzitu"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"AdServices Custom Audiences APIa atzitzeko baimena ematen die aplikazioei."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Sakatu birritan zooma kontrolatzeko"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Ezin izan da widgeta gehitu."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Joan"</string>
@@ -1464,7 +1467,7 @@
<string name="ime_action_previous" msgid="6548799326860401611">"Atzera"</string>
<string name="ime_action_default" msgid="8265027027659800121">"Abiarazi"</string>
<string name="dial_number_using" msgid="6060769078933953531">"Markatu zenbakia \n<xliff:g id="NUMBER">%s</xliff:g> erabilita"</string>
- <string name="create_contact_using" msgid="6200708808003692594">"Sortu kontaktua\n<xliff:g id="NUMBER">%s</xliff:g> erabilita"</string>
+ <string name="create_contact_using" msgid="6200708808003692594">"Sortu kontaktu bat\n<xliff:g id="NUMBER">%s</xliff:g> erabilita"</string>
<string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Aplikazio hauetako bat edo gehiago kontua orain eta etorkizunean atzitzeko baimena eskatzen ari dira."</string>
<string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Eskaera onartu nahi duzu?"</string>
<string name="grant_permissions_header_text" msgid="3420736827804657201">"Sarbide-eskaera"</string>
@@ -1568,7 +1571,7 @@
<string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> enpresaren USB bidezko unitatea"</string>
<string name="storage_usb" msgid="2391213347883616886">"USB bidezko memoria"</string>
<string name="extract_edit_menu_button" msgid="63954536535863040">"Editatu"</string>
- <string name="data_usage_warning_title" msgid="9034893717078325845">"Datuen erabileraren abisua"</string>
+ <string name="data_usage_warning_title" msgid="9034893717078325845">"Datu-erabileraren abisua"</string>
<string name="data_usage_warning_body" msgid="1669325367188029454">"<xliff:g id="APP">%s</xliff:g> erabili dituzu"</string>
<string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"Datu-konexioaren mugara iritsi zara"</string>
<string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Wi-Fi datuen mugara iritsi zara"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"\"<xliff:g id="NAME">%1$s</xliff:g>\" erabiltzailera aldatzen…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzailearen saioa amaitzen…"</string>
<string name="owner_name" msgid="8713560351570795743">"Jabea"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gonbidatua"</string>
<string name="error_message_title" msgid="4082495589294631966">"Errorea"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Administratzaileak ez du eman aldaketa egiteko baimena"</string>
<string name="app_not_found" msgid="3429506115332341800">"Ez da ekintza gauza dezakeen aplikaziorik aurkitu"</string>
@@ -1854,7 +1858,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"Ados"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Bateria-aurrezleak gai iluna aktibatzen du, eta murriztu edo desaktibatu egiten ditu atzeko planoko jarduerak, zenbait efektu bisual, eta eginbide jakin eta sareko konexio batzuk."</string>
<string name="battery_saver_description" msgid="8518809702138617167">"Bateria-aurrezleak gai iluna aktibatzen du, eta atzeko planoko jarduerak, zenbait efektu bisual, eta eginbide jakin eta sareko konexio batzuk murrizten edo desaktibatzen ditu."</string>
- <string name="data_saver_description" msgid="4995164271550590517">"Datuen erabilera murrizteko, atzeko planoan datuak bidaltzea eta jasotzea galarazten die datu-aurrezleak aplikazio batzuei. Une honetan erabiltzen ari zaren aplikazio batek datuak atzitu ahal izango ditu, baina baliteke maiztasun txikiagoarekin atzitzea. Horrela, adibidez, baliteke irudiak ez erakustea haiek sakatu arte."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Datu-erabilera murrizteko, atzeko planoan datuak bidaltzea eta jasotzea galarazten die datu-aurrezleak aplikazio batzuei. Une honetan erabiltzen ari zaren aplikazio batek datuak atzitu ahal izango ditu, baina baliteke maiztasun txikiagoarekin atzitzea. Horrela, adibidez, baliteke irudiak ez erakustea haiek sakatu arte."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Datu-aurrezlea aktibatu nahi duzu?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Aktibatu"</string>
<string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Minutu batez ({formattedTime} arte)}other{# minutuz ({formattedTime} arte)}}"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DESINSTALATU"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"IREKI, HALA ERE"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Aplikazio kaltegarri bat hauteman da"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Sistemaren erregistroak atzitzeko eskaera"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Gailuko erregistro guztiak atzitzeko baimena eman nahi diozu <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aplikazioari?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Oraingoan soilik"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ez eman baimenik"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aplikazioak sistemaren erregistroak atzitu behar ditu funtzioak arazteko. Litekeena da gailuko aplikazio eta zerbitzuek idatzitako informazioa agertzea erregistro horietan."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Gailuko erregistroetan gailuan gertatzen den guztia gordetzen da. Arazoak bilatu eta konpontzeko erabil ditzakete aplikazioek erregistro horiek.\n\nBaliteke erregistro batzuek kontuzko informazioa edukitzea. Beraz, eman gailuko erregistro guztiak atzitzeko baimena fidagarritzat jotzen dituzun aplikazioei bakarrik. \n\nNahiz eta gailuko erregistro guztiak atzitzeko baimena ez eman aplikazio honi, aplikazioak hari dagozkion erregistroak atzitu ahalko ditu, eta baliteke gailuaren fabrikatzaileak gailuko erregistro edo datu batzuk atzitu ahal izatea. Lortu informazio gehiago"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ez erakutsi berriro"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> aplikazioak <xliff:g id="APP_2">%2$s</xliff:g> aplikazioaren zatiak erakutsi nahi ditu"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Editatu"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> aplikazioak denbora asko darama atzeko planoan exekutatzen. Sakatu berrikusteko."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Ikusi zer aplikazio dauden aktibo"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Ezin da atzitu kamera gailu honetatik"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 5734803..4c3a3fa 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"شرکت مخابراتیتان موقتاً آن را برای سیمکارت <xliff:g id="SIMNUMBER">%d</xliff:g> خاموش کرده است"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"شبکه تلفن همراه دردسترس نیست"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"تغییر شبکه ترجیحی را امتحان کنید. برای تغییر، ضربه بزنید."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"تماس اضطراری امکانپذیر نیست"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"تماس اضطراری ازطریق Wi‑Fi امکانپذیر نیست"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"ممکن است تماسهای اضطراری دردسترس نباشد"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> از تماسهای اضطراری ازطریق Wi-Fi پشتیبانی نمیکند. برای دیدن جزئیات، ضربه بزنید."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"هشدارها"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"بازارسال تماس"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"حالت پاسخ تماس اضطراری"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"به برنامه اجازه میدهد گزارشهای تماس رایانهٔ لوحی شما، از جمله دادههایی درباره تماسهای ورودی و خروجی را تغییر دهد. برنامههای مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"به برنامه اجازه میدهد گزارشهای تماس در دستگاه Android TV را تغییر دهد، ازجمله دادههای مربوط به تماسهای ورودی و خروجی. برنامههای مخرب میتوانند از این مجوز برای پاک کردن یا تغییر دادن گزارش تماس شما استفاده کنند."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"به برنامه اجازه میدهد گزارشات تماس تلفنی شما، از جمله دادههایی درمورد تماسهای ورودی و خروجی را تغییر دهد. برنامههای مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"دسترسی به حسگرهای بدن (مانند پایشگرهای ضربان قلب)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"دسترسی به دادههای حسگرهای بدن مثل ضربان قلب، دما، درصد اکسیژن خون، و غیره."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"دسترسی به حسگرهای بدن (مثل نمایشگرهای ضربان قلب) هنگام اجرا شدن در پسزمینه"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"دسترسی به دادههای حسگرهای بدن مثل ضربان قلب، دما، درصد اکسیژن خون، و غیره، هنگام اجرا شدن در پسزمینه."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"دسترسی به دادههای حسگر بدن، مثل ضربان قلب، درحین استفاده"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"به برنامه اجازه میدهد تا زمانی که درحال استفاده است، به دادههای حسگر بدن، مثل ضربان قلب، دما، و درصد اکسیژن خون دسترسی داشته باشد."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"دسترسی به دادههای حسگر بدن، مثل ضربان قلب، درحین اجرا در پسزمینه"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"به برنامه اجازه میدهد تا زمانی که در پسزمینه درحال اجرا است، به دادههای حسگر بدن، مثل ضربان قلب، دما، و درصد اکسیژن خون دسترسی داشته باشد."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"خواندن رویدادها و جزئیات تقویم"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"این برنامه میتواند همه رویدادهای تقویم ذخیرهشده در رایانه لوحی شما را بخواند و دادههای تقویم شما را به اشتراک بگذارد یا ذخیره کند."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"این برنامه میتواند همه رویدادهای تقویم را که در Android TV شما ذخیرهشده بخواند، و دادههای تقویم شما را همرسانی یا ذخیره کند."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"به برنامه اجازه میدهد فایلهای صوتی موجود در فضای ذخیرهسازی همرسانیشده را بخواند."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"خواندن فایلهای ویدیویی موجود در فضای ذخیرهسازی همرسانیشده"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"به برنامه اجازه میدهد فایلهای ویدیویی موجود در فضای ذخیرهسازی همرسانیشده را بخواند."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"خواندن فایلهای تصویری موجود در فضای ذخیرهسازی همرسانیشده"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"به برنامه اجازه میدهد فایلهای تصویری موجود در فضای ذخیرهسازی همرسانیشده را بخواند."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"خواندن فایلهای تصویری موجود در فضای ذخیرهسازی مشترک"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"به برنامه اجازه میدهد فایلهای تصویری موجود در فضای ذخیرهسازی مشترک را بخواند."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"تغییر یا حذف محتوای فضای ذخیرهسازی مشترک"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"به برنامه اجازه میدهد محتوای فضای ذخیرهسازی مشترکتان را بنویسد."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"تماس گرفتن/دریافت تماس از طریق SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"برای بازکردن قفل یا انجام تماس اضطراری روی «منو» فشار دهید."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"برای بازگشایی قفل روی منو فشار دهید."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"الگو را بکشید تا قفل آن باز شود"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"تماس اضطراری"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"اضطراری"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"بازگشت به تماس"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"صحیح است!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"دوباره امتحان کنید"</string>
@@ -931,7 +931,7 @@
<string name="lockscreen_transport_next_description" msgid="2931509904881099919">"آهنگ بعدی"</string>
<string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"مکث"</string>
<string name="lockscreen_transport_play_description" msgid="106868788691652733">"پخش"</string>
- <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"توقف"</string>
+ <string name="lockscreen_transport_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>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"هیچوقت"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"شما اجازه بازکردن این صفحه را ندارید."</string>
<string name="text_copied" msgid="2531420577879738860">"متن در بریدهدان کپی شد."</string>
- <string name="copied" msgid="4675902854553014676">"کپی شد"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> از <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> جایگذاری کرد"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> محتوا را از بریدهدان جایگذاری کرد"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> نوشتاری را که کپی کردید جایگذاری کرد"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"به یک برنامه اجازه میدهد جهت نادیده گرفتن بهینهسازی باتری برای خود مجوز درخواست کند."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"پُرسمان همه بستهها"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"به برنامه اجازه میدهد همه بستههای نصبشده را ببیند."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"دسترسی به SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"به برنامه اجازه میدهد به SupplementalApis دسترسی داشته باشد."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"دسترسی به میانای برنامهسازی کاربردی AdServices Topics"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"به برنامه اجازه میدهد به میانای برنامهسازی کاربردی AdServices Topics دسترسی داشته باشد."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"دسترسی به میاناهای برنامهسازی کاربردی AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"به برنامه اجازه میدهد به میاناهای برنامهسازی کاربردی AdServices Attribution دسترسی داشته باشد."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"دسترسی به میانای برنامهسازی کاربردی AdServices Custom Audiences"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"به برنامه اجازه میدهد به میانای برنامهسازی کاربردی AdServices Custom Audiences دسترسی داشته باشد."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"برای کنترل بزرگنمایی، دو بار ضربه بزنید"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"افزودن ابزارک انجام نشد."</string>
<string name="ime_action_go" msgid="5536744546326495436">"برو"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"در حالت تغییر به <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"در حال خروج از سیستم <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"مالک"</string>
+ <string name="guest_name" msgid="8502103277839834324">"مهمان"</string>
<string name="error_message_title" msgid="4082495589294631966">"خطا"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"سرپرست سیستم شما این تغییر را مجاز نمیداند"</string>
<string name="app_not_found" msgid="3429506115332341800">"برنامهای برای انجام این عملکرد موجود نیست"</string>
@@ -1852,8 +1856,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="5444908404021316250">"«بهینهسازی باتری» «طرح زمینه تیره» را روشن میکند و فعالیت پسزمینه، برخی از جلوههای بصری، ویژگیهایی خاص، و برخی از اتصالهای شبکه را محدود یا خاموش میکند."</string>
- <string name="battery_saver_description" msgid="8518809702138617167">"«بهینهسازی باتری» «طرح زمینه تیره» را روشن میکند و فعالیت پسزمینه، برخی از جلوههای بصری، ویژگیهایی خاص، و برخی از اتصالهای شبکه را محدود یا خاموش میکند."</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"«بهینهسازی باتری» «زمینه تیره» را روشن میکند و فعالیت پسزمینه، برخی از جلوههای بصری، ویژگیهایی خاص، و برخی از اتصالهای شبکه را محدود یا خاموش میکند."</string>
+ <string name="battery_saver_description" msgid="8518809702138617167">"«بهینهسازی باتری» «زمینه تیره» را روشن میکند و فعالیت پسزمینه، برخی از جلوههای بصری، ویژگیهایی خاص، و برخی از اتصالهای شبکه را محدود یا خاموش میکند."</string>
<string name="data_saver_description" msgid="4995164271550590517">"برای کمک به کاهش مصرف داده، «صرفهجویی داده» از ارسال و دریافت داده در پسزمینه در بعضی برنامهها جلوگیری میکند. برنامهای که درحالحاضر استفاده میکنید میتواند به دادهها دسترسی داشته باشد اما دفعات دسترسی آن محدود است. این میتواند به این معنی باشد که، برای مثال، تصاویر تازمانیکه روی آنها ضربه نزنید نشان داده نمیشوند."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"«صرفهجویی داده» روشن شود؟"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"روشن کردن"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"حذف نصب"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"درهرصورت باز شود"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"برنامه مضر شناسایی شد"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"درخواست دسترسی به گزارش سیستم"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"به <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> اجازه میدهید به همه گزارشهای دستگاه دسترسی داشته باشد؟"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"فقط این بار"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"مجاز نیست"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> گزارشهای سیستم را برای اشکالزدایی عملکردی درخواست میکند. این گزارشها ممکن است حاوی اطلاعاتی باشد که برنامهها و سرویسهای موجود در دستگاهتان نوشتهاند."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"گزارشهای دستگاه آنچه را در دستگاهتان رخ میدهد ثبت میکند. برنامهها میتوانند از این گزارشها برای پیدا کردن مشکلات و رفع آنها استفاده کنند.\n\nممکن است برخیاز گزارشها حاوی اطلاعات حساس باشند، بنابراین فقط به برنامههای مورداعتمادتان اجازه دسترسی به همه گزارشهای دستگاه را بدهید. \n\nاگر به این برنامه اجازه ندهید به همه گزارشهای دستگاه دسترسی داشته باشد، همچنان میتواند به گزارشهای خودش دسترسی داشته باشد، و سازنده دستگاهتان نیز ممکن است همچنان بتواند به برخیاز گزارشها یا اطلاعات در دستگاهتان دسترسی داشته باشد. بیشتر بدانید"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"دوباره نشان داده نشود"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> میخواهد تکههای <xliff:g id="APP_2">%2$s</xliff:g> را نشان دهد"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"ویرایش"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> برای مدتی طولانی در پسزمینه اجرا میشود. برای مرور، ضربه بزنید."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"بررسی برنامههای فعال"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"نمیتوان از این دستگاه به دوربین دسترسی پیدا کرد"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 0348505..36d748c 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Operaattori poisti tämän väliaikaisesti käytöstä SIM-kortilla <xliff:g id="SIMNUMBER">%d</xliff:g>."</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobiiliverkkoon ei saada yhteyttä"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Kokeile vaihtaa ensisijaista verkkoa. Vaihda se napauttamalla."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hätäpuhelut eivät ole käytettävissä"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Hätäpuhelujen soittaminen Wi-Fi-yhteyden kautta ei onnistu."</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Hätäpuhelut eivät ehkä ole käytettävissä"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ei tue hätäpuheluita Wi-Fi-yhteydellä. Katso lisätietoja napauttamalla."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Ilmoitukset"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Soitonsiirto"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Hätäpuhelujen takaisinsoittotila"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Antaa sovelluksen muokata tablet-laitteesi puhelulokia, kuten tietoja vastatuista ja soitetuista puheluista. Haitalliset sovellukset voivat poistaa puhelulokisi tai muokata sitä."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Antaa sovelluksen muokata Android TV ‑laitteen puhelulokia, kuten tietoja vastatuista ja soitetuista puheluista. Haitalliset sovellukset voivat tyhjentää puhelulokisi tai muokata sitä."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Antaa sovelluksen muokata puhelimesi puhelulokia, kuten tietoja vastatuista ja soitetuista puheluista. Haitalliset sovellukset voivat poistaa puhelulokisi tai muokata sitä."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"käyttää kehon antureita (kuten sykemittareita)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Pääsy kehon antureiden dataan, esim. sykkeeseen, ruumiinlämpöön ja veren happiprosenttiin."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"Pääsy kehon antureihin (kuten sykemittareihin) taustalla"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Pääsy kehon antureiden dataan (esim. sykkeeseen, ruumiinlämpöön ja veren happiprosenttiin) taustalla."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Pääsy kehoanturidataan, esim. sykkeeseen, kun käytössä"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Myöntää sovellukselle pääsyn kehoanturidataan, esim. sykkeeseen, lämpötilaan ja veren happipitoisuuteen, kun sovellusta käytetään."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pääsy kehoanturidataan, esim. sykkeeseen, kun käynnissä taustalla"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Myöntää sovellukselle pääsyn kehoanturidataan, esim. sykkeeseen, lämpötilaan ja veren happipitoisuuteen, kun sovellus on käynnissä taustalla."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Lue kalenterin tapahtumia ja tietoja"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Tämä sovellus voi lukea kaikkia tabletille tallennettuja kalenteritapahtumia sekä jakaa tai tallentaa kalenteritietoja."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Tämä sovellus voi lukea kaikkia Android TV ‑laitteeseen tallennettuja kalenteritapahtumia sekä jakaa tai tallentaa kalenteritietoja."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Sallii sovelluksen lukea jaetun tallennustilan audiotiedostoja."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"lukulupa jaetun tallennustilan videotiedostoihin"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Sallii sovelluksen lukea jaetun tallennustilan videotiedostoja."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"lukulupa jaetun tallennustilan kuvatiedostoihin"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Sallii sovelluksen lukea jaetun tallennustilan kuvatiedostoja."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"lue jaetun tallennustilan kuvatiedostoja"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Sallii sovelluksen lukea jaetun tallennustilan kuvatiedostoja."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"muokata tai poistaa jaetun tallennustilan sisältöä"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Antaa sovelluksen kirjoittaa jaetun tallennustilan sisällön."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"soita/vastaanota SIP-puheluja"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Poista lukitus tai soita hätäpuhelu painamalla Valikko-painiketta."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Poista lukitus painamalla Valikko-painiketta."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Poista lukitus piirtämällä kuvio"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Hätäpuhelu"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Hätäpuhelu"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Palaa puheluun"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Oikein!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Yritä uudelleen"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Ei koskaan"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Ei lupaa avata tätä sivua."</string>
<string name="text_copied" msgid="2531420577879738860">"Teksti kopioitu leikepöydälle."</string>
- <string name="copied" msgid="4675902854553014676">"Kopioitu"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> liitetty täältä: <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> liitti leikepöydältäsi"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> on liittänyt kopioimasi tekstin"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Sallii sovelluksen pyytää lupaa ohittaa tietyn sovelluksen akun optimoinnit."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"kaikkien pakettien näkeminen"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Antaa sovelluksen nähdä kaikki asennetut paketit."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"pääsy SupplementalApi-rajapintoihin"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Sovellus saa pääsyn SupplementalApi-rajapintoihin."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"pääsy AdServices Topics API ‑rajapintoihin"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Sovellus saa pääsyn AdServices Topics API ‑rajapintoihin."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"pääsy AdServices Attribution API ‑rajapintoihin"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Sovellus saa pääsyn AdServices Attribution API ‑rajapintoihin."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"pääsy AdServices Custom Audiences API ‑rajapintoihin"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Sovellus saa pääsyn AdServices Custom Audiences API ‑rajapintoihin."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Hallitse zoomausta napauttamalla kahdesti"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widgetin lisääminen epäonnistui."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Siirry"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Vaihdetaan käyttäjään <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> kirjautuu ulos…"</string>
<string name="owner_name" msgid="8713560351570795743">"Omistaja"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Vieras"</string>
<string name="error_message_title" msgid="4082495589294631966">"Virhe"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Järjestelmänvalvoja ei salli tätä muutosta."</string>
<string name="app_not_found" msgid="3429506115332341800">"Tätä toimintoa käsittelevää sovellusta ei löydy"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"POISTA"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"AVAA SILTI"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Haitallinen sovellus havaittu"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Järjestelmälokin pääsyoikeuspyyntö"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Saako <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> pääsyn kaikkiin laitelokeihin?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Vain tämän kerran"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Älä salli"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> pyytää järjestelmälokeja virheenkorjausta varten. Lokeissa voi olla tietoja, jotka ovat peräisin laitteellasi olevista sovelluksista ja palveluista."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Laitteen tapahtumat tallentuvat laitelokeihin. Niiden avulla sovellukset voivat löytää ja korjata ongelmia.\n\nJotkin lokit voivat sisältää arkaluontoista tietoa, joten salli pääsy kaikkiin laitelokeihin vain sovelluksille, joihin luotat. \n\nJos et salli tälle sovellukselle pääsyä kaikkiin laitelokeihin, sillä on kuitenkin pääsy sen omiin lokeihin ja laitteen valmistajalla voi olla pääsy joihinkin lokeihin tai tietoihin laitteella. Lue lisää"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Älä näytä uudelleen"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> haluaa näyttää osia sovelluksesta <xliff:g id="APP_2">%2$s</xliff:g>."</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Muokkaa"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> on ollut käynnissä taustalla pitkän aikaa. Tarkista napauttamalla."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tarkista aktiiviset sovellukset"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Ei pääsyä kameraan tältä laitteelta"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index b877da2..cb89659 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Temporairement désactivé par votre fournisseur de services pour la carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Impossible de joindre le réseau cellulaire"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Essayez de changer de réseau préféré. Touchez l\'écran pour changer."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Le service d\'appel d\'urgence n\'est pas accessible"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Impossible d\'effectuer des appels d\'urgence par Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Les appels d\'urgence peuvent ne pas être disponibles"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ne prend pas en charge les appels d\'urgence par Wi-Fi. Touchez pour en savoir plus."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertes"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Transfert d\'appel"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mode de rappel d\'urgence"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permet à l\'application de lire le journal d\'appels de votre tablette, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permet à l\'application de modifier le journal d\'appels de votre appareil Android TV, y compris les données sur les appels entrants et sortants. Des applications malveillantes pourraient utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permet à l\'application de lire le journal d\'appels de votre téléphone, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"accéder aux capteurs corporels (comme les moniteurs de fréquence cardiaque)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Accès aux données des capteurs corporels comme la fréquence cardiaque, la température, le pourcentage d\'oxygène dans le sang, etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"Accès capteurs corporels (comme moniteurs fréquence cardiaque) en arrière-plan"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Accès aux données des capteurs corporels comme la fréquence cardiaque, la température, le pourcentage d\'oxygène dans le sang, etc. en arrière-plan."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Accéder aux données des capteurs corporels si en utilisation (fréq. card., etc.)"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant l\'utilisation de l\'application."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données des capteurs corporels si en arrière-plan (fréq. card., etc.)"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant que l\'application s\'exécute en arrière-plan."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Lire les événements d\'agenda et leurs détails"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette application peut lire tous les événements d\'agenda stockés sur votre tablette et partager ou enregistrer les données de votre agenda."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Cette application peut lire tous les événements d\'agenda stockés sur votre appareil Android TV et partager ou enregistrer les données de votre agenda."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permet à l\'application de lire les fichiers audio de votre espace de stockage partagé."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"lire des fichiers vidéo à partir de l\'espace de stockage partagé"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permet à l\'application de lire les fichiers vidéo de votre espace de stockage partagé."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"lire des fichiers d\'image à partir de l\'espace de stockage partagé"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Permet à l\'application de lire les fichiers d\'image de votre espace de stockage partagé."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"lire des fichiers d\'image à partir de l\'espace de stockage partagé"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permet à l\'application de lire les fichiers d\'image de votre espace de stockage partagé."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modifier ou supprimer le contenu de votre espace de stockage partagé"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Autorise l\'application à écrire le contenu de votre espace de stockage partagé."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"faire et recevoir des appels SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Appuyez sur \"Menu\" pour débloquer le téléphone ou appeler un numéro d\'urgence."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Appuyez sur \"Menu\" pour déverrouiller l\'appareil."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Dessinez un schéma pour déverrouiller le téléphone"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Appel d\'urgence"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Urgence"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Retour à l\'appel"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"C\'est exact!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Réessayer"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Jamais"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Vous n\'êtes pas autorisé à ouvrir cette page."</string>
<string name="text_copied" msgid="2531420577879738860">"Le texte a été copié dans le presse-papiers."</string>
- <string name="copied" msgid="4675902854553014676">"Copié"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> collé à partir de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé du contenu de votre presse-papiers"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé du texte que vous avez copié"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permet à une application de demander la permission d\'ignorer les optimisations de la pile."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"envoyer une requête à propos de tous les paquets"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permet à une application de voir tous les paquets installés."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"accès à SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Autorise une application à accéder à SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"accès à l\'API Topics d\'AdServices"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Autorise une application à accéder à l\'API Topics d\'AdServices."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"accès aux API Attribution d\'AdServices"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Autorise une application à accéder aux API Attribution d\'AdServices."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"accès à l\'API Custom Audiences d\'AdServices"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Autorise une application à accéder à l\'API Custom Audiences d\'AdServices."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Appuyer deux fois pour régler le zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Impossible d\'ajouter le widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Aller"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Déconnexion de <xliff:g id="NAME">%1$s</xliff:g> en cours..."</string>
<string name="owner_name" msgid="8713560351570795743">"Propriétaire"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Invité"</string>
<string name="error_message_title" msgid="4082495589294631966">"Erreur"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Cette modification n\'est pas autorisée par votre administrateur"</string>
<string name="app_not_found" msgid="3429506115332341800">"Aucune application trouvée pour gérer cette action."</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DÉSINSTALLER"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OUVRIR QUAND MÊME"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Une application nuisible a été détectée"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Demande d\'accès aux journaux système"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Autoriser <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> à accéder à l\'ensemble des journaux de l\'appareil?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Seulement cette fois"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ne pas autoriser"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> demande l\'accès aux journaux système aux fins de débogage fonctionnel. Ces journaux peuvent contenir des informations écrites par des applications et des services sur votre appareil."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Les journaux de l\'appareil enregistrent ce qui se passe sur celui-ci. Les applications peuvent utiliser ces journaux pour trouver et résoudre des problèmes.\n\nCertains journaux peuvent contenir des renseignements confidentiels. N\'autorisez donc que les applications auxquelles vous faites confiance puisque celles-ci pourront accéder à l\'ensemble des journaux de l\'appareil. \n\nMême si vous n\'autorisez pas cette application à accéder à l\'ensemble des journaux de l\'appareil, elle aura toujours accès à ses propres journaux, et le fabricant de votre appareil sera toujours en mesure d\'accéder à certains journaux ou renseignements sur votre appareil. En savoir plus"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne plus afficher"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> souhaite afficher <xliff:g id="APP_2">%2$s</xliff:g> tranches"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Modifier"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan depuis longtemps. Touchez pour examiner."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applications actives"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Impossible d\'accéder à l\'appareil photo à partir de cet appareil"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f73398e..eb7cc67 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Service temporairement désactivé par votre opérateur concernant la carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Impossible d\'accéder au réseau mobile"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Essayez de changer le réseau préféré. Appuyez pour le modifier."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Appels d\'urgence non disponibles"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Impossible de passer des appels d\'urgence via le Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Vous ne pourrez peut-être pas passer d\'appels d\'urgence"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ne prend pas en charge les appels d\'urgence via le Wi-Fi. Appuyez ici pour en savoir plus."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertes"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Transfert d\'appel"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mode de rappel d\'urgence"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permet à l\'application de lire le journal d\'appels de votre tablette, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permet à l\'application de lire le journal d\'appels de votre appareil Android TV, y compris les données sur les appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permet à l\'application de lire le journal d\'appels de votre téléphone, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"accéder capteurs corp. (ex : cardiofréquencemètres)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Accès aux données des capteurs corporels mesurant la fréquence cardiaque, la température, le pourcentage d\'oxygène dans le sang, etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"accéder en arrière-plan aux capteurs corporels (par ex., cardiofréquencemètres)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Accès en arrière-plan aux données des capteurs corporels mesurant la fréquence cardiaque, la température, le pourcentage d\'oxygène dans le sang, etc."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Accéder aux données de capteurs corporels (comme fréquence cardiaque) pendant utilisation"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'appli d\'accéder aux données des capteurs corporels (fréquence cardiaque, température, taux d\'oxygène dans le sang, etc.) quand l\'appli est en cours d\'utilisation."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données de capteurs corporels (comme fréquence cardiaque) quand en arrière-plan"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'appli d\'accéder aux données des capteurs corporels (fréquence cardiaque, température, taux d\'oxygène dans le sang, etc.) quand l\'appli est en arrière-plan."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Lire les événements d\'agenda et les détails associés"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette application peut lire tous les événements d\'agenda enregistrés sur votre tablette et partager ou enregistrer vos données d\'agenda."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Cette application peut lire tous les événements de l\'agenda enregistrés sur votre appareil Android TV, et partager ou enregistrer les données de votre agenda."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permettre à l\'application de lire les fichiers audio de votre espace de stockage partagé."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"lire les fichiers vidéo de l\'espace de stockage partagé"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permettre à l\'application de lire les fichiers vidéo de votre espace de stockage partagé."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"lire les fichiers image de l\'espace de stockage partagé"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Permettre à l\'application de lire les fichiers image de votre espace de stockage partagé."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"lire les fichiers image de l\'espace de stockage partagé"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permettre à l\'application de lire les fichiers image de votre espace de stockage partagé."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modifier/supprimer contenu mémoire stockage partagée"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Permet de modifier le contenu mémoire de stockage partagée."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"effectuer/recevoir des appels SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Appuyez sur \"Menu\" pour déverrouiller le téléphone ou appeler un numéro d\'urgence"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Appuyez sur \"Menu\" pour déverrouiller le téléphone."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Dessinez un schéma pour déverrouiller le téléphone"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Appel d\'urgence"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Urgences"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Retour à l\'appel"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Combinaison correcte !"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Veuillez réessayer."</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Jamais"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Vous n\'êtes pas autorisé à ouvrir cette page."</string>
<string name="text_copied" msgid="2531420577879738860">"Le texte a été copié dans le presse-papier."</string>
- <string name="copied" msgid="4675902854553014676">"Copie effectuée"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> collé depuis <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé des données depuis le presse-papiers"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé du texte que vous avez copié"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Autorise une application à demander l\'autorisation d\'ignorer les optimisations de batterie pour cette application."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"interroger tous les packages"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Autorise une appli à voir tous les packages installés."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"accéder à SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Autorise une application à accéder à SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"accéder à l\'API AdServices Topics"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Permet à une appli d\'accéder à l\'API AdServices Topics."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"accéder aux API AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Permet à une appli d\'accéder aux API AdServices Attribution."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"accéder à l\'API AdServices Custom Audiences"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Permet à une appli d\'accéder à l\'API AdServices Custom Audiences."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Appuyer deux fois pour régler le zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Impossible d\'ajouter le widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"OK"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Déconnexion de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Propriétaire"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Invité"</string>
<string name="error_message_title" msgid="4082495589294631966">"Erreur"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Votre administrateur n\'autorise pas cette modification"</string>
<string name="app_not_found" msgid="3429506115332341800">"Aucune application trouvée pour gérer cette action."</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DÉSINSTALLER"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OUVRIR QUAND MÊME"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Application dangereuse détectée"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Demande d\'accès aux journaux système"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Autoriser <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> à accéder à tous les journaux de l\'appareil ?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Cette fois seulement"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ne pas autoriser"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"Journaux système des demandes <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> pour le débogage fonctionnel. Ces journaux peuvent contenir des informations écrites par les applis et services de votre appareil."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Les journaux enregistrent ce qui se passe sur votre appareil. Les applis peuvent les utiliser pour rechercher et résoudre les problèmes.\n\nCertains journaux pouvant contenir des infos sensibles, autorisez uniquement les applis de confiance à accéder à tous les journaux de l\'appareil. \n\nSi vous refusez à cette appli l\'accès à tous les journaux de l\'appareil, elle a quand même accès aux siens, et le fabricant de l\'appareil peut accéder à certains journaux ou certaines infos sur votre appareil. En savoir plus"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne plus afficher"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> souhaite afficher des éléments de <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Modifier"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan depuis longtemps. Appuyez ici pour en savoir plus."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applis actives"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Impossible d\'accéder à l\'appareil photo depuis cet appareil"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index dfc6e69..d50699a 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"O teu operador desactivou este servizo temporalmente para a SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Non se puido conectar coa rede de telefonía móbil"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Proba a cambiar a rede preferida. Toca para cambiar."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"As chamadas de emerxencia non están dispoñibles"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Non se poden realizar chamadas de emerxencia por wifi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"É posible que as chamadas de emerxencia non estean dispoñibles"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> non permite realizar chamadas de emerxencia por wifi. Toca para obter información."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Desvío de chamadas"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modo de devolución de chamadas de emerxencia"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permite á aplicación modificar o rexistro de chamadas da tableta, incluídos os datos acerca de chamadas entrantes e saíntes. É posible que aplicacións maliciosas utilicen esta acción para borrar ou modificar o teu rexistro de chamadas."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permite que a aplicación modifique o rexistro de chamadas do dispositivo Android TV, incluídos os datos acerca de chamadas entrantes e saíntes. As aplicacións maliciosas poden utilizar este permiso para borrar ou modificar o rexistro de chamadas."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permite á aplicación modificar o rexistro de chamadas do teléfono, incluídos os datos acerca de chamadas entrantes e saíntes. É posible que aplicacións maliciosas utilicen esta acción para borrar ou modificar o teu rexistro de chamadas."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"acceder a sensores corporais (como monitores de ritmo cardíaco)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Acceso a datos de sensores corporais, como o ritmo cardíaco, a temperatura, a porcentaxe de osíxeno en sangue etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"acceso en segundo plano a sensores corporais (como monitores de ritmo cardíaco)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Acceso en segundo plano a datos de sensores corporais, como o ritmo cardíaco, a temperatura, a porcentaxe de osíxeno en sangue etc."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Acceso aos datos dos sensores corporais, como o ritmo cardíaco, mentres se use"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que a aplicación acceda aos datos dos sensores corporais (por exemplo, o ritmo cardíaco, a temperatura ou a porcentaxe de osíxeno en sangue) mentres se estea utilizando."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acceso en segundo plano aos datos dos sensores corporais, como o ritmo cardíaco"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que a aplicación acceda aos datos dos sensores corporais (por exemplo, a frecuencia cardíaca, a temperatura ou a porcentaxe de osíxeno en sangue) mentres se estea executando en segundo plano."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Ler os detalles e os eventos do calendario"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta aplicación pode ler todos os eventos do calendario almacenados na túa tableta e compartir ou gardar os datos do calendario."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta aplicación pode ler todos os eventos do calendario almacenados no dispositivo Android TV e compartir ou gardar os datos do calendario."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permite que a aplicación acceda a ficheiros de audio do almacenamento compartido."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"acceder a ficheiros de vídeo do almacenamento compartido"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permite que a aplicación acceda a ficheiros de vídeo do almacenamento compartido."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"acceder a ficheiros de imaxe do almacenamento compartido"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Permite que a aplicación acceda a ficheiros de imaxe do almacenamento compartido."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"acceder a ficheiros de imaxe do almacenamento compartido"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permite que a aplicación acceda a ficheiros de imaxe do almacenamento compartido."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modificar ou eliminar o almacenamento compartido"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Permite á aplicación escribir no almacenamento compartido."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"facer/recibir chamadas SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Preme Menú para desbloquear ou realizar unha chamada de emerxencia."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Preme Menú para desbloquear."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Crea o padrón de desbloqueo"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Chamada de emerxencia"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emerxencia"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Volver á chamada"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correcto!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Téntao de novo"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nunca"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Non tes permiso para abrir esta páxina."</string>
<string name="text_copied" msgid="2531420577879738860">"O texto copiouse no portapapeis."</string>
- <string name="copied" msgid="4675902854553014676">"Copiuse"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegou contido procedente de <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegou contido do portapapeis"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> pegou texto que copiaches"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Fai que unha aplicación poida solicitar permiso para ignorar as optimizacións da batería."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"consultar todos os paquetes"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permite que unha aplicación consulte todos os paquetes instalados."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"acceso a SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Permite que unha aplicación acceda a SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"acceder a AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Permite que unha aplicación acceda a AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"acceder ás AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Permite que unha aplicación acceda ás AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"acceder a AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Permite que unha aplicación acceda a AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Toca dúas veces para controlar o zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Non se puido engadir o widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Pechando sesión de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Propietario"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Convidado"</string>
<string name="error_message_title" msgid="4082495589294631966">"Erro"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"O administrador non admite este cambio"</string>
<string name="app_not_found" msgid="3429506115332341800">"Non se atopou ningunha aplicación para procesar esta acción"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DESINSTALAR"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR IGUALMENTE"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Detectouse unha aplicación daniña"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Solicitude acceso a rexistros do sistema"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Queres permitir que a aplicación <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acceda a todos os rexistros do dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Só esta vez"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Non permitir"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> solicita rexistros do sistema para realizar unha depuración funcional. Estes rexistros poderían conter información que escribiron as aplicacións e os servizos do teu dispositivo."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Os rexistros do dispositivo dan conta do que ocorre neste. As aplicacións poden usalos para buscar problemas e solucionalos.\n\nAlgúns poden conter información confidencial, polo que che recomendamos que só permitas que accedan a todos os rexistros do dispositivo as aplicacións nas que confíes. \n\nEsta aplicación pode acceder aos seus propios rexistros aínda que non lle permitas acceder a todos, e é posible que o fabricante do teu dispositivo teña acceso a algúns rexistros ou á información do teu dispositivo. Máis información"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Non amosar outra vez"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quere mostrar fragmentos de aplicación de <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> leva moito tempo executándose en segundo plano. Toca para revisalo."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Comprobar aplicacións activas"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Non se pode acceder á cámara desde este dispositivo"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 3cd24d2..4186f9b 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"તમારા કૅરિઅર દ્વારા સિમ <xliff:g id="SIMNUMBER">%d</xliff:g> માટે હંગામી રૂપે બંધ કરેલ છે"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"મોબાઇલ નેટવર્ક સુધી પહોંચી શકાતું નથી"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"પસંદગીનું નેટવર્ક બદલવાનો પ્રયાસ કરો. બદલવા માટે ટૅપ કરો."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"કટોકટીની કૉલિંગ સેવા અનુપલબ્ધ"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"વાઇ-ફાઇ પરથી કટોકટીના કૉલ કરી શકાતા નથી"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"ઇમર્જન્સી કૉલ કદાચ ઉપલબ્ધ ન હોય"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> વાઇ-ફાઇ પર ઇમર્જન્સી કૉલને સપોર્ટ કરતા નથી. વિગતો માટે ટૅપ કરો."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"અલર્ટ"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"કૉલ ફૉર્વર્ડિંગ"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"કટોકટી કૉલબૅક મોડ"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"એપ્લિકેશનને ઇનકમિંગ અને આઉટગોઇંગ કૉલ્સ વિશેનાં ડેટા સહિત, તમારા ટેબ્લેટના કૉલ લૉગને સંશોધિત કરવાની મંજૂરી આપે છે. દુર્ભાવનાપૂર્ણ ઍપ્લિકેશનો આનો ઉપયોગ તમારા કૉલ લૉગને કાઢી નાખવા અથવા સંશોધિત માટે કરી શકે છે."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ઍપને ઇનકમિંગ અને આઉટગોઇંગ કૉલ વિશેના ડેટા સહિત, તમારા Android TV ડિવાઇસના કૉલ લૉગને સંશોધિત કરવાની મંજૂરી આપે છે. દુર્ભાવનાપૂર્ણ ઍપ આનો ઉપયોગ તમારા કૉલ લૉગને કાઢી નાખવા અથવા સંશોધિત કરવા માટે કરી શકે છે."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"એપ્લિકેશનને ઇનકમિંગ અને આઉટગોઇંગ કૉલ્સ વિશેનાં ડેટા સહિત, તમારા ફોનના કૉલ લૉગને સંશોધિત કરવાની મંજૂરી આપે છે. દુર્ભાવનાપૂર્ણ ઍપ્લિકેશનો આનો ઉપયોગ તમારા કૉલ લૉગને કાઢી નાખવા અથવા સંશોધિત માટે કરી શકે છે."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"બૉડીસેન્સર્સ ઍક્સેસ(જેમકે હ્રદય ગતી મૉનિટર)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"બૉડી સેન્સરના ડેટાનો ઍક્સેસ જેમ કે હૃદયના ધબકારા, તાપમાન, લોહીમાં ઑક્સિજનની ટકાવારી વગેરે."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"બૉડી સેન્સર (જેમ કે હૃદયના ધબકારાના નિરીક્ષણો) બૅકગ્રાઉન્ડમાં ઍક્સેસ કરો"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"બૅકગ્રાઉન્ડમાં હોય ત્યારે બૉડી સેન્સરના ડેટાનો ઍક્સેસ જેમ કે હૃદયના ધબકારા, તાપમાન, લોહીમાં ઑક્સિજનની ટકાવારી વગેરે."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ઍપ ઉપયોગમાં હોય, ત્યારે હૃદયના ધબકારા જેવા બૉડી સેન્સર ડેટાનો ઍક્સેસ કરો"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ઍપનો ઉપયોગમાં હોય, ત્યારે ઍપને હૃદયના ધબકારા, તાપમાન અને લોહીમાં ઑક્સિજનની ટકાવારી જેવા બૉડી સેન્સર ડેટાનો ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ઍપ બૅકગ્રાઉન્ડમાં હોય, ત્યારે હૃદયના ધબકારા જેવા બૉડી સેન્સર ડેટાનો ઍક્સેસ કરો"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ઍપ બૅકગ્રાઉન્ડમાં હોય, ત્યારે ઍપને હૃદયના ધબકારા, તાપમાન અને લોહીમાં ઑક્સિજનની ટકાવારી જેવા બૉડી સેન્સર ડેટાનો ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"કૅલેન્ડર ઇવેન્ટ્સ અને વિગતો વાંચો"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"આ ઍપ્લિકેશન, તમારા ટેબ્લેટ પર સંગ્રહિત તમામ કૅલેન્ડર ઇવેન્ટ્સને વાંચી શકે છે અને તમારા કૅલેન્ડર ડેટાને શેર કરી અથવા સાચવી શકે છે."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"આ ઍપ, તમારા Android TV ડિવાઇસ પર સંગ્રહિત બધા કૅલેન્ડર ઇવેન્ટને વાંચી શકે છે અને તમારા કૅલેન્ડર ડેટાને શેર કરી અથવા સાચવી શકે છે."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"ઍપને તમારા શેર કરાયેલા સ્ટોરેજમાંથી ઑડિયો ફાઇલો વાંચવાની મંજૂરી આપે છે."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"શેર કરાયેલા સ્ટોરેજમાંથી વીડિયો ફાઇલો વાંચવા માટે"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"ઍપને તમારા શેર કરાયેલા સ્ટોરેજમાંથી વીડિયો ફાઇલો વાંચવાની મંજૂરી આપે છે."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"શેર કરાયેલા સ્ટોરેજમાંથી છબી ફાઇલો વાંચવા માટે"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"ઍપને તમારા શેર કરાયેલા સ્ટોરેજમાંથી છબી ફાઇલો વાંચવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"શેર કરાયેલા સ્ટોરેજમાંથી છબી ફાઇલો વાંચવા માટે"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"ઍપને તમારા શેર કરાયેલા સ્ટોરેજમાંથી છબી ફાઇલો વાંચવાની મંજૂરી આપે છે."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"શેર કરેલા સ્ટોરેજ કન્ટેન્ટમાં ફેરફાર કરો/ડિલીટ કરો"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"શેર કરેલા સ્ટોરેજ કન્ટેન્ટમાં લખવાની મંજૂરી આપે છે."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP કૉલ્સ કરો/પ્રાપ્ત કરો"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"અનલૉક કરવા માટે અથવા કટોકટીનો કૉલ કરવા માટે મેનૂ દબાવો."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"અનલૉક કરવા માટે મેનૂ દબાવો."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"અનલૉક કરવા માટે પૅટર્ન દોરો."</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"ઇમર્જન્સી કૉલ"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ઇમર્જન્સી"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"કૉલ પર પાછા ફરો"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"સાચું!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"ફરી પ્રયાસ કરો"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"ક્યારેય નહીં"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"તમને આ પૃષ્ઠને ખોલવાની પરવાનગી નથી."</string>
<string name="text_copied" msgid="2531420577879738860">"ક્લિપબોર્ડ પર ટેક્સ્ટ કૉપિ કરી."</string>
- <string name="copied" msgid="4675902854553014676">"કૉપિ કરેલ"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>માંથી કૉપિ કરાયેલો ડેટા <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>માં પેસ્ટ કરવામાં આવ્યો"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> દ્વારા તમારા ક્લિપબોર્ડ પરથી પેસ્ટ કરવામાં આવ્યું"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> દ્વારા તમે કૉપિ કરેલી ટેક્સ્ટ પેસ્ટ કરાઈ"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ઍપ્લિકેશનને તે ઍપ્લિકેશન માટે બૅટરી ઓપ્ટિમાઇઝેશન્સને અવગણવાની પરવાનગી આપવા માટે પૂછવાની મંજૂરી આપે છે."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"બધા પૅકેજ જુઓ"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"કોઈ ઍપને ઇન્સ્ટૉલ કરેલા બધા પૅકેજ જોવાની મંજૂરી આપે છે."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApisને ઍક્સેસ કરો"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"કોઈ ઍપ્લિકેશનને SupplementalApis ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API ઍક્સેસ કરો"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"ઍપ્લિકેશનને AdServices Topics API ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution APIs ઍક્સેસ કરો"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"ઍપ્લિકેશનને AdServices Attribution APIs ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API ઍક્સેસ કરો"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"ઍપ્લિકેશનને AdServices Custom Audiences API ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ઝૂમ નિયંત્રણ માટે બેવાર ટૅપ કરો"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"વિજેટ ઉમેરી શકાયું નથી."</string>
<string name="ime_action_go" msgid="5536744546326495436">"જાઓ"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> પર સ્વિચ કરી રહ્યાં છે…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> લોગ આઉટ થઈ રહ્યાં છે…"</string>
<string name="owner_name" msgid="8713560351570795743">"માલિક"</string>
+ <string name="guest_name" msgid="8502103277839834324">"અતિથિ"</string>
<string name="error_message_title" msgid="4082495589294631966">"ભૂલ"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"તમારા વ્યવસ્થાપકે આ ફેરફારની મંજૂરી આપી નથી"</string>
<string name="app_not_found" msgid="3429506115332341800">"આ ક્રિયાને હેન્ડલ કરવા માટે કોઈ ઍપ્લિકેશન મળી નહીં"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"અનઇન્સ્ટૉલ કરો"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"કોઈપણ રીતે ખોલો"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"નુકસાનકારક ઍપ મળી આવી છે"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"સિસ્ટમ લૉગ ઍક્સેસ કરવાની વિનંતી"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>ને ડિવાઇસનો બધો લૉગ ઍક્સેસ કરવાની મંજૂરી આપવી છે?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"માત્ર આ વખતે"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"મંજૂરી આપશો નહીં"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"ફંક્શનલ ડિબગીંગ માટે, <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> સિસ્ટમ લૉગની વિનંતી કરે છે. તમારા ડિવાઇસ પરની ઍપ અને સેવાઓએ લખેલી માહિતી આ લૉગમાં શામેલ હોઈ શકે છે."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"તમારા ડિવાઇસ પર થતી કામગીરીને ડિવાઇસ લૉગ રેકોર્ડ કરે છે. ઍપ આ લૉગનો ઉપયોગ સમસ્યાઓ શોધી તેનું નિરાકરણ કરવા માટે કરી શકે છે.\n\nઅમુક લૉગમાં સંવેદનશીલ માહિતી હોઈ શકે, આથી ડિવાઇસનો બધો લૉગ ઍક્સેસ કરવાની મંજૂરી માત્ર તમારી વિશ્વાસપાત્ર ઍપને જ આપો. \n\nતમે આ ઍપને ડિવાઇસનો બધો લૉગ ઍક્સેસ કરવાની મંજૂરી નહીં આપી હોય, તો પણ તે તેના પોતાના લૉગ ઍક્સેસ કરી શકે છે અને તમારા ડિવાઇસના ઉત્પાદક હજુ પણ તમારા ડિવાઇસ પર અમુક લૉગ અથવા માહિતી ઍક્સેસ કરી શકે તેમ બની શકે છે. વધુ જાણો"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"ફરીથી બતાવશો નહીં"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>એ <xliff:g id="APP_2">%2$s</xliff:g> સ્લાઇસ બતાવવા માગે છે"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"ફેરફાર કરો"</string>
@@ -2261,8 +2265,10 @@
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>થી <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>માં સંદેશનો અનુવાદ કરવામાં આવ્યો."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"બૅકગ્રાઉન્ડ પ્રવૃત્તિ"</string>
<string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"બૅકગ્રાઉન્ડ પ્રવૃત્તિ"</string>
- <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> બૅકગ્રાઉન્ડમાં ચાલી રહી છે અને અતિશય બૅટરી વાપરી રહી છે. રિવ્યૂ કરવા માટે ટૅપ કરો."</string>
+ <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ઍપ બૅકગ્રાઉન્ડમાં ચાલી રહી છે અને અતિશય બૅટરી વાપરી રહી છે. રિવ્યૂ કરવા માટે ટૅપ કરો."</string>
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> લાંબા સમયથી બૅકગ્રાઉન્ડમાં ચાલી રહી છે. રિવ્યૂ કરવા માટે ટૅપ કરો."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"સક્રિય ઍપ ચેક કરો"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"આ ડિવાઇસમાંથી કૅમેરા ઍક્સેસ કરી શકાતો નથી"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 00b29d3..8f3337f 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"सिम <xliff:g id="SIMNUMBER">%d</xliff:g> पर आपकी मोबाइल और इंटरनेट सेवा देने वाली कंपनी ने कुछ समय के लिए सेवा बंद कर दी है"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"मोबाइल नेटवर्क से कनेक्ट नहीं किया जा सका"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"पसंदीदा नेटवर्क बदलकर देखें. बदलने के लिए टैप करें."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"आपातकालीन कॉल करने की सुविधा उपलब्ध नहीं है"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"वाई-फ़ाई के ज़रिए आपातकालीन कॉल नहीं किया जा सकता"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"शायद आपातकालीन कॉल करने की सुविधा उपलब्ध न हो"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> पर, वाई-फ़ाई की मदद से आपातकालीन कॉल करने की सुविधा नहीं दी जाती. जानकारी पाने के लिए टैप करें."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"सूचनाएं"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"कॉल को दूसरे नंबर पर भेजना"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"आपातकालीन कॉलबैक मोड"</string>
@@ -338,7 +338,7 @@
<string name="capability_title_canPerformGestures" msgid="9106545062106728987">"जेस्चर करें"</string>
<string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"इस सेवा के ज़रिए टैप, स्वाइप, पिंच और बाकी जेस्चर किए जा सकते हैं."</string>
<string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"फ़िंगरप्रिंट जेस्चर"</string>
- <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"डिवाइस के फ़िंगरप्रिंट सेंसर पर किए गए हाथ के जेस्चर (स्पर्श) कैप्चर किए जा सकते हैं."</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"डिवाइस के फ़िंगरप्रिंट सेंसर पर किए गए हाथ के जेस्चर कैप्चर किए जा सकते हैं."</string>
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"स्क्रीनशॉट लें"</string>
<string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"डिसप्ले का स्क्रीनशॉट लिया जा सकता है."</string>
<string name="permlab_statusBar" msgid="8798267849526214017">"स्टेटस बार को अक्षम करें या बदलें"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ऐप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके टैबलेट के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले ऐप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"यह ऐप्लिकेशन को आपके Android TV डिवाइस के कॉल लॉग में बदलाव करने की अनुमति देता है. इसमें किसी को की गई (आउटगोइंग) कॉल और किसी से मिली (इनकमिंग) कॉल शामिल हैं. हालांकि, नुकसान पहुंचाने वाले ऐप्लिकेशन इसका इस्तेमाल करके कॉल लॉग को मिटा सकते हैं या बदल सकते हैं."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ऐप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके फ़ोन के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले ऐप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"शरीर के लिए बने सेंसर (जैसे हृदय गति मॉनीटर) को ऐक्सेस करें"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"बॉडी सेंसर से मिले डेटा का ऐक्सेस, जैसे कि धड़कन की दर, तापमान, खून में मौजूद ऑक्सीजन का प्रतिशत वगैरह."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"बैकग्राउंड में काम करने वाले बॉडी सेंसर (जैसे, धड़कन की दर मापने वाले मॉनिटर) से मिले डेटा का ऐक्सेस"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"बैकग्राउंड में काम करने वाले बॉडी सेंसर से मिले डेटा का ऐक्सेस, जैसे कि धड़कन की दर, तापमान, खून में मौजूद ऑक्सीजन का प्रतिशत वगैरह."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ऐप इस्तेमाल करने के दौरान, उसे धड़कन की दर जैसे बॉडी सेंसर डेटा का ऐक्सेस दें"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"इससे ऐप्लिकेशन को इस्तेमाल करने के दौरान, उसे बॉडी सेंसर के डेटा को ऐक्सेस करने की अनुमति मिलती है. इसमें धड़कन की दर, शरीर का तापमान, और खून में ऑक्सीजन का प्रतिशत जैसी जानकारी शामिल होती है."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"बैकग्राउंड में चलने के दौरान, धड़कन की दर जैसे बॉडी सेंसर डेटा का ऐक्सेस दें"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"इससे ऐप्लिकेशन के बैकग्राउंड में चलने के दौरान, उसे बॉडी सेंसर के डेटा को ऐक्सेस करने की अनुमति मिलती है. इसमें धड़कन की दर, शरीर का तापमान, और खून में ऑक्सीजन का प्रतिशत जैसी जानकारी शामिल होती है."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"कैलेंडर इवेंट और विवरण पढ़ें"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"यह ऐप्लिकेशन आपके टैबलेट पर संग्रहित सभी कैलेंडर इवेंट पढ़ सकता है और आपका कैलेंडर डेटा शेयर कर सकता है या सहेज सकता है."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"यह ऐप्लिकेशन आपके टीवी पर सेव किए गए सभी कैलेंडर इवेंट को पढ़ सकता है. इसके अलावा यह आपके कैलेंडर का डेटा शेयर कर सकता है या सेव कर सकता है."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"अपने डिवाइस के शेयर किए गए स्टोरेज से, ऐप्लिकेशन को ऑडियो फ़ाइलें पढ़ने की अनुमति दें."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"डिवाइस के शेयर किए गए स्टोरेज से, वीडियो फ़ाइलें पढ़ने की अनुमति"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"अपने डिवाइस के शेयर किए गए स्टोरेज से, ऐप्लिकेशन को वीडियो फ़ाइलें पढ़ने की अनुमति दें."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"डिवाइस के शेयर किए गए स्टोरेज से, इमेज फ़ाइलें पढ़ने की अनुमति"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"अपने डिवाइस के शेयर किए गए स्टोरेज से, ऐप्लिकेशन को इमेज फ़ाइलें पढ़ने की अनुमति दें."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"डिवाइस के शेयर किए गए स्टोरेज से, इमेज फ़ाइलें देखने की अनुमति"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"अपने डिवाइस के शेयर किए गए स्टोरेज से, ऐप्लिकेशन को इमेज फ़ाइलें देखने की अनुमति दें."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"आपकी शेयर की गई मेमोरी की सामग्री में बदलाव करना या उसे मिटाना"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"ऐप्लिकेशन को आपकी शेयर की गई मेमोरी की सामग्री लिखने देती है."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP कॉल करें/पाएं"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"लॉक खोलने के लिए मेन्यू दबाएं या आपातलकालीन कॉल करें."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"लॉक खोलने के लिए मेन्यू दबाएं."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"अनलॉक करने के लिए आकार आरेखित करें"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"आपातकालीन कॉल"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"आपातकाल"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"कॉल पर वापस लौटें"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"सही!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"फिर से कोशिश करें"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"कभी नहीं"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"आपके पास इस पेज को खोलने की अनुमति नहीं है."</string>
<string name="text_copied" msgid="2531420577879738860">"लेख को क्लिपबोर्ड पर कॉपी किया गया."</string>
- <string name="copied" msgid="4675902854553014676">"कॉपी किया गया"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> से कॉपी किए गए डेटा को <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> में चिपकाया गया है"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ने क्लिपबोर्ड में मौजूद डेटा कॉपी करके चिपकाया"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ने आपका कॉपी किया हुआ टेक्स्ट चिपका दिया है"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"किसी ऐप्लिकेशन को उस ऐप्लिकेशन के लिए बैटरी ऑप्टिमाइज़ेशन पर ध्यान ना देने की अनुमति के लिए पूछने देता है."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"डिवाइस पर इंस्टॉल किए गए सभी पैकेज देखें"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"यह किसी ऐप्लिकेशन को, डिवाइस पर इंस्टॉल किए गए सभी पैकेज देखने की अनुमति देता है."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis का ऐक्सेस पाना"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"इससे, किसी ऐप्लिकेशन को SupplementalApis को ऐक्सेस करने की अनुमति मिलती है."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices टॉपिक एपीआई को ऐक्सेस करें"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"इससे किसी ऐप्लिकेशन को AdServices टॉपिक एपीआई को ऐक्सेस करने की अनुमति मिलती है."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices एट्रिब्यूशन एपीआई को ऐक्सेस करें"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"इससे किसी ऐप्लिकेशन को AdServices एट्रिब्यूशन एपीआई को ऐक्सेस करने की अनुमति मिलती है."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices कस्टम ऑडियंस एपीआई को ऐक्सेस करें"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"इससे किसी ऐप्लिकेशन को AdServices कस्टम ऑडियंस एपीआई को ऐक्सेस करने की अनुमति मिलती है."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ज़ूम नियंत्रण के लिए दो बार टैप करें"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"विजेट नहीं जोड़ा जा सका."</string>
<string name="ime_action_go" msgid="5536744546326495436">"जाएं"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> द्वारा प्रस्थान किया जा रहा है…"</string>
<string name="owner_name" msgid="8713560351570795743">"मालिक"</string>
+ <string name="guest_name" msgid="8502103277839834324">"मेहमान"</string>
<string name="error_message_title" msgid="4082495589294631966">"गड़बड़ी"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"आपका व्यवस्थापक इस बदलाव की अनुमति नहीं देता"</string>
<string name="app_not_found" msgid="3429506115332341800">"इस कार्यवाही को प्रबंधित करने के लिए कोई ऐप्स नहीं मिला"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"अनइंस्टॉल करें"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"फिर भी खोलें"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"नुकसान पहुंचाने वाले ऐप का पता चला"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"सिस्टम लॉग को ऐक्सेस करने का अनुरोध"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"क्या <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> को डिवाइस लॉग का ऐक्सेस देना है?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"सिर्फ़ इस बार"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"अनुमति न दें"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"फ़ंक्शनल डीबगिंग के लिए, <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> का सिस्टम लॉग के लिए अनुरोध. इन लॉग में आपके डिवाइस पर मौजूद ऐप्लिकेशन और सेवाओं से मिली जानकारी शामिल हो सकती है."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"डिवाइस लॉग में आपके डिवाइस पर की गई कार्रवाइयां रिकॉर्ड होती हैं. ऐप्लिकेशन, इन लॉग का इस्तेमाल गड़बड़ियां ढूंढने और उन्हें सही करने के लिए करता है.\n\nकुछ लॉग में संवेदनशील जानकारी हो सकती है. इसलिए, सिर्फ़ भरोसेमंद ऐप्लिकेशन को डिवाइस लॉग का ऐक्सेस दें. \n\nअगर इस ऐप्लिकेशन को डिवाइस लॉग का ऐक्सेस नहीं दिया जाता है, तब भी यह अपने डिवाइस लॉग को ऐक्सेस कर सकता है. इसके अलावा, डिवाइस को बनाने वाली कंपनी अब भी डिवाइस के कुछ लॉग और जानकारी को ऐक्सेस कर सकती है. ज़्यादा जानें"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"फिर से न दिखाएं"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>, <xliff:g id="APP_2">%2$s</xliff:g> के हिस्से (स्लाइस) दिखाना चाहता है"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"बदलाव करें"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> बैकग्राउंड में बहुत देर से चल रहा है. देखने के लिए टैप करें."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"चालू ऐप्लिकेशन देखें"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"इस डिवाइस से कैमरे का इस्तेमाल नहीं किया जा सकता"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index ccbcaaf..52f7ea2 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -86,8 +86,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Uslugu je privremeno isključio mobilni operater za SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilna mreža nije dostupna"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Pokušajte promijeniti preferiranu mrežu. Dodirnite da biste je promijenili."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi nisu dostupni"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Nije moguće upućivati hitne pozive putem Wi‑Fi-ja"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Hitni pozivi možda nisu dostupni"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ne podržava hitne pozive putem Wi-Fija. Dodirnite da biste vidjeli pojedinosti."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozorenja"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmjeravanje poziva"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Način hitnog povratnog poziva"</string>
@@ -426,10 +426,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Aplikaciji omogućuje izmjenu dnevnika poziva vašeg tabletnog računala zajedno s podacima o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije to mogu upotrebljavati za brisanje ili izmjenu vašeg dnevnika poziva."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Aplikaciji omogućuje izmjenu zapisnika poziva vašeg Android TV uređaja, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije to mogu upotrijebiti za brisanje ili izmjenu zapisnika poziva."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Aplikaciji omogućuje izmjenu dnevnika poziva vašeg telefona zajedno s podacima o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije to mogu upotrebljavati za brisanje ili izmjenu vašeg dnevnika poziva."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"pristupati biometrijskim senzorima (kao što su monitori otkucaja srca)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Pristupite podacima biometrijskih senzora kao što su puls, temperatura, postotak kisika u krvi itd."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"pristup biometrijskim senzorima (kao što su monitori pulsa) u pozadini"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Pristupite podacima biometrijskih senzora kao što su puls, temperatura, postotak kisika u krvi itd. u pozadini."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Pristup podacima s biometrijskih senzora, kao što je puls, dok se upotrebljava"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Omogućuje aplikaciji pristup podacima s biometrijskih senzora, kao što su puls, temperatura i postotak kisika u krvi, dok se aplikacija upotrebljava."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pristup podacima s biometrijskih senzora, kao što je puls, dok je u pozadini"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Omogućuje aplikaciji pristup podacima s biometrijskih senzora, kao što su puls, temperatura i postotak kisika u krvi, dok je aplikacija u pozadini."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Čitanje događaja i pojedinosti kalendara"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aplikacija može čitati sve kalendarske događaje pohranjene na tabletu i dijeliti ili spremati podatke iz vašeg kalendara."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aplikacija može čitati sve kalendarske događaje pohranjene na Android TV uređaju i dijeliti ili spremati podatke iz vašeg kalendara."</string>
@@ -690,8 +690,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Aplikaciji omogućuje čitanje audiodatoteka iz dijeljene pohrane."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"čitanje videodatoteka iz dijeljene pohrane"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Aplikaciji omogućuje čitanje videodatoteka iz dijeljene pohrane."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"čitanje slikovnih datoteka iz dijeljene pohrane"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Aplikaciji omogućuje čitanje slikovnih datoteka iz dijeljene pohrane."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"čitati slikovne datoteke iz dijeljene pohrane"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Aplikaciji omogućuje čitanje slikovnih datoteka iz dijeljene pohrane."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"izmjena ili brisanje sadržaja dijeljene pohrane"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Aplikaciji omogućuje pisanje sadržaja u dijeljenu pohranu."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"upućivanje/primanje SIP poziva"</string>
@@ -913,7 +913,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Pritisnite Izbornik za otključavanje ili pozivanje hitnih službi."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Pritisnite Izbornik za otključavanje."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Iscrtajte uzorak za otključavanje"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Hitni poziv"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Hitne službe"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Uzvrati poziv"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Ispravno!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Pokušajte ponovo"</string>
@@ -1052,7 +1052,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nikad"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nemate dozvolu za otvaranje te stranice."</string>
<string name="text_copied" msgid="2531420577879738860">"Tekst kopiran u međuspremnik."</string>
- <string name="copied" msgid="4675902854553014676">"Kopirano"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"U aplikaciji <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> zalijepljen je sadržaj aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Apl. <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> zalijepila je ovaj sadržaj iz međuspremnika"</string>
<string name="pasted_text" msgid="4298871641549173733">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> zalijepila je tekst koji ste kopirali"</string>
@@ -1453,8 +1452,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Aplikaciji omogućuje da traži dopuštenje za zanemarivanje optimizacija baterije za tu aplikaciju."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"slanje upita za sve pakete"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Aplikaciji omogućuje pregled instaliranih paketa."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"pristupiti SupplementalApijima"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Omogućuje aplikaciji pristupanje SupplementalApijima."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"pristupiti AdServices Topics API-ju"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Omogućuje aplikaciji pristupanje AdServices Topics API-ju."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"pristupiti AdServices Attribution API-jima"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Omogućuje aplikaciji pristupanje AdServices Attribution API-jima."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"pristupiti AdServices Custom Audiences API-ju"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Omogućuje aplikaciji pristupanje AdServices Custom Audiences API-ju."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dvaput dotaknite za upravljanje zumiranjem"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget nije moguće dodati."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Idi"</string>
@@ -1717,6 +1720,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Odjavljivanje korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Vlasnik"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gost"</string>
<string name="error_message_title" msgid="4082495589294631966">"Pogreška"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Vaš administrator ne dopušta tu promjenu"</string>
<string name="app_not_found" msgid="3429506115332341800">"Nije pronađena aplikacija za upravljanje ovom radnjom"</string>
@@ -2028,10 +2032,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DEINSTALIRAJ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"IPAK OTVORI"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Otkrivena je štetna aplikacija"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Zahtjev za pristup zapisnicima sustava"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Želite li dopustiti aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> da pristupa svim zapisnicima uređaja?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Samo ovaj put"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nemoj dopustiti"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"Aplikacija <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> zahtijeva zapisnike sustava radi funkcionalnog otklanjanja pogrešaka. Ti zapisnici mogu sadržavati podatke koje su zabilježile aplikacije i usluge na vašem uređaju."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"U zapisnicima uređaja bilježi se što se događa na uređaju. Aplikacije mogu koristiti te zapisnike kako bi pronašle i riješile poteškoće.\n\nNeki zapisnici mogu sadržavati osjetljive podatke, pa pristup svim zapisnicima uređaja odobrite samo pouzdanim aplikacijama. \n\nAko ne dopustite ovoj aplikaciji da pristupa svim zapisnicima uređaja, ona i dalje može pristupati svojim zapisnicima, a proizvođač uređaja i dalje može pristupati nekim zapisnicima ili podacima na vašem uređaju. Saznajte više"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikazuj ponovo"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> želi prikazivati isječke aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Uredi"</string>
@@ -2266,4 +2270,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> dugo se izvodi u pozadini. Dodirnite za pregled."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Provjera aktivnih aplikacija"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Kameri se ne može pristupiti s ovog uređaja"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index f901ca6..4cefac6 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"A szolgáltató ideiglenesen kikapcsolta a következő SIM-kártya esetében: <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"A mobilhálózat nem érhető el"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Próbálja meg módosítani a preferált hálózatot. Koppintson a módosításhoz."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Segélyhívás nem lehetséges"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Nem lehet segélyhívást kezdeményezni Wi-Fi-n keresztül"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Előfordulhat, hogy a segélyhívás funkció nem áll rendelkezésre"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"A(z) <xliff:g id="SPN">%s</xliff:g> nem támogatja segélyhívás indítását Wi-Fi-n keresztül. Koppintson a részletekért."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Értesítések"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Hívásátirányítás"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Sürgősségi visszahívás mód"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Lehetővé teszi, hogy az alkalmazás módosítsa a táblagép híváslistáját, beleértve a bejövő és kimenő hívások adatait is. A rosszindulatú alkalmazások ezt arra használhatják, hogy híváslistáját töröljék vagy módosítsák."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Lehetővé teszi, hogy az alkalmazás módosítsa az Android TV eszköz híváslistáját, beleértve a bejövő és kimenő hívások adatait is. A rosszindulatú alkalmazások ezt felhasználhatják a híváslista törlésére vagy módosítására."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Lehetővé teszi, hogy az alkalmazás módosítsa a telefon híváslistáját, beleértve a bejövő és kimenő hívások adatait is. A rosszindulatú alkalmazások ezt arra használhatják, hogy híváslistáját töröljék vagy módosítsák."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"hozzáférés a testérzékelőkhöz (például pulzusmérők)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Hozzáférhet olyan, testérzékelőktől származó adatokhoz, mint a pulzusszám, a testhőmérséklet, a véroxigénszint stb."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"hozzáférés a háttérben futó testérzékelőkhöz (például pulzusmérők)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Hozzáférhet olyan, a háttérben futó testérzékelőktől származó adatokhoz, mint a pulzusszám, a testhőmérséklet, a véroxigénszint stb."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Hozzáférés a testérzékelők adataihoz (pl. pulzusszám) használat közben"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Lehetővé teszi, hogy az alkalmazás hozzáférjen a testérzékelők adataihoz (pl. pulzusszám, testhőmérséklet és véroxigénszint), miközben az alkalmazás használatban van."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Hozzáférés a testérzékelők adataihoz (pl. pulzusszám) a háttérben"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Lehetővé teszi, hogy az alkalmazás hozzáférjen a testérzékelők adataihoz (pl. pulzusszám, testhőmérséklet és véroxigénszint), miközben az alkalmazás a háttérben van."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Naptáresemények és a naptári adatok olvasása"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Az alkalmazás olvashatja a táblagépen tárolt összes naptáreseményt, és megoszthatja vagy mentheti a naptáradatokat."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Az alkalmazás olvashatja az Android TV eszközön tárolt összes naptáreseményt, és megoszthatja vagy mentheti a naptáradatokat."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Engedélyezi az alkalmazásnak a megosztott tárhelyen található hangfájlok olvasását."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"a megosztott tárhelyen található videófájlok olvasása"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Engedélyezi az alkalmazásnak a megosztott tárhelyen található videófájlok olvasását."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"a megosztott tárhelyen található képfájlok olvasása"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Engedélyezi az alkalmazásnak a megosztott tárhelyen található képfájlok olvasását."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"a megosztott tárhelyen található képfájlok olvasása"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Engedélyezi az alkalmazásnak a megosztott tárhelyen található képfájlok olvasását."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"a közös tárhely tartalmainak törlése és módosítása"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Engedélyezi az alkalmazás számára a közös tárhely tartalmainak felülírását."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP-hívások indítása/fogadása"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"A feloldáshoz vagy segélyhívás kezdeményezéséhez nyomja meg a Menü gombot."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"A feloldáshoz nyomja meg a Menü gombot."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Rajzolja le a mintát a feloldáshoz"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Segélyhívás"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Segélyhívás"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Hívás folytatása"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Helyes!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Próbálja újra"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Soha"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nincs engedélye ennek az oldalnak a megnyitására."</string>
<string name="text_copied" msgid="2531420577879738860">"A szöveg bemásolva a vágólapra."</string>
- <string name="copied" msgid="4675902854553014676">"Átmásolva"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"A(z) <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> tartalmat másolt vágólapra a(z) <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> appból"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"A(z) <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> beillesztett a vágólapról"</string>
<string name="pasted_text" msgid="4298871641549173733">"A(z) <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> beillesztette a másolt szöveget"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Az alkalmazás engedélyt kérhet az akkumulátoroptimalizálási beállítások mellőzésére."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"az összes csomag lekérdezése"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Engedélyezi az adott alkalmazás számára, hogy lássa az összes telepített csomagot."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"hozzáférés ehhez: SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Lehetővé teszi egy alkalmazás számára, hogy hozzáférjen a következőhöz: SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"hozzáférés az AdServices Topics API-hoz"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Lehetővé teszi egy alkalmazás számára, hogy hozzáférjen az AdServices Topics API-hoz."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"hozzáférés az AdServices Attribution API-khoz"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Lehetővé teszi egy alkalmazás számára, hogy hozzáférjen az AdServices Attribution API-khoz."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"hozzáférés az AdServices Custom Audiences API-hoz"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Lehetővé teszi egy alkalmazás számára, hogy hozzáférjen az AdServices Custom Audiences API-hoz."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Érintse meg kétszer a nagyítás beállításához"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nem sikerült hozzáadni a modult."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ugrás"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Átváltás erre: <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> kijelentkeztetése folyamatban van…"</string>
<string name="owner_name" msgid="8713560351570795743">"Tulajdonos"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Vendég"</string>
<string name="error_message_title" msgid="4082495589294631966">"Hiba"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Ezt a módosítást nem engedélyezi a rendszergazda"</string>
<string name="app_not_found" msgid="3429506115332341800">"Nincs megfelelő alkalmazás a művelet elvégzésére."</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ELTÁVOLÍTÁS"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"MEGNYITÁS MÉGIS"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"A rendszer kártékony alkalmazást észlelt"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Rendszernaplókhoz való hozzáférés kérése"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Engedélyezi a(z) <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> számára, hogy hozzáférjen az összes eszköznaplóhoz?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Csak most"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Tiltás"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"Funkcionális hibaelhárítás céljából a(z) <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> hozzáférést kér a rendszernaplókhoz. A naplókban olyan információk lehetnek, amelyek az eszközön használt alkalmazásoktól és szolgáltatásoktól származnak."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Az eszköznaplók rögzítik, hogy mi történik az eszközén. Az alkalmazások ezeket a naplókat használhatják a problémák megkeresésére és kijavítására.\n\nBizonyos naplók érzékeny adatokat is tartalmazhatnak, ezért csak olyan alkalmazások számára engedélyezze az összes eszköznaplóhoz való hozzáférést, amelyekben megbízik. \n\nHa nem engedélyezi ennek az alkalmazásnak, hogy hozzáférjen az összes eszköznaplójához, az app továbbra is hozzáférhet a saját naplóihoz, és előfordulhat, hogy az eszköz gyártója továbbra is hozzáfér az eszközön található bizonyos naplókhoz és adatokhoz. További információ."</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne jelenjen meg újra"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"A(z) <xliff:g id="APP_0">%1$s</xliff:g> alkalmazás részleteket szeretne megjeleníteni a(z) <xliff:g id="APP_2">%2$s</xliff:g> alkalmazásból"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Szerkesztés"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"A(z) <xliff:g id="APP">%1$s</xliff:g> alkalmazás már hosszú ideje fut a háttérben. Koppintson az áttekintéshez."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Aktív alkalmazások ellenőrzése"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Ezen az eszközön nem lehet hozzáférni a kamerához"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 136f0ea..f170740 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> քարտի օպերատորը ժամանակավորապես անջատել է"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Չհաջողվեց միանալ բջջային ցանցին"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Փորձեք այլ ցանցի միանալ: Հպեք՝ նախընտրած ցանցը փոխելու համար:"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Շտապ կանչերը հասանելի չեն"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Շտապ կանչերը հասանելի չեն Wi‑Fi-ի միջոցով"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Շտապ կանչերը կարող են անհասանելի լինել"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g>՝ չի աջակցում շտապ կանչեր Wi-Fi-ի միջոցով։ Հպեք՝ ավելին իմանալու համար։"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Ծանուցումներ"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Զանգի վերահասցեավորում"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Շտապ հետզանգի ռեժիմ"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Թույլ է տալիս հավելվածին փոփոխել ձեր պլանշետի զանգերի մատյանը, այդ թվում` մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել` ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Թույլ է տալիս հավելվածին փոփոխել Android TV սարքի զանգերի մատյանը, այդ թվում՝ մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել՝ ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Թույլ է տալիս հավելվածին փոփոխել ձեր հեռախոսի զանգերի մատյանը, այդ թվում` մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել` ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"օգտագործել մարմնի սենսորները (օրինակ՝ սրտի կծկումների հաճախականության չափիչ)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Մարմնի սենսորների տվյալների (օրինակ՝ սրտի զարկերի հաճախականության, ջերմաստիճանի, արյան մեջ թթվածնի տոկոսային պարունակության ցուցանիշների) օգտագործման թույլտվություն"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"ֆոնային ռեժիմում մարմնի սենսորների տվյալների օգտագործման թույլտվություն"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Ֆոնային ռեժիմում մարմնի սենսորների տվյալների (օրինակ՝ սրտի զարկերի հաճախականության, ջերմաստիճանի, արյան մեջ թթվածնի տոկոսային պարունակության ցուցանիշների) օգտագործման թույլտվություն"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Մարմնի սենսորների տվյալների հասանելիություն հավելվածի օգտագործման ընթացքում"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Հավելվածին հասանելի է դարձնում մարմնի սենսորների տվյալները (օրինակ՝ սրտի զարկերի հաճախականությունը, ջերմաստիճանը, արյան մեջ թթվածնի տոկոսային պարունակության ցուցանիշները) հավելվածի օգտագործման ժամանակ։"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Մարմնի սենսորների տվյալների հասանելիություն ֆոնային ռեժիմում"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Հավելվածին հասանելի է դարձնում մարմնի սենսորների տվյալները (օրինակ՝ սրտի զարկերի հաճախականությունը, ջերմաստիճանը, արյան մեջ թթվածնի տոկոսային պարունակության ցուցանիշները), երբ հավելվածն աշխատում է ֆոնային ռեժիմում։"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Կարդալ օրացույցի միջոցառումները և տվյալները"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Այս հավելվածը կարող է կարդալ օրացույցի՝ ձեր պլանշետում պահված բոլոր միջոցառումները, ինչպես նաև հրապարակել կամ պահել ձեր օրացույցի տվյալները:"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Այս հավելվածը կարող է կարդալ օրացույցի՝ ձեր Android TV սարքում պահված բոլոր միջոցառումները, ինչպես նաև հրապարակել կամ պահել ձեր օրացույցի տվյալները:"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Հավելվածին թույլ է տալիս կարդալ ձեր սարքի ընդհանուր հիշողության մեջ պահված աուդիո ֆայլերը։"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"կարդալ ձեր սարքի ընդհանուր հիշողության մեջ պահված վիդեո ֆայլերը"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Հավելվածին թույլ է տալիս կարդալ ձեր սարքի ընդհանուր հիշողության մեջ պահված վիդեո ֆայլերը։"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"կարդալ ձեր սարքի ընդհանուր հիշողության մեջ պահված գրաֆիկական ֆայլերը"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Հավելվածին թույլ է տալիս կարդալ ձեր սարքի ընդհանուր հիշողության մեջ պահված գրաֆիկական ֆայլերը։"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"կարդալ ձեր սարքի ընդհանուր հիշողության մեջ պահված գրաֆիկական ֆայլերը"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Հավելվածին թույլ է տալիս կարդալ ձեր սարքի ընդհանուր հիշողության մեջ պահված գրաֆիկական ֆայլերը։"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"փոփոխել կամ ջնջել ձեր ընդհանուր հիշողության բովանդակությունը"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Հավելվածին թույլ է տալիս փոփոխել ձեր ընդհանուր հիշողության պարունակությունը:"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"կատարել կամ ստանալ SIP զանգեր"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Ապակողպելու կամ շտապ կանչ անելու համար սեղմեք «Ընտրացանկ»"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Ապակողպելու համար սեղմեք Ցանկը:"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Հավաքեք սխեման` ապակողպելու համար"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Շտապ կանչ"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Շտապ կանչ"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Վերադառնալ զանգին"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Ճիշտ է:"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Կրկին փորձեք"</string>
@@ -931,7 +931,7 @@
<string name="lockscreen_transport_next_description" msgid="2931509904881099919">"Հաջորդը"</string>
<string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Դադարեցնել"</string>
<string name="lockscreen_transport_play_description" msgid="106868788691652733">"Նվագարկել"</string>
- <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Դադարեցնել"</string>
+ <string name="lockscreen_transport_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>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Երբեք"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Դուք չունեք այս էջը բացելու թույլտվություն:"</string>
<string name="text_copied" msgid="2531420577879738860">"Տեքստը պատճենված է սեղմատախտակին:"</string>
- <string name="copied" msgid="4675902854553014676">"Պատճենվեց"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> հավելվածը տվյալներ տեղադրեց <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> հավելվածից"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> հավելվածը տվյալներ է տեղադրել ձեր սեղմատախտակից"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> հավելվածը տեղադրեց ձեր պատճենած տեքստը"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Հավելվածին հնարավորություն է տալիս հայցելու թույլտվություն՝ տվյալ հավելվածի համար մարտկոցի օպտիմալացումն անտեսելու համար:"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"հարցում բոլոր փաթեթների համար"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Թույլ է տալիս հավելվածին տեսնել բոլոր տեղադրված փաթեթները։"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"օգտվել SupplementalApis-ից"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Թույլ է տալիս հավելվածին օգտվել SupplementalApis-ից։"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API-ի օգտագործման թույլտվություն"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Թույլ է տալիս հավելվածին օգտագործել AdServices Topics API-ը։"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API-ների օգտագործման թույլտվություն"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Թույլ է տալիս հավելվածին օգտագործել AdServices Attribution API-ները։"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API-ի օգտագործման թույլտվություն"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Թույլ է տալիս հավելվածին օգտագործել AdServices Custom Audiences API-ը։"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Հպեք երկու անգամ` խոշորացման վերահսկման համար"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Չհաջողվեց վիջեթ ավելացնել:"</string>
<string name="ime_action_go" msgid="5536744546326495436">"Առաջ"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Անցում հետևյալ պրոֆիլին՝ <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Ելք <xliff:g id="NAME">%1$s</xliff:g>-ից…"</string>
<string name="owner_name" msgid="8713560351570795743">"Սեփականատեր"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Հյուր"</string>
<string name="error_message_title" msgid="4082495589294631966">"Սխալ"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Ձեր ադմինիստրատորը չի թույլատրում այս փոփոխությունը"</string>
<string name="app_not_found" msgid="3429506115332341800">"Այս գործողությունը կատարելու համար ոչ մի ծրագիր չի գտնվել:"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ԱՊԱՏԵՂԱԴՐԵԼ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ԲԱՑԵԼ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Հայտնաբերվել է վնասաբեր հավելված"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Համակարգի մատյանների օգտագործման հարցում"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Հասանելի դարձնե՞լ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> հավելվածին սարքի բոլոր մատյանները"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Միայն այս անգամ"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Չթույլատրել"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> հավելվածը համակարգի մատյաններն օգտագործելու թույլտվություն է խնդրում՝ ֆունկցիոնալ վրիպազերծում կատարելու համար։ Այս մատյանները կարող են պարունակել տեղեկություններ, որոնք գրվել են ձեր սարքի հավելվածների ու ծառայությունների կողմից։"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Այն, ինչ տեղի է ունենում ձեր սարքում, գրանցվում է սարքի մատյաններում։ Հավելվածները կարող են օգտագործել դրանք՝ անսարքությունները հայտնաբերելու և վերացնելու նպատակով։\n\nՔանի որ որոշ մատյաններ պարունակում են անձնական տեղեկություններ, խորհուրդ ենք տալիս հասանելի դարձնել ձեր սարքի բոլոր մատյանները միայն վստահելի հավելվածներին։ \n\nԵթե այս հավելվածին նման թույլտվություն չեք տվել, դրան նախկինի պես հասանելի կլինեն իր մատյանները։ Հնարավոր է՝ ձեր սարքի արտադրողին ևս հասանելի լինեն սարքի որոշ մատյաններ և տեղեկություններ։ Իմանալ ավելին"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Այլևս ցույց չտալ"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> հավելվածն ուզում է ցուցադրել հատվածներ <xliff:g id="APP_2">%2$s</xliff:g> հավելվածից"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Փոփոխել"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> հավելվածը երկար ժամանակ աշխատում է ֆոնային ռեժիմում։ Հպեք՝ դիտելու համար։"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Ստուգել ակտիվ հավելվածները"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Հնարավոր չէ բացել տեսախցիկն այս սարքից"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index d2bad48..a16505c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Dinonaktifkan sementara oleh operator untuk SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Tidak dapat menjangkau jaringan seluler"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Coba ubah jaringan pilihan. Ketuk untuk mengubah."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Panggilan darurat tidak tersedia"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Tidak dapat melakukan panggilan darurat melalui Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Panggilan darurat mungkin tidak tersedia"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> tidak mendukung panggilan darurat melalui Wi-Fi. Ketuk untuk melihat detailnya."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Notifikasi"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Penerusan panggilan"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mode telepon balik darurat"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Memungkinkan apl memodifikasi log panggilan tablet Anda, termasuk data tentang panggilan masuk dan keluar. Apl berbahaya dapat menggunakan ini untuk menghapus atau memodifikasi log panggilan Anda."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Mengizinkan aplikasi mengubah log panggilan perangkat Android TV, termasuk data tentang panggilan masuk dan keluar. Aplikasi berbahaya dapat menggunakan izin ini untuk menghapus atau mengubah log panggilan Anda."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Memungkinkan apl memodifikasi log panggilan ponsel Anda, termasuk data tentang panggilan masuk dan keluar. Apl berbahaya dapat menggunakan ini untuk menghapus atau memodifikasi log panggilan Anda."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"akses sensor tubuh (misalnya, monitor detak jantung)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Akses ke data dari sensor tubuh seperti detak jantung, suhu, persentase oksigen dalam darah, dan lainnya."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"akses sensor tubuh (misalnya, monitor detak jantung) saat di latar belakang"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Akses ke data dari sensor tubuh seperti detak jantung, suhu, persentase oksigen dalam darah, dan lainnya saat di latar belakang."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Mengakses data sensor tubuh, seperti detak jantung, saat sedang digunakan"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Mengizinkan aplikasi mengakses data sensor tubuh, seperti detak jantung, suhu, dan persentase oksigen dalam darah, saat aplikasi sedang digunakan."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Mengakses data sensor tubuh, seperti detak jantung, saat ada di latar belakang"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Mengizinkan aplikasi mengakses data sensor tubuh, seperti detak jantung, suhu, dan persentase oksigen dalam darah, saat aplikasi berada di latar belakang."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Baca acara kalender dan detailnya"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aplikasi ini dapat membaca semua acara kalender yang tersimpan di tablet dan membagikan atau menyimpan data kalender."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aplikasi ini dapat membaca semua acara kalender yang tersimpan di perangkat Android TV dan membagikan atau menyimpan data kalender."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Mengizinkan aplikasi membaca file audio dari penyimpanan bersama."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"membaca file video dari penyimpanan bersama"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Mengizinkan aplikasi membaca file video dari penyimpanan bersama."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"membaca file gambar dari penyimpanan bersama"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Mengizinkan aplikasi membaca file gambar dari penyimpanan bersama."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"membaca file gambar dari penyimpanan bersama"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Mengizinkan aplikasi membaca file gambar dari penyimpanan bersama."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"memodifikasi atau menghapus konten penyimpanan bersama Anda"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Mengizinkan aplikasi menulis konten penyimpanan bersama Anda."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"lakukan/terima panggilan SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Tekan Menu untuk membuka atau melakukan panggilan darurat."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Tekan Menu untuk membuka."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Buat pola untuk membuka"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Panggilan darurat"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Darurat"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Kembali ke panggilan"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Perbaiki!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Coba lagi"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Jangan"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Anda tidak memiliki izin untuk membuka halaman ini."</string>
<string name="text_copied" msgid="2531420577879738860">"Teks disalin ke papan klip."</string>
- <string name="copied" msgid="4675902854553014676">"Disalin"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ditempelkan dari <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> menempelkan konten dari papan klip Anda"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> menempelkan teks yang Anda salin"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Mengizinkan aplikasi meminta izin untuk mengabaikan pengoptimalan baterai bagi aplikasi tersebut."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"mengkueri semua paket"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Mengizinkan aplikasi melihat semua paket yang diinstal."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"akses SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Mengizinkan aplikasi mengakses SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"mengakses AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Mengizinkan aplikasi mengakses AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"mengakses AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Mengizinkan aplikasi mengakses AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"mengakses AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Mengizinkan aplikasi mengakses AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Ketuk dua kali untuk kontrol perbesar/perkecil"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Tidak dapat menambahkan widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Buka"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Beralih ke <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Mengeluarkan <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Pemilik"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Tamu"</string>
<string name="error_message_title" msgid="4082495589294631966">"Kesalahan"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Perubahan ini tidak diizinkan oleh admin Anda"</string>
<string name="app_not_found" msgid="3429506115332341800">"Tidak ada aplikasi yang ditemukan untuk menangani tindakan ini"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"UNINSTAL"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"TETAP BUKA"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Aplikasi berbahaya terdeteksi"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Permintaan akses log sistem"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Izinkan <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> mengakses semua log perangkat?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Hanya kali ini"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Jangan izinkan"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> meminta log sistem untuk proses debug fungsional. Log ini mungkin berisi informasi yang telah ditulis oleh aplikasi dan layanan di perangkat Anda."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Log perangkat merekam hal-hal yang terjadi di perangkat Anda. Aplikasi dapat menggunakan log ini untuk menemukan dan memperbaiki masalah.\n\nBeberapa log mungkin berisi info sensitif, jadi hanya izinkan aplikasi yang Anda percayai untuk mengakses semua log perangkat. \n\nJika Anda tidak mengizinkan aplikasi ini mengakses semua log perangkat, aplikasi masih dapat mengakses log-nya sendiri dan produsen perangkat masih dapat mengakses beberapa log atau info di perangkat Anda. Pelajari lebih lanjut"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Jangan tampilkan lagi"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ingin menampilkan potongan <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> berjalan di latar belakang dalam waktu yang lama. Ketuk untuk meninjau."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Periksa aplikasi aktif"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Tidak dapat mengakses kamera dari perangkat ini"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index d49a777..6b30619 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Símafyrirtækið slökkti tímabundið á þessu fyrir SIM-kort <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Ekki næst samband við farsímakerfi"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prófaðu að velja annað símkerfi. Ýttu til að breyta."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Neyðarsímtöl eru ekki í boði"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Ekki er hægt að hringja neyðarsímtöl með Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Neyðarsímtöl eru hugsanlega ekki tiltæk"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> styður ekki neyðarsímtöl um Wi-Fi. Ýttu til að fá frekari upplýsingar."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Tilkynningar"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Símtalsflutningur"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Stilling fyrir svarhringingu neyðarsímtala"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Leyfir forriti að breyta símtalaskrá spjaldtölvunnar, þ. á m. gögnum um hringd og móttekin símtöl. Spilliforrit geta notað þetta til að eyða eða breyta símtalaskránni."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Leyfir forritinu að breyta símtalaskrá Android TV tækisins, þ. á m. gögnum um hringd og móttekin símtöl. Spilliforrit geta notað þetta til að eyða eða breyta símtalaskránni."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Leyfir forriti að breyta símtalaskrá símans, þ. á m. gögnum um hringd og móttekin símtöl. Spilliforrit geta notað þetta til að eyða eða breyta símtalaskránni."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"fá aðgang að líkamsskynjurum (s.s. hjartsláttarmælum)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Aðgangur að gögnum frá líkamsskynjurum, svo sem um hjartslátt, hitastig, súrefnismettun í blóði o.s.frv."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"aðgangur að líkamsskynjurum (svo sem púlsmælum) í bakgrunni"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Aðgangur að gögnum frá líkamsskynjurum, svo sem um hjartslátt, hitastig, súrefnismettun í blóði o.s.frv. í bakgrunni."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Aðgangur að gögnum líkamsskynjara, svo sem um hjartslátt, meðan það er í notkun"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Veitir forritinu aðgang að gögnum frá líkamsskynjurum, svo sem um hjartslátt, hitastig og súrefnismettun í blóði á meðan forritið er í notkun."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Aðgangur að gögnum líkamsskynjara, t.d. um hjartslátt, meðan það er í bakgrunni"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Veitir forritinu aðgang að gögnum frá líkamsskynjurum, svo sem um hjartslátt, hitastig og súrefnismettun í blóði á meðan forritið keyrir í bakgrunni."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Lesa dagatalsviðburði og upplýsingar"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Þetta forrit getur lesið alla dagatalsviðburði sem eru vistaðir í spjaldtölvunni og deilt eða vistað dagatalsgögnin þín."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Þetta forrit getur lesið alla dagatalsviðburði sem eru vistaðir í Android TV og deilt eða vistað dagatalsgögnin þín."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Leyfir forritinu að lesa hljóðskrár úr samnýtta geymslurýminu þínu."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"lesa myndskeiðaskrár úr samnýttu geymslurými"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Leyfir forritinu að lesa myndskeiðaskrár úr samnýtta geymslurýminu þínu."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"lesa myndskrár úr samnýttu geymslurými"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Leyfir forritinu að lesa myndskrár úr samnýtta geymslurýminu þínu."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"lesa myndskrár úr samnýttu geymslurými"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Leyfir forritinu að lesa myndskrár úr samnýtta geymslurýminu þínu."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"breyta eða eyða innihaldi samnýtta geymslurýmisins"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Leyfir forriti að skrifa í innihald samnýtta geymslurýmisins."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"hringja/svara SIP-símtölum"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Ýttu á valmyndartakkann til að taka úr lás eða hringja neyðarsímtal."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Ýttu á valmyndartakkann til að taka úr lás."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Teiknaðu mynstur til að taka úr lás"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Neyðarsímtal"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Neyðarsímtal"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Aftur í símtal"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Rétt!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Reyndu aftur"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Aldrei"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Þú hefur ekki heimild til að opna þessa síðu."</string>
<string name="text_copied" msgid="2531420577879738860">"Texti afritaður á klippiborð."</string>
- <string name="copied" msgid="4675902854553014676">"Afritað"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> límt úr <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> límdi af klippiborðinu"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> límdi texta sem þú afritaðir"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Gerir forriti kleift að biðja um heimild til að hunsa rafhlöðusparnað fyrir forritið."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"spyrja fyrir alla pakka"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Leyfir forriti að sjá alla uppsetta pakka."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"aðgangur að SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Veitir forriti aðgang að SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"opna forritaskil umfjöllunarefna AdServices"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Veitir forritum aðgang að forritaskilum umfjöllunarefna AdServices."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"opna forritaskil eigindar AdServices"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Veitir forriti aðgang að forritaskilum eigindar AdServices."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"opna forritaskil sérsniðinna áhorfenda AdServices"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Veitir forritum aðgang að forritaskilum sérsniðinna áhorfenda AdServices."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Ýttu tvisvar til að opna aðdráttarstýringar"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Ekki tókst að bæta græju við."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Áfram"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Skiptir yfir á <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Skráir <xliff:g id="NAME">%1$s</xliff:g> út…"</string>
<string name="owner_name" msgid="8713560351570795743">"Eigandi"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gestur"</string>
<string name="error_message_title" msgid="4082495589294631966">"Villa"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Kerfisstjórinn þinn leyfir ekki þessa breytingu"</string>
<string name="app_not_found" msgid="3429506115332341800">"Ekkert forrit fannst til að meðhöndla þessa aðgerð"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"FJARLÆGJA"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPNA SAMT"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Skaðlegt forrit fannst"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Beiðni um aðgang að kerfisannálum"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Veita <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aðgang að öllum annálum í tækinu?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Aðeins í þetta skipti"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ekki leyfa"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> biður um kerfisannála fyrir virka villuleit. Annálarnir kunna að innihalda upplýsingar sem forrit og þjónustur í tækinu þínu hafa skrifað."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Annálar tækisins skrá niður það sem gerist í tækinu. Forrit geta notað þessa annála til að finna og lagfæra vandamál.\n\nTilteknir annálar innihalda viðkvæmar upplýsingar og því skaltu einungis veita forritum sem þú treystir aðgang að öllum annálum tækisins. \n\nEf þú veitir þessu forriti ekki aðgang að öllum annálum tækisins hefur það áfram aðgang að eigin annálum og framleiðandi tækisins getur hugsanlega opnað tiltekna annála eða upplýsingar í tækinu. Nánar"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ekki sýna aftur"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> vill sýna sneiðar úr <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Breyta"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> hefur keyrt lengi í bakgrunni. Ýttu til að skoða."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Skoða virk forrit"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Aðgangur að myndavél er ekki tiltækur í þessu tæki"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 1ef2619..0394cea 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -51,8 +51,8 @@
<string name="needPuk2" msgid="7032612093451537186">"Digita il PUK2 per sbloccare la SIM."</string>
<string name="enablePin" msgid="2543771964137091212">"Operazione non riuscita; attiva blocco SIM/RUIM."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
- <item quantity="one">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
<item quantity="other">Hai ancora <xliff:g id="NUMBER_1">%d</xliff:g> tentativi a disposizione prima che la SIM venga bloccata.</item>
+ <item quantity="one">Hai ancora <xliff:g id="NUMBER_0">%d</xliff:g> tentativo a disposizione prima che la SIM venga bloccata.</item>
</plurals>
<string name="imei" msgid="2157082351232630390">"IMEI"</string>
<string name="meid" msgid="3291227361605924674">"MEID"</string>
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Servizio disattivato temporaneamente dall\'operatore per la SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Impossibile raggiungere la rete mobile"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prova a cambiare la rete preferita. Tocca per cambiare."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Chiamate di emergenza non disponibili"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Impossibile fare chiamate di emergenza tramite Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Le chiamate di emergenza potrebbero non essere disponibili"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> non supporta le chiamate di emergenza tramite Wi-Fi. Tocca per conoscere i dettagli."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Avvisi"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Deviazione chiamate"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modalità di richiamata di emergenza"</string>
@@ -180,7 +180,7 @@
<string name="low_memory" product="watch" msgid="3479447988234030194">"La memoria dell\'orologio è piena. Elimina alcuni file per liberare spazio."</string>
<string name="low_memory" product="tv" msgid="6663680413790323318">"Lo spazio di archiviazione del dispositivo Android TV è pieno. Elimina alcuni file per liberare spazio."</string>
<string name="low_memory" product="default" msgid="2539532364144025569">"Spazio di archiviazione del telefono esaurito. Elimina alcuni file per liberare spazio."</string>
- <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{Autorità di certificazione installata}one{Autorità di certificazione installata}other{Autorità di certificazione installate}}"</string>
+ <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{Autorità di certificazione installata}other{Autorità di certificazione installate}}"</string>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Da una terza parte sconosciuta"</string>
<string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Dall\'amministratore del tuo profilo di lavoro"</string>
<string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Da <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
@@ -254,7 +254,7 @@
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Utilizza questa opzione nella maggior parte dei casi. Ti consente di monitorare l\'avanzamento della segnalazione, di inserire maggiori dettagli relativi al problema e di acquisire screenshot. Potrebbero essere omesse alcune sezioni meno utilizzate il cui inserimento nella segnalazione richiede molto tempo."</string>
<string name="bugreport_option_full_title" msgid="7681035745950045690">"Report completo"</string>
<string name="bugreport_option_full_summary" msgid="1975130009258435885">"Utilizza questa opzione per ridurre al minimo l\'interferenza di sistema quando il dispositivo non risponde, è troppo lento oppure quando ti servono tutte le sezioni della segnalazione. Non puoi inserire altri dettagli o acquisire altri screenshot."</string>
- <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Lo screenshot per la segnalazione di bug verrà acquisito tra # secondo.}one{Lo screenshot per la segnalazione di bug verrà acquisito tra # secondo.}other{Lo screenshot per la segnalazione di bug verrà acquisito tra # secondi.}}"</string>
+ <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Lo screenshot per la segnalazione di bug verrà acquisito tra # secondo.}other{Lo screenshot per la segnalazione di bug verrà acquisito tra # secondi.}}"</string>
<string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Screenshot con segnalazione di bug effettuato correttamente"</string>
<string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Impossibile acquisire screenshot con segnalazione di bug"</string>
<string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"Modalità silenziosa"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Consente all\'applicazione di modificare il registro chiamate del tablet, inclusi i dati sulle chiamate in arrivo e in uscita. Le applicazioni dannose potrebbero farne uso per cancellare o modificare il registro chiamate."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Consente all\'app di modificare il registro chiamate del dispositivo Android TV, inclusi i dati relativi alle chiamate in arrivo e in uscita. Le app dannose potrebbero farne uso per cancellare o modificare il registro chiamate."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Consente all\'applicazione di modificare il registro chiamate del telefono, inclusi i dati sulle chiamate in arrivo e in uscita. Le applicazioni dannose potrebbero farne uso per cancellare o modificare il registro chiamate."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"accesso ai sensori (come il cardiofrequenzimetro)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Accedere ai dati dei sensori del corpo, ad esempio a frequenza cardiaca, temperatura, percentuale di ossigeno nel sangue e così via."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"Accesso ai sensori del corpo (come i cardiofrequenzimetri) in background"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Accedere ai dati dei sensori del corpo, ad esempio a frequenza cardiaca, temperatura, percentuale di ossigeno nel sangue e così via in background."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Accesso ai dati dei sensori del corpo, come il battito cardiaco, mentre è in uso"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Autorizza l\'app ad accedere ai dati relativi ai sensori del corpo, ad esempio battito cardiaco, temperatura e percentuale di ossigeno nel sangue, mentre l\'app è in uso."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accesso ai dati dei sensori del corpo, come il battito cardiaco, in background"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Autorizza l\'app ad accedere ai dati relativi ai sensori del corpo, ad esempio battito cardiaco, temperatura e percentuale di ossigeno nel sangue, mentre l\'app è in background."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"lettura di eventi di calendario e dettagli"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Questa app può leggere tutti gli eventi di calendario memorizzati sul tablet e condividere o salvare i dati di calendario."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Questa app può leggere tutti gli eventi di calendario memorizzati sul dispositivo Android TV e condividere o salvare i dati di calendario."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Consente all\'app di leggere i file audio dal tuo spazio di archiviazione condiviso."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"Lettura dei file video dallo spazio di archiviazione condiviso"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Consente all\'app di leggere i file video dal tuo spazio di archiviazione condiviso."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"Lettura dei file immagine dallo spazio di archiviazione condiviso"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Consente all\'app di leggere i file immagine dal tuo spazio di archiviazione condiviso."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"Lettura dei file immagine dallo spazio di archiviazione condiviso"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Consente all\'app di leggere i file immagine dal tuo spazio di archiviazione condiviso."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"Modifica/eliminazione dei contenuti dell\'archivio condiviso"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Consente all\'app di modificare i contenuti del tuo archivio condiviso."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"invio/ricezione di chiamate SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Premi Menu per sbloccare o effettuare chiamate di emergenza."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Premi Menu per sbloccare."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Traccia la sequenza di sblocco"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Chiamata di emergenza"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergenza"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Torna a chiamata"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Corretta."</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Riprova"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Mai"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Non sei autorizzato ad aprire questa pagina."</string>
<string name="text_copied" msgid="2531420577879738860">"Testo copiato negli appunti."</string>
- <string name="copied" msgid="4675902854553014676">"Copia eseguita"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Dati dell\'app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> incollati dall\'app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha incollato dati dagli appunti"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ha incollato il testo che hai copiato"</string>
@@ -1080,7 +1079,7 @@
<string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vuole attivare la funzione Esplora al tocco. Quando la funzione Esplora al tocco è attiva, puoi ascoltare o visualizzare le descrizioni di ciò che stai toccando oppure interagire con il telefono tramite gesti."</string>
<string name="oneMonthDurationPast" msgid="4538030857114635777">"1 mese fa"</string>
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Oltre 1 mese fa"</string>
- <string name="last_num_days" msgid="2393660431490280537">"{count,plural, =1{Ultimo giorno}one{Ultimo giorno}other{Ultimi # giorni}}"</string>
+ <string name="last_num_days" msgid="2393660431490280537">"{count,plural, =1{Ultimo giorno}other{Ultimi # giorni}}"</string>
<string name="last_month" msgid="1528906781083518683">"Ultimo mese"</string>
<string name="older" msgid="1645159827884647400">"Precedente"</string>
<string name="preposition_for_date" msgid="2780767868832729599">"<xliff:g id="DATE">%s</xliff:g>"</string>
@@ -1107,14 +1106,14 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"tra <xliff:g id="COUNT">%d</xliff:g> h"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"tra <xliff:g id="COUNT">%d</xliff:g> g"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"tra <xliff:g id="COUNT">%d</xliff:g> a"</string>
- <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# minuto fa}one{# minuto fa}other{# minuti fa}}"</string>
- <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# ora fa}one{# ora fa}other{# ore fa}}"</string>
- <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# giorno fa}one{# giorno fa}other{# giorni fa}}"</string>
- <string name="duration_years_relative" msgid="8731202348869424370">"{count,plural, =1{# anno fa}one{# anno fa}other{# anni fa}}"</string>
- <string name="duration_minutes_relative_future" msgid="5259574171747708115">"{count,plural, =1{# minuto}one{# minuto}other{# minuti}}"</string>
- <string name="duration_hours_relative_future" msgid="6670440478481140565">"{count,plural, =1{# ora}one{# ora}other{# ore}}"</string>
- <string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# giorno}one{# giorno}other{# giorni}}"</string>
- <string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# anno}one{# anno}other{# anni}}"</string>
+ <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# minuto fa}other{# minuti fa}}"</string>
+ <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# ora fa}other{# ore fa}}"</string>
+ <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# giorno fa}other{# giorni fa}}"</string>
+ <string name="duration_years_relative" msgid="8731202348869424370">"{count,plural, =1{# anno fa}other{# anni fa}}"</string>
+ <string name="duration_minutes_relative_future" msgid="5259574171747708115">"{count,plural, =1{# minuto}other{# minuti}}"</string>
+ <string name="duration_hours_relative_future" msgid="6670440478481140565">"{count,plural, =1{# ora}other{# ore}}"</string>
+ <string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# giorno}other{# giorni}}"</string>
+ <string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# anno}other{# anni}}"</string>
<string name="VideoView_error_title" msgid="5750686717225068016">"Problemi video"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"Questo video non è valido per lo streaming su questo dispositivo."</string>
<string name="VideoView_error_text_unknown" msgid="7658683339707607138">"Impossibile riprodurre il video."</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Consente a un\'app di chiedere l\'autorizzazione a ignorare le ottimizzazioni della batteria per quell\'app."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"Invio di query per tutti i pacchetti"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Consente a un\'app di visualizzare tutti i pacchetti installati."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"Accesso a SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Consente a un\'applicazione di accedere a SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"accedi all\'API AdServices Topics"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Consente a un\'applicazione di accedere all\'API AdServices Topics."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"accedi alle API AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Consente a un\'applicazione di accedere alle API AdServices Attribution."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"accedi all\'API AdServices Custom Audiences"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Consente a un\'applicazione di accedere all\'API AdServices Custom Audiences."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tocca due volte per il comando dello zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Aggiunta del widget non riuscita."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Vai"</string>
@@ -1504,7 +1507,7 @@
<string name="skip_button_label" msgid="3566599811326688389">"Salta"</string>
<string name="no_matches" msgid="6472699895759164599">"Nessuna corrispondenza"</string>
<string name="find_on_page" msgid="5400537367077438198">"Trova nella pagina"</string>
- <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# corrispondenza}one{# di {total}}other{# di {total}}}"</string>
+ <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# corrispondenza}other{# di {total}}}"</string>
<string name="action_mode_done" msgid="2536182504764803222">"Fine"</string>
<string name="progress_erasing" msgid="6891435992721028004">"Cancellazione archivio condiviso…"</string>
<string name="share" msgid="4157615043345227321">"Condividi"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Passaggio a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Disconnessione di <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Proprietario"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Ospite"</string>
<string name="error_message_title" msgid="4082495589294631966">"Errore"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Questa modifica non è consentita dall\'amministratore"</string>
<string name="app_not_found" msgid="3429506115332341800">"Nessuna applicazione trovata in grado di gestire questa azione"</string>
@@ -1857,14 +1861,14 @@
<string name="data_saver_description" msgid="4995164271550590517">"Per contribuire a ridurre l\'utilizzo dei dati, la funzione Risparmio dati impedisce ad alcune app di inviare o ricevere dati in background. Un\'app in uso può accedere ai dati, ma potrebbe farlo con meno frequenza. Esempio: le immagini non vengono visualizzate finché non le tocchi."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Attivare Risparmio dati?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Attiva"</string>
- <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Per un minuto (fino alle ore {formattedTime})}one{Per # minuto (fino alle ore {formattedTime})}other{Per # minuti (fino alle ore {formattedTime})}}"</string>
- <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{Per 1 min (fino alle ore {formattedTime})}one{Per # min (fino alle ore {formattedTime})}other{Per # min (fino alle ore {formattedTime})}}"</string>
- <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{Per 1 ora (fino alle ore {formattedTime})}one{Per # ora (fino alle ore {formattedTime})}other{Per # ore (fino alle ore {formattedTime})}}"</string>
- <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{Per 1 h (fino alle ore {formattedTime})}one{Per # h (fino alle ore {formattedTime})}other{Per # h (fino alle ore {formattedTime})}}"</string>
- <string name="zen_mode_duration_minutes" msgid="2340007982276569054">"{count,plural, =1{Per un minuto}one{Per # minuto}other{Per # minuti}}"</string>
- <string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{Per 1 min}one{Per # min}other{Per # min}}"</string>
- <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{Per 1 ora}one{Per # ora}other{Per # ore}}"</string>
- <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{Per 1 h}one{Per # h}other{Per # h}}"</string>
+ <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Per un minuto (fino alle ore {formattedTime})}other{Per # minuti (fino alle ore {formattedTime})}}"</string>
+ <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{Per 1 min (fino alle ore {formattedTime})}other{Per # min (fino alle ore {formattedTime})}}"</string>
+ <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{Per 1 ora (fino alle ore {formattedTime})}other{Per # ore (fino alle ore {formattedTime})}}"</string>
+ <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{Per 1 h (fino alle ore {formattedTime})}other{Per # h (fino alle ore {formattedTime})}}"</string>
+ <string name="zen_mode_duration_minutes" msgid="2340007982276569054">"{count,plural, =1{Per un minuto}other{Per # minuti}}"</string>
+ <string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{Per 1 min}other{Per # min}}"</string>
+ <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{Per 1 ora}other{Per # ore}}"</string>
+ <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{Per 1 h}other{Per # h}}"</string>
<string name="zen_mode_until_next_day" msgid="1403042784161725038">"Fino a: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_until" msgid="2250286190237669079">"Fino a <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_alarm" msgid="7046911727540499275">"Fino a <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (prossima sveglia)"</string>
@@ -1980,7 +1984,7 @@
<string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Salva per Compilazione automatica"</string>
<string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Impossibile compilare automaticamente i contenuti"</string>
<string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Nessun suggerimento di Compilazione automatica"</string>
- <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{Un suggerimento di compilazione automatica}one{# suggerimento di compilazione automatica}other{# suggerimenti di compilazione automatica}}"</string>
+ <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{Un suggerimento di compilazione automatica}other{# suggerimenti di compilazione automatica}}"</string>
<string name="autofill_save_title" msgid="7719802414283739775">"Vuoi salvare su "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_type" msgid="3002460014579799605">"Vuoi salvare la <xliff:g id="TYPE">%1$s</xliff:g> su "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Vuoi salvare <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> su "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DISINSTALLA"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"APRI COMUNQUE"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"App dannosa rilevata"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Richiesta di accesso al log di sistema"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Consentire all\'app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> di accedere a tutti i log del dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Solo questa volta"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Non consentire"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> richiede i log di sistema per eseguire debug funzionali. Questi log potrebbero contenere informazioni scritte dalle app e dai servizi sul tuo dispositivo."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"I log del dispositivo registrano tutto ciò che succede sul tuo dispositivo. Le app possono usare i log per individuare problemi e correggerli.\n\nAlcuni log potrebbero contenere informazioni sensibili, quindi concedi l\'accesso ai log del dispositivo soltanto alle app attendibili. \n\nSe le neghi l\'accesso a tutti i log del dispositivo, l\'app può comunque accedere ai propri log e il produttore del tuo dispositivo potrebbe essere ancora in grado di accedere ad alcuni log o informazioni sul dispositivo. Scopri di più"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Non mostrare più"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"L\'app <xliff:g id="APP_0">%1$s</xliff:g> vuole mostrare porzioni dell\'app <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Modifica"</string>
@@ -2086,7 +2090,7 @@
<string name="mime_type_presentation_ext" msgid="8761049335564371468">"Presentazione <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Il Bluetooth rimane attivo durante l\'uso della modalità aereo"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"Caricamento"</string>
- <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # file}one{{file_name} + # file}other{{file_name} + # file}}"</string>
+ <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # file}other{{file_name} + # file}}"</string>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nessuna persona consigliata per la condivisione"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Elenco di app"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"A questa app non è stata concessa l\'autorizzazione di registrazione, ma l\'app potrebbe acquisire l\'audio tramite questo dispositivo USB."</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> è in esecuzione in background da molto tempo. Tocca per controllare."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verifica le app attive"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Impossibile accedere alla fotocamera da questo dispositivo"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 17f455d..8646830 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -87,8 +87,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"השירות הושבת באופן זמני על ידי הספק עבור SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"לא ניתן להתחבר לרשת הסלולרית"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"אפשר לנסות לשנות את הרשת המועדפת. יש להקיש כדי לשנות אותה."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"שיחות חירום לא זמינות"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"לא ניתן לבצע שיחות חירום דרך Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"יכול להיות ששיחות חירום לא יהיו זמינות"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"ב‑<xliff:g id="SPN">%s</xliff:g> אין תמיכה בשיחות חירום באמצעות Wi‑Fi. יש להקיש לקבלת פרטים."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"התראות"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"העברת שיחות"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"מצב \'התקשרות חזרה בחירום\'"</string>
@@ -427,10 +427,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"מאפשרת לאפליקציה לשנות את יומן השיחות של הטאבלט, כולל נתונים על שיחות נכנסות ויוצאות. אפליקציות זדוניות עלולות לעשות בכך שימוש כדי למחוק או לשנות את יומן השיחות שלך."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"מאפשרת לאפליקציה לשנות את יומן השיחות של מכשיר ה-Android TV, כולל נתונים על שיחות נכנסות ויוצאות. אפליקציות זדוניות עלולות להשתמש בכך כדי למחוק או לשנות את יומן השיחות."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"מאפשרת לאפליקציה לשנות את יומן השיחות של הטלפון, כולל נתונים על שיחות נכנסות ויוצאות. אפליקציות זדוניות עלולות לעשות בכך שימוש כדי למחוק או לשנות את יומן השיחות שלך."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"גישה אל חיישני גוף (כמו מוניטורים לקצב לב)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"גישה לנתונים מחיישנים גופניים כמו דופק, חום גוף, שיעור החמצן בדם ועוד."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"גישה לחיישנים גופניים (כמו מוניטורים למדידת דופק) תוך כדי פעילות ברקע"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"גישה לנתונים מחיישנים גופניים, כמו דופק, חום גוף, שיעור החמצן בדם, תוך כדי פעילות ברקע."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"גישה לנתונים של חיישנים גופניים, כמו דופק, כשנעשה שימוש באפליקציה"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ההרשאה מאפשרת לאפליקציה לגשת לנתונים של חיישנים גופניים, כמו דופק, חום גוף ושיעור החמצן בדם, כשנעשה שימוש באפליקציה."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"גישה לנתונים של חיישנים גופניים, כמו דופק, כשהאפליקציה פועלת ברקע"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ההרשאה מאפשרת לאפליקציה לגשת לנתונים של חיישנים גופניים, כמו דופק, חום גוף ושיעור החמצן בדם, כשהאפליקציה פועלת ברקע."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"קריאה של אירועי יומן והפרטים שלהם"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"האפליקציה הזו יכולה לקרוא את כל אירועי היומן המאוחסנים בטאבלט, ולשתף או לשמור את נתוני היומן."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"האפליקציה הזו יכולה לקרוא את כל אירועי היומן המאוחסנים במכשיר ה-Android TV, ולשתף או לשמור את נתוני היומן."</string>
@@ -691,8 +691,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"מאפשרת לאפליקציה לקרוא קובצי אודיו מתוך האחסון המשותף."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"קריאה של קובצי וידאו מתוך האחסון המשותף"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"מאפשרת לאפליקציה לקרוא קובצי וידאו מתוך האחסון המשותף."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"קריאה של קובצי תמונה מתוך האחסון המשותף"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"מאפשרת לאפליקציה לקרוא קובצי תמונה מתוך האחסון המשותף."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"קריאה של קובצי תמונה מתוך האחסון המשותף"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"מאפשרת לאפליקציה לקרוא קובצי תמונה מתוך האחסון המשותף."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"שינוי או מחיקה של תוכן האחסון המשותף שלך"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"מאפשרת לאפליקציה לכתוב את התוכן של האחסון המשותף."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"ביצוע/קבלה של שיחות SIP"</string>
@@ -914,7 +914,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"יש ללחוץ על \'תפריט\' כדי לבטל את הנעילה או כדי לבצע שיחת חירום."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"יש ללחוץ על \'תפריט\' כדי לבטל את הנעילה."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"יש לשרטט קו לביטול נעילת המסך"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"שיחת חירום"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"חירום"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"חזרה לשיחה"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"נכון!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"כדאי לנסות שוב"</string>
@@ -1053,7 +1053,6 @@
<string name="save_password_never" msgid="6776808375903410659">"אף פעם"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"אין לך הרשאה לפתוח את הדף הזה."</string>
<string name="text_copied" msgid="2531420577879738860">"הטקסט הועתק ללוח."</string>
- <string name="copied" msgid="4675902854553014676">"ההעתקה בוצעה"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"האפליקציה <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> הודבקה מ-<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"אפליקציית <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ביצעה הדבקה מהלוח"</string>
<string name="pasted_text" msgid="4298871641549173733">"טקסט שהעתקת הודבק על ידי <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
@@ -1454,8 +1453,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"מאפשרת לאפליקציה לבקש רשות להתעלם מאופטימיזציות של הסוללה לאפליקציה הזו."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"שליחת שאילתות לכל החבילות"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"מאפשרת לאפליקציה לראות את כל החבילות המותקנות."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"גישה אל SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"מאפשרת לאפליקציה לגשת אל SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"גישה לממשק ה‑API של \'נושאים\' ב‑AdServices"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"מאפשרת לאפליקציה לגשת לממשק ה‑API של \'נושאים\' ב‑AdServices."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"גישה לממשקי ה‑API של \'שיוך\' (Attribution) ב‑AdServices"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"מאפשרת לאפליקציה לגשת לממשקי ה‑API של \'שיוך\' (Attribution) ב‑AdServices."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"גישה לממשק ה‑API של \'קהלים בהתאמה אישית\' ב‑AdServices"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"מאפשרת לאפליקציה לגשת לממשק ה‑API של \'קהלים בהתאמה אישית\' ב‑AdServices."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"יש להקיש פעמיים לשינוי המרחק מהתצוגה"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"לא ניתן להוסיף widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"התחלה"</string>
@@ -1718,6 +1721,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"מעבר אל <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"מתבצע ניתוק של <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"בעלים"</string>
+ <string name="guest_name" msgid="8502103277839834324">"אורח/ת"</string>
<string name="error_message_title" msgid="4082495589294631966">"שגיאה"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"מנהל המערכת שלך לא מאפשר את השינוי הזה"</string>
<string name="app_not_found" msgid="3429506115332341800">"לא נמצאה אפליקציה שתומכת בפעולה הזו"</string>
@@ -2029,10 +2033,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"הסרת התקנה"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"לפתוח בכל זאת"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"אותרה אפליקציה מזיקה"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"בקשת גישה ליומן מערכת"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"לתת לאפליקציה <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> הרשאת גישה לכל יומני המכשיר?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"רק הפעם"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"אין אישור"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"האפליקציה <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> מבקשת יומני מערכת לצורך ניפוי באגים פונקציונלי. יכול להיות שהיומנים האלה מכילים מידע שנכתב על ידי אפליקציות ושירותים שבמכשיר שלך."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"ביומני המכשיר מתועדת הפעילות במכשיר. האפליקציות יכולות להשתמש ביומנים האלה כדי למצוא בעיות ולפתור אותן.\n\nהמידע בחלק מהיומנים יכול להיות רגיש, לכן יש לתת הרשאת גישה לכל יומני המכשיר רק לאפליקציות מהימנות. \n\nגם אם האפליקציה הזו לא תקבל הרשאת גישה לכל יומני המכשיר, היא תוכל לגשת ליומנים שלה, ויכול להיות שליצרן המכשיר עדיין תהיה גישה לחלק מהיומנים או למידע במכשיר שלך. מידע נוסף"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"אין להציג שוב"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> רוצה להציג חלקים מ-<xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"עריכה"</string>
@@ -2267,4 +2271,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> פועלת ברקע במשך הרבה זמן. יש להקיש כדי לבדוק."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"כדאי לבדוק את האפליקציות הפעילות"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"לא ניתן לגשת למצלמה מהמכשיר הזה"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 0862df1..c72ff34 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> は携帯通信会社によって一時的に OFF になっています"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"モバイル ネットワークにアクセスできません"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"タップして、優先ネットワークを変更してください。"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"緊急通報は利用できません"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi‑Fi では緊急通報ができません"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"緊急通報が利用できない可能性があります"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> は Wi-Fi 経由の緊急通報をサポートしていません。タップして詳細をご確認ください。"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"通知"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"電話の転送"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"緊急通報待機モード"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"タブレットの通話履歴(着信や発信のデータなど)の変更をアプリに許可します。この許可を悪意のあるアプリに利用されると、通話履歴が消去または変更される恐れがあります。"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Android TV デバイスの通話履歴(着信や発信のデータなど)の変更をアプリに許可します。この許可を悪意のあるアプリに利用されると、通話履歴が消去または変更される恐れがあります。"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"モバイル デバイスの通話履歴(着信や発信のデータなど)の変更をアプリに許可します。この許可を悪意のあるアプリに利用されると、通話履歴が消去または変更される恐れがあります。"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"ボディーセンサー(心拍数モニターなど)へのアクセス"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"心拍数、体温、血液中の酸素の割合などのボディセンサー データにアクセスする権限です。"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"ボディセンサー(心拍数モニター)のデータへのバックグラウンドでのアクセス権限"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"心拍数、体温、血液中の酸素の割合などのボディセンサー データにバックグラウンドでアクセスする権限です。"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"使用時の、心拍数などのボディセンサー データへのアクセス"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"アプリの使用時に、心拍数、体温、血中酸素濃度など、ボディセンサー データにアクセスすることをアプリに許可します。"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"バックグラウンド動作時の、心拍数などのボディセンサー データへのアクセス"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"バックグラウンドでのアプリの動作時に、心拍数、体温、血中酸素濃度など、ボディセンサー データにアクセスすることをアプリに許可します。"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"カレンダーの予定と詳細を読み取り"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"このアプリは、お使いのタブレットに保存されたカレンダーの予定をすべて読み取り、カレンダーのデータを共有したり、保存したりできます。"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"このアプリは、Android TV デバイスに保存されているカレンダーの予定をすべて読み取り、カレンダーのデータを共有したり、保存したりできます。"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"共有ストレージからの音声ファイルの読み取りをアプリに許可します。"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"共有ストレージからの動画ファイルの読み取り"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"共有ストレージからの動画ファイルの読み取りをアプリに許可します。"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"共有ストレージからの画像ファイルの読み取り"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"共有ストレージからの画像ファイルの読み取りをアプリに許可します。"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"共有ストレージからの画像ファイルの読み取り"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"共有ストレージからの画像ファイルの読み取りをアプリに許可します。"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"共有ストレージのコンテンツの変更または削除"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"共有ストレージのコンテンツの書き込みをアプリに許可します。"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP通話の発着信"</string>
@@ -834,7 +834,7 @@
<string name="phoneTypeFaxHome" msgid="6678559953115904345">"FAX(自宅)"</string>
<string name="phoneTypePager" msgid="576402072263522767">"ポケベル"</string>
<string name="phoneTypeOther" msgid="6918196243648754715">"その他"</string>
- <string name="phoneTypeCallback" msgid="3455781500844157767">"コールバック"</string>
+ <string name="phoneTypeCallback" msgid="3455781500844157767">"かけ直す"</string>
<string name="phoneTypeCar" msgid="4604775148963129195">"クルマ"</string>
<string name="phoneTypeCompanyMain" msgid="4482773154536455441">"会社代表番号"</string>
<string name="phoneTypeIsdn" msgid="2496238954533998512">"ISDN"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"MENUキーでロック解除(または緊急通報)"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"MENUキーでロック解除"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"パターンを入力"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"緊急通報"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"緊急通報"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"通話に戻る"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"一致しました"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"もう一度お試しください"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"保存しない"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"このページへのアクセスは許可されていません。"</string>
<string name="text_copied" msgid="2531420577879738860">"テキストをクリップボードにコピーしました。"</string>
- <string name="copied" msgid="4675902854553014676">"コピーしました"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> から <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> に貼り付けました"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> にクリップボードから貼り付けました"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> がクリップボード内のテキストを貼り付けました"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"電池の最適化の無視についてアプリが確認することを許可します。"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"すべてのパッケージを照会する"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"すべてのインストール済みパッケージを参照することをアプリに許可します。"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis へのアクセス"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"SupplementalApis へのアクセスをアプリに許可します。"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API へのアクセス"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"AdServices Topics API へのアクセスをアプリに許可します。"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API へのアクセス"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"AdServices Attribution API へのアクセスをアプリに許可します。"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API へのアクセス"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"AdServices Custom Audiences API へのアクセスをアプリに許可します。"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ダブルタップでズームします"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ウィジェットを追加できませんでした。"</string>
<string name="ime_action_go" msgid="5536744546326495436">"移動"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>に切り替えています…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> をログアウトしています…"</string>
<string name="owner_name" msgid="8713560351570795743">"所有者"</string>
+ <string name="guest_name" msgid="8502103277839834324">"ゲスト"</string>
<string name="error_message_title" msgid="4082495589294631966">"エラー"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"この変更は管理者によって許可されていません"</string>
<string name="app_not_found" msgid="3429506115332341800">"この操作を行うアプリが見つかりません"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"アンインストール"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"開く"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"有害なアプリが検出されました"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"システムログへのアクセスのリクエスト"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> にすべてのデバイスログへのアクセスを許可しますか?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"今回のみ"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"許可しない"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> が機能デバッグのためにシステムログをリクエストしています。これらのログには、デバイス上のアプリやサービスが書き込んだ情報が含まれている可能性があります。"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"デバイスのログに、このデバイスで発生したことが記録されます。アプリは問題を検出、修正するためにこれらのログを使用することができます。\n\nログによっては機密性の高い情報が含まれている可能性があるため、すべてのデバイスログへのアクセスは信頼できるアプリにのみ許可してください。\n\nすべてのデバイスログへのアクセスをこのアプリに許可しなかった場合も、このアプリはアプリ独自のログにアクセスできます。また、デバイスのメーカーもデバイスの一部のログや情報にアクセスできる可能性があります。詳細"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"次回から表示しない"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"「<xliff:g id="APP_0">%1$s</xliff:g>」が「<xliff:g id="APP_2">%2$s</xliff:g>」のスライスの表示をリクエストしています"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"編集"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> がバックグラウンドで長時間実行されています。タップしてご確認ください。"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"有効なアプリをチェック"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"このデバイスからはカメラにアクセスできません"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index f0b2f34..ec80e5b 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"დროებით გამორთულია თქვენი ოპერატორის მიერ SIM-ისთვის (<xliff:g id="SIMNUMBER">%d</xliff:g>)"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"მობილურ ქსელთან დაკავშირება ვერ ხერხდება"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ცადეთ უპირატესი ქსელის შეცვლა. შეეხეთ შესაცვლელად."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"გადაუდებელი ზარი მიუწვდომელია"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"გადაუდებელი ზარები Wi‑Fi-ს მეშვეობით ვერ განხორციელდება"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"გადაუდებელი ზარები შეიძლება მიუწვდომელი იყოს"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> არ აქვს გადაუდებელი ზარების მხარდაჭერა Wi-Fi-ით. შეეხეთ დეტალების სანახავად."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"გაფრთხილებები"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"ზარის გადამისამართება"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"გადაუდებელი გადმორეკვის რეჟიმი"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"აპს შეეძლება, შეცვალოს თქვენი ტაბლეტის ზარების ჟურნალი, მათ შორის შემომავალი და გამავალი ზარების მონაცემები. მავნე აპებმა შეიძლება გამოიყენონ ეს თქვენი ზარების ჟურნალის წასაშლელად ან შესაცვლელად."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ნებას რთავს აპს, შეცვალოს თქვენს Android TV მოწყობილობაზე ზარების ჟურნალი, შემომავალი და გამავალი ზარების მონაცემთა ჩათვლით. მავნე აპებს შეუძლიათ, ამის მეშვეობით, ამოშალონ ან შეცვალონ თქვენი ზარების ჟურნალი."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"აპს შეეძლება, შეცვალოს თქვენი ტელეფონის ზარების ჟურნალი, მათ შორის შემომავალი და გამავალი ზარების მონაცემები. მავნე აპებმა შეიძლება გამოიყენონ ეს თქვენი ზარების ჟურნალის წასაშლელად ან შესაცვლელად."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"სხეულის სენსორებზე წვდომა (მაგ., გულისცემის მონიტორები)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"წვდომა სხეულის ისეთ სენსორებზე, როგორიცაა გულისცემის სიხშირე, ტემპერატურა, სისხლში ჟანგბადის პროცენტული შემცველობა და ა.შ."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"სხეულის სენსორებზე წვდომა (მაგ., გულისცემის სიხშ. მონ.) ფონურ რეჟიმში მუშაობისას"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"წვდომა სხეულის ისეთ სენსორებზე, როგორიცაა გულისცემის სიხშირე, ტემპერატურა, სისხლში ჟანგბადის პროცენტული შემცველობა და ა.შ. ფონურ რეჟიმში მუშაობისას."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"აპის გამოყენებისას სხეულის სენსორების მონაცემებზე წვდომა, როგორიცაა გულისცემა"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"საშუალებას აძლევს აპს, მისი გამოყენებისას, წვდომა ჰქონდეს სხეულის სენსორების მონაცემებზე, როგორიცაა გულისცემა, ტემპერატურა და სისხლში ჟანგბადის პროცენტული შემცველობა."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"აპის ფონურ რეჟიმში მუშაობისას, სხეულის სენსორების მონაცემებზე წვდომა, როგორიცაა გულისცემა"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"საშუალებას აძლევს აპს, ფონურ რეჟიმში მუშაობისას, წვდომა ჰქონდეს სხეულის სენსორების მონაცემებზე, როგორიცაა გულისცემა, ტემპერატურა და სისხლში ჟანგბადის პროცენტული შემცველობა."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"კალენდრის მოვლენებისა და დეტალების წაკითხვა"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ამ აპს შეუძლია თქვენს ტაბლეტში შენახული კალენდრის ყველა მოვლენის წაკითხვა და თქვენი კალენდრის მონაცემების გაზიარება ან შენახვა."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ამ აპს შეუძლია თქვენს Android TV მოწყობილობაზე შენახული კალენდრის ყველა მოვლენის წაკითხვა და თქვენი კალენდრის მონაცემების გაზიარება ან შენახვა."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"საშუალებას აძლევს აპს, წაიკითხოს აუდიო ფაილები თქვენი ზიარი მეხსიერებიდან."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"ვიდეო ფაილების წაკითხვა ზიარი მეხსიერებიდან"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"საშუალებას აძლევს აპს, წაიკითხოს ვიდეო ფაილები თქვენი ზიარი მეხსიერებიდან."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"სურათების ფაილების წაკითხვა ზიარი მეხსიერებიდან"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"საშუალებას აძლევს აპს, წაიკითხოს სურათის ფაილები თქვენი ზიარი მეხსიერებიდან."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"სურათების ფაილების წაკითხვა ზიარი მეხსიერებიდან"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"საშუალებას აძლევს აპს, წაიკითხოს სურათის ფაილები თქვენი ზიარი მეხსიერებიდან."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"თქვენი ზიარი მეხსიერების შიგთავსის შეცვლა ან წაშლა"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"საშუალებას აძლევს აპს, ჩაწეროს თქვენი ზიარი მეხსიერების შიგთავსი."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP ზარების წამოწყება/მიღება"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"განბლოკვისთვის ან გადაუდებელი ზარისთვის დააჭირეთ მენიუს."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"განბლოკვისთვის დააჭირეთ მენიუს."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"განსაბლოკად დახატეთ ნიმუში"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"გადაუდებელი ზარი"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"საგანგებო სამსახურები"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"ზარზე დაბრუნება"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"სწორია!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"კიდევ სცადეთ"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"არასოდეს"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"ამ გვერდის გახსნის უფლება არ გაქვთ."</string>
<string name="text_copied" msgid="2531420577879738860">"ტექსტი დაკოპირებულია გაცვლის ბუფერში."</string>
- <string name="copied" msgid="4675902854553014676">"დაკოპირდა"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-დან <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>-ში ჩასმული"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-მა ჩასვა ტექსტი თქვენი გაცვლის ბუფერიდან"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-მ(ა) ჩასვა თქვენ მიერ დაკოპირებული ტექსტი"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"საშუალებას მისცემს აპს, მოითხოვოს მასთან დაკავშირებული ბატარეის ოპტიმიზაციის იგნორირების ნებართვა."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"ყველა პაკეტის მოთხოვნა"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"საშუალებას აძლევს აპს, ნახოს ყველა ინსტალირებული პაკეტი."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis-ზე წვდომა"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"აპლიკაციას SupplementalApis-ზე წვდომის საშუალებას აძლევს."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"წვდომა AdServices Topics API-ებზე"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"აპლიკაციას აძლევს წვდომას AdServices Topics API-ებზე."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"წვდომა AdServices Attribution API-ებზე"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"აპლიკაციას აძლევს წვდომას AdServices Attribution API-ებზე."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"წვდომა AdServices Custom Audiences API-ებზე"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"აპლიკაციას აძლევს წვდომას AdServices Custom Audiences API-ებზე."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"მასშტაბის ცვლილებისთვის შეეხეთ ორჯერ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ვერ დაემატა ვიჯეტი."</string>
<string name="ime_action_go" msgid="5536744546326495436">"გადასვლა"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>-ზე გადართვა…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>-ის ანგარიშიდან გასვლა…"</string>
<string name="owner_name" msgid="8713560351570795743">"მფლობელი"</string>
+ <string name="guest_name" msgid="8502103277839834324">"სტუმარი"</string>
<string name="error_message_title" msgid="4082495589294631966">"შეცდომა"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ეს ცვლილება თქვენი ადმინისტრატორის მიერ ნებადართული არ არის"</string>
<string name="app_not_found" msgid="3429506115332341800">"ამ მოქმედების შესასრულებლად აპლიკაცია ვერ მოიძებნა"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"დეინსტალაცია"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"მაინც გახსნა"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"აღმოჩენილია საზიანო აპი"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"სისტემის ჟურნალში წვდომის მოთხოვნა"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"გსურთ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>-ს მიანიჭოთ მოწყობილობის ყველა ჟურნალზე წვდომა?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"მხოლოდ ამ ერთხელ"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"არ დაიშვას"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ითხოვს სისტემის ჟურნალებს ფუნქციური გამართვისთვის. ეს ჟურნალები შეიძლება შეიცავდეს ინფორმაციას, რომელიც დაწერილია თქვენს მოწყობილობაზე არსებულ აპებსა და სერვისებზე."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"მოწყობილობის ჟურნალში იწერება, რა ხდება ამ მოწყობილობაზე. აპებს შეუძლია ამ ჟურნალების გამოყენება პრობლემების აღმოსაჩენად და მოსაგვარებლად.\n\nზოგი ჟურნალი შეიძლება სენსიტიური ინფორმაციის მატარებელი იყოს, ამიტომაც მოწყობილობის ყველა ჟურნალზე წვდომა მხოლოდ სანდო აპებს მიანიჭეთ. \n\nთუ ამ აპს მოწყობილობის ყველა ჟურნალზე წვდომას არ მიანიჭებთ, მას მაინც ექნება წვდომა თქვენს ჟურნალებზე და თქვენი მოწყობილობის მწარმოებელს მაინც შეეძლება თქვენი მოწყობილობის ზოგიერთ ჟურნალსა თუ ინფორმაციაზე წვდომა. შეიტყვეთ მეტი"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"აღარ გამოჩნდეს"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>-ს სურს, გაჩვენოთ <xliff:g id="APP_2">%2$s</xliff:g>-ის ფრაგმენტები"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"რედაქტირება"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ფონურ რეჟიმში დიდი ხანია გაშვებულია. შეეხეთ გადასახედად."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"აქტიური აპების შემოწმება"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"კამერაზე წვდომა ამ მოწყობილობიდან ვერ მოხერხდება"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 6f4b66a..2405664 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Оператор SIM <xliff:g id="SIMNUMBER">%d</xliff:g> картасы үшін уақытша өшірді"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобильдік желіге қосылу мүмкін емес"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Таңдаулы желіні өзгертіп көріңіз. Өзгерту үшін түртіңіз."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Жедел қызметке қоңырау шалу мүмкін емес"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi-Fi арқылы жедел қызметке қоңырау шалу мүмкін емес"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Құтқару қызметіне қоңырау шалу қолжетімсіз болуы мүмкін"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> операторында Wi-Fi арқылы құтқару қызметіне қоңырау шалу қарастырылмаған. Мәлімет алу үшін түртіңіз."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Дабылдар"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Қоңырауды басқа нөмірге бағыттау"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Шұғыл кері қоңырау шалу режимі"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Қолданбаға сіздің планшетіңіздегі қоңырау тіркеуін, келетін немесе шығатын қоңыраулар туралы деректерді қоса, өзгерту мүмкіндігін береді. Залалды қолданбалар бұны сіздің қоңырау тіркеуіңізді өшіру үшін қолдануы мүмкін."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Қолданба Android TV құрылғысының қоңыраулар журналын, сонымен қатар кіріс және шығыс қоңыраулар туралы деректерді өзгерте алатын болады. Қоңыраулар журналын деректерден тазарту немесе оны өзгерту үшін зиянды қолданбалар осы рұқсатты пайдалануы мүмкін."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Қолданбаға сіздің телефоныңыздың қоңырау тіркеуін, келетін немесе шығатын қоңыраулар туралы деректерді қоса, өзгерту мүмкіндігін береді. Залалды қолданбалар бұны сіздің қоңырау тіркеуіңізді өшіру үшін қолдануы мүмкін."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"дене датчиктеріне (мысалы, жүрек соғу жиілігінің мониторларына) қатынасу"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Жүрек қағысы, температура, қандағы оттегі пайызы және т.б. сияқты дене датчиктерінен алынған деректерді пайдалану."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"дене датчиктерін (мысалы, жүрек қағысын өлшегіштерді) фондық режимде пайдалану"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Жүрек қағысы, температура, қандағы оттегі пайызы және т.б. сияқты дене датчиктерінен алынған деректерді фондық режимде пайдалану."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Жұмыс кезінде дене датчигінен алынған жүрек қағысы сияқты деректі пайдалану"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Жұмыс кезінде қолданбаға дене датчигінен алынған жүрек қағысы, температура, қандағы оттегі пайызы сияқты деректі пайдалануға рұқсат береді."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Фондық режимде дене датчигінен алынған жүрек қағысы сияқты деректі пайдалану"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Фондық режимде қолданбаға дене датчигінен алынған жүрек қағысы, температура, қандағы оттегі пайызы сияқты деректі пайдалануға рұқсат береді."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Күнтізбе оқиғалары мен мәліметтерін оқу"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Бұл қолданба планшетте сақталған барлық күнтізбе оқиғаларын оқи алады және күнтізбе деректерін бөлісе не сақтай алады."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Бұл қолданба Android TV құрылғыңызда сақталған барлық күнтізбе оқиғаларын оқи алады және күнтізбе деректерін бөлісе не сақтай алады."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Қолданбаға ортақ жадтың аудиофайлдарын оқуға мүмкіндік береді."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"ортақ жадтың бейнефайлдарын оқу"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Қолданбаға ортақ жадтың бейнефайлдарын оқуға мүмкіндік береді."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"ортақ жадтың кескін файлдарын оқу"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Қолданбаға ортақ жадтың кескін файлдарын оқуға мүмкіндік береді."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"ортақ жадтың кескін файлдарын оқу"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Қолданбаға ортақ жадтың кескін файлдарын оқуға мүмкіндік береді."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"ортақ жадтың мазмұнын өзгерту немесе жою"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Қолданбаға ортақ жадтың мазмұнын жазуға мүмкіндік береді."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP қоңырауларын шалу/қабылдау"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Бекітпесін ашу үшін немесе төтенше қоңырауды табу үшін Мәзір тармағын басыңыз."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Ашу үшін Мәзір пернесін басыңыз."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Бекітпесін ашу үшін кескінді сызыңыз"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Құтқару қызметіне қоңырау шалу"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Төтенше жағдай"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Қоңырауға оралу"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Дұрыс!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Қайталап көріңіз"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Ешқашан"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Сізде осы бетті ашуға рұқсат жоқ."</string>
<string name="text_copied" msgid="2531420577879738860">"Мәтін ақпарат алмастыру қорына сақталды."</string>
- <string name="copied" msgid="4675902854553014676">"Көшірілді"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> қолданбасынан <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> қолданбасына қойылды."</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> қолданбасы буферіңізден алынған деректерді қойды."</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> сіз көшірген мәтінді қойды."</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Қолданба батареяны оңтайландыру әрекетін елемеуді сұрай алады."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"барлық бумаға сұрау жасау"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Қолданба барлық орнатылған буманы көре алады."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApi интерфейстерін пайдалану"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Қолданбаға SupplementalApi интерфейстерін пайдалануға мүмкіндік береді."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API-ын пайдалану"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Қолданбаға AdServices Topics API-ын пайдалануға мүмкіндік береді."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API-ларын пайдалану"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Қолданбаға AdServices Attribution API-ларын пайдалануға мүмкіндік береді."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API-ын пайдалану"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Қолданбаға AdServices Custom Audiences API-ын пайдалануға мүмкіндік береді."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Масштабтау параметрін басқару үшін екі рет түртіңіз"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Виджетті қосу."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Өту"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> профиліне ауысу…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> ішінен шығу…"</string>
<string name="owner_name" msgid="8713560351570795743">"Құрылғы иесі"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Қонақ"</string>
<string name="error_message_title" msgid="4082495589294631966">"Қателік"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Бұл өзгертуге әкімші рұқсат етпеген"</string>
<string name="app_not_found" msgid="3429506115332341800">"Бұл әрекетті орындайтын қолданба табылмады"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ЖОЮ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"БӘРІБІР АШУ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Зиянды қолданба анықталды"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Жүйе журналын пайдалану рұқсатын сұрау"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> қолданбасына барлық құрылғының журналын пайдалануға рұқсат берілсін бе?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Тек осы жолы"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Рұқсат бермеу"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> қолданбасы функционалдық түзету үшін жүйе журналдарын сұрайды. Бұл журналдарда құрылғыңыздағы қолданбалар мен қызметтер енгізген ақпарат қамтылуы мүмкін."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Журналдарға құрылғыда не болып жатқаны жазылады. Қолданбалар осы журналдарды қате тауып, түзету үшін пайдаланады.\n\nКейбір журналдарда құпия ақпарат болуы мүмкін. Сондықтан барлық құрылғының журналын пайдалану рұқсаты тек сенімді қолданбаларға берілуі керек. \n\nБұл қолданбаға барлық құрылғының журналын пайдалануға рұқсат бермесеңіз де, ол өзінің журналдарын пайдалана береді. Сондай-ақ құрылғы өндірушісі де құрылғыдағы кейбір журналдарды немесе ақпаратты пайдалануы мүмкін. Толығырақ"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Қайта көрсетілмесін"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> қолданбасы <xliff:g id="APP_2">%2$s</xliff:g> қолданбасының үзінділерін көрсеткісі келеді"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Өзгерту"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> қолданбасы ұзақ уақыт бойы фондық режимде жұмыс істеуде. Көру үшін түртіңіз."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Белсенді қолданбаларды тексеру"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Бұл құрылғыдан камераны пайдалану мүмкін емес."</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 162b0f6..772205f 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"បិទដោយក្រុមហ៊ុនសេវាទូរសព្ទរបស់អ្នកជាបណ្តោះអាសន្ន សម្រាប់ស៊ីមទី <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"មិនអាចភ្ជាប់បណ្ដាញទូរសព្ទចល័តបានទេ"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"សាកល្បងប្ដូរទៅបណ្ដាញដែលចង់ប្រើ។ សូមចុចដើម្បីផ្លាស់ប្ដូរ។"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"មិនអាចប្រើការហៅបន្ទាន់បានទេ"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"មិនអាចធ្វើការហៅបន្ទាន់តាម Wi‑Fi បានទេ"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"ប្រហែលជាមិនអាចហៅទៅលេខសង្គ្រោះបន្ទាន់បានទេ"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> មិនអាចហៅទៅលេខសង្គ្រោះបន្ទាន់តាម Wi-Fi បានទេ។ សូមចុចដើម្បីទទួលបានព័ត៌មានលម្អិត។"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"ការជូនដំណឹង"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"ការបញ្ជូនការហៅទូរសព្ទបន្ត"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"មុខងារហៅត្រឡប់វិញបន្ទាន់"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ឲ្យកម្មវិធីកែបញ្ជីហៅកុំព្យូទ័របន្ទះរបស់អ្នករួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុប ឬកែបញ្ជីហៅរបស់អ្នក។"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"អនុញ្ញាតឱ្យកម្មវិធីកែកំណត់ហេតុហៅទូរសព្ទនៃឧបករណ៍ Android TV របស់អ្នក រួមទាំងទិន្នន័យអំពីការហៅចូល និងការហៅចេញផងដែរ។ កម្មវិធីគ្រោះថ្នាក់អាចប្រើការអនុញ្ញាតនេះ ដើម្បីលុប ឬកែកំណត់ហេតុហៅទូរសព្ទរបស់អ្នក។"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ឲ្យកម្មវិធីកែបញ្ជីហៅនៃទូរស័ព្ទរបស់អ្នក រួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។ កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុប ឬកែបញ្ជីការហៅរបស់អ្នក។"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"ចូលដំណើរការឧបករណ៍ចាប់សញ្ញារាងកាយ (ដូចជាម៉ាស៊ីនវាស់ចង្វាក់បេះដូង)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"សិទ្ធិចូលប្រើទិន្នន័យពីឧបករណ៍ចាប់សញ្ញារាងកាយដូចជា ចង្វាក់បេះដូង សីតុណ្ហភាព ភាគរយនៃអុកស៊ីសែនក្នុងឈាម។ល។"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"ចូលប្រើឧបករណ៍ចាប់សញ្ញារាងកាយ (ដូចជាឧបករណ៍វាស់ចង្វាក់បេះដូង) ខណៈពេលនៅផ្ទៃខាងក្រោយ"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"សិទ្ធិចូលប្រើទិន្នន័យពីឧបករណ៍ចាប់សញ្ញារាងកាយដូចជា ចង្វាក់បេះដូង សីតុណ្ហភាព ភាគរយនៃអុកស៊ីសែនក្នុងឈាម។ល។ ខណៈពេលនៅផ្ទៃខាងក្រោយ។"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ចូលប្រើទិន្នន័យឧបករណ៍ចាប់សញ្ញារាងកាយ ដូចជាចង្វាក់បេះដូងជាដើម ខណៈពេលកំពុងប្រើ"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"អនុញ្ញាតឱ្យកម្មវិធីចូលប្រើទិន្នន័យឧបករណ៍ចាប់សញ្ញារាងកាយ ដូចជាចង្វាក់បេះដូង សីតុណ្ហភាព និងភាគរយនៃអុកស៊ីសែនក្នុងឈាមជាដើម ខណៈពេលកំពុងប្រើកម្មវិធី។"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ចូលប្រើទិន្នន័យឧបករណ៍ចាប់សញ្ញារាងកាយ ដូចជាចង្វាក់បេះដូងជាដើម ខណៈពេលស្ថិតនៅផ្ទៃខាងក្រោយ"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"អនុញ្ញាតឱ្យកម្មវិធីចូលប្រើទិន្នន័យឧបករណ៍ចាប់សញ្ញារាងកាយ ដូចជាចង្វាក់បេះដូង សីតុណ្ហភាព និងភាគរយនៃអុកស៊ីសែនក្នុងឈាមជាដើម ខណៈពេលដែលកម្មវិធីស្ថិតនៅផ្ទៃខាងក្រោយ។"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"អានព្រឹត្តិការណ៍ប្រតិទិន និងព័ត៌មានលម្អិត"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"កម្មវិធីនេះអាចធ្វើការអានព្រឹត្តិការណ៍ប្រតិទិនទាំងអស់ ដែលផ្ទុកនៅលើថេប្លេតរបស់អ្នក និងចែករំលែក ឬរក្សាទុកទិន្នន័យប្រតិទិនរបស់អ្នក។"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"កម្មវិធីនេះអាចអានព្រឹត្តិការណ៍ក្នុងប្រតិទិនទាំងអស់ដែលបានរក្សាទុកនៅក្នុងឧបករណ៍ Android TV របស់អ្នក និងចែករំលែក ឬរក្សាទុកទិន្នន័យប្រតិទិនរបស់អ្នក។"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"អនុញ្ញាតឱ្យកម្មវិធីអានឯកសារសំឡេងពីទំហំផ្ទុករួមរបស់អ្នក។"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"អានឯកសារវីដេអូពីទំហំផ្ទុករួម"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"អនុញ្ញាតឱ្យកម្មវិធីអានឯកសារវីដេអូពីទំហំផ្ទុករួមរបស់អ្នក។"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"អានឯកសាររូបភាពពីទំហំផ្ទុករួម"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"អនុញ្ញាតឱ្យកម្មវិធីអានឯកសាររូបភាពពីទំហំផ្ទុករួមរបស់អ្នក។"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"អានឯកសាររូបភាពពីទំហំផ្ទុករួម"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"អនុញ្ញាតឱ្យកម្មវិធីអានឯកសាររូបភាពពីទំហំផ្ទុករួមរបស់អ្នក។"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"កែប្រែ ឬលុបខ្លឹមសារនៃទំហំផ្ទុករួមរបស់អ្នក"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"អនុញ្ញាតឱ្យកម្មវិធីសរសេរខ្លឹមសារនៃទំហំផ្ទុករួមរបស់អ្នក។"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"បង្កើត/ទទួល ការហៅ SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"ចុចម៉ឺនុយ ដើម្បីដោះសោ ឬហៅពេលអាសន្ន។"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"ចុចម៉ឺនុយ ដើម្បីដោះសោ។"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"គូរលំនាំ ដើម្បីដោះសោ"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"ហៅទៅលេខសង្គ្រោះបន្ទាន់"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"បន្ទាន់"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"ត្រឡប់ទៅការហៅ"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"ត្រឹមត្រូវ!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"ព្យាយាមម្ដងទៀត"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"កុំ"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"អ្នកមិនមានសិទ្ធិ ដើម្បីបើកទំព័រនេះ។"</string>
<string name="text_copied" msgid="2531420577879738860">"បានចម្លងអត្ថបទទៅក្ដារតម្បៀតខ្ទាស់។"</string>
- <string name="copied" msgid="4675902854553014676">"បានចម្លង"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូលពី <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"បានដាក់ចូល <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ពីឃ្លីបបតរបស់អ្នក"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> បានដាក់ចូលអត្ថបទដែលអ្នកបានចម្លង"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"អនុញ្ញាតឲ្យកម្មវិធីស្នើសុំការអនុញ្ញាត ដើម្បីមិនអើពើចំពោះការបង្កើនប្រសិទ្ធភាពថ្ម។"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"សួរសំណួរអំពីកញ្ចប់ទាំងអស់"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"អនុញ្ញាតឱ្យកម្មវិធីមើលកញ្ចប់ដែលបានដំឡើងទាំងអស់។"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"ចូលប្រើ SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"អនុញ្ញាតឱ្យកម្មវិធីចូលប្រើ SupplementalApis។"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"ចូលប្រើ AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"អនុញ្ញាតឱ្យកម្មវិធីចូលប្រើ AdServices Topics API។"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"ចូលប្រើ AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"អនុញ្ញាតឱ្យកម្មវិធីចូលប្រើ AdServices Attribution API។"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"ចូលប្រើ AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"អនុញ្ញាតឱ្យកម្មវិធីចូលប្រើ AdServices Custom Audiences API។"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ប៉ះ ពីរដងដើម្បីពិនិត្យការពង្រីក"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"មិនអាចបន្ថែមធាតុក្រាហ្វិក។"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ទៅ"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"កំពុងប្ដូរទៅ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"កំពុងចេញ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"ម្ចាស់"</string>
+ <string name="guest_name" msgid="8502103277839834324">"ភ្ញៀវ"</string>
<string name="error_message_title" msgid="4082495589294631966">"កំហុស"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ការផ្លាស់ប្ដូរនេះមិនត្រូវបានអនុញ្ញាតដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
<string name="app_not_found" msgid="3429506115332341800">"រកមិនឃើញកម្មវិធី ដើម្បីគ្រប់គ្រងសកម្មភាពនេះ"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"លុប"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"មិនអីទេ បើកចុះ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"បានរកឃើញកម្មវិធីដែលបង្កគ្រោះថ្នាក់"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"សំណើចូលប្រើកំណត់ហេតុប្រព័ន្ធ"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"អនុញ្ញាតឱ្យ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ចូលប្រើកំណត់ហេតុឧបករណ៍ទាំងអស់ឬ?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"តែពេលនេះប៉ុណ្ណោះ"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"មិនអនុញ្ញាត"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ស្នើសុំកំណត់ហេតុប្រព័ន្ធសម្រាប់ជួសជុលមុខងារ។ កំណត់ហេតុទាំងនេះប្រហែលជាមានព័ត៌មានដែលកម្មវិធី និងសេវាកម្មនៅលើឧបករណ៍របស់អ្នកបានសរសេរ។"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"កំណត់ហេតុឧបករណ៍កត់ត្រាអ្វីដែលកើតឡើងនៅលើឧបករណ៍របស់អ្នក។ កម្មវិធីអាចប្រើកំណត់ហេតុទាំងនេះដើម្បីស្វែងរក និងដោះស្រាយបញ្ហាបាន។\n\nកំណត់ហេតុមួយចំនួនអាចមានព័ត៌មានរសើប ដូច្នេះគួរអនុញ្ញាតឱ្យចូលប្រើកំណត់ហេតុឧបករណ៍ទាំងអស់សម្រាប់តែកម្មវិធីដែលអ្នកទុកចិត្តប៉ុណ្ណោះ។ \n\nប្រសិនបើអ្នកមិនអនុញ្ញាតឱ្យកម្មវិធីនេះចូលប្រើកំណត់ហេតុឧបករណ៍ទាំងអស់ទេ វានៅតែអាចចូលប្រើកំណត់ហេតុរបស់វាផ្ទាល់ ហើយក្រុមហ៊ុនផលិតឧបករណ៍របស់អ្នកប្រហែលជានៅតែអាចចូលប្រើកំណត់ហេតុ ឬព័ត៌មានមួយចំនួននៅលើឧបករណ៍របស់អ្នកបានដដែល។ ស្វែងយល់បន្ថែម"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"កុំបង្ហាញម្ដងទៀត"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ចង់បង្ហាញស្ថិតិប្រើប្រាស់របស់ <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"កែសម្រួល"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> កំពុងដំណើរការនៅផ្ទៃខាងក្រោយអស់រយៈពេលយូរហើយ។ សូមចុច ដើម្បីពិនិត្យមើល។"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ពិនិត្យមើលកម្មវិធីសកម្ម"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"មិនអាចចូលប្រើកាមេរ៉ាពីឧបករណ៍នេះបានទេ"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index d9b1fab..022d665 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"ಸಿಮ್ <xliff:g id="SIMNUMBER">%d</xliff:g> ಗಾಗಿ ನಿಮ್ಮ ವಾಹಕದ ಮೂಲಕ ತಾತ್ಕಾಲಿಕವಾಗಿ ಆಫ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ಮೊಬೈಲ್ ನೆಟ್ವರ್ಕ್ ತಲುಪಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ಆದ್ಯತೆಗೊಳಿಸಿದ ನೆಟ್ವರ್ಕ್ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಪ್ರಯತ್ನಿಸಿ. ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ತುರ್ತು ಕರೆ ಮಾಡುವಿಕೆ ಲಭ್ಯವಿಲ್ಲ"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"ವೈ-ಫೈ ಮೂಲಕ ತುರ್ತು ಕರೆಗಳನ್ನು ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"ತುರ್ತು ಕರೆಗಳು ಲಭ್ಯವಿಲ್ಲದಿರಬಹುದು"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"ವೈ-ಫೈ ಮೂಲಕ ತುರ್ತು ಕರೆಗಳನ್ನು <xliff:g id="SPN">%s</xliff:g> ಬೆಂಬಲಿಸುವುದಿಲ್ಲ. ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"ಎಚ್ಚರಿಕೆಗಳು"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"ಕರೆ ಫಾರ್ವರ್ಡ್ ಮಾಡುವಿಕೆ"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"ತುರ್ತು ಕಾಲ್ಬ್ಯಾಕ್ ಮೋಡ್"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ಒಳಬರುವ ಮತ್ತು ಹೊರಹೋಗುವ ಕರೆಗಳ ಕುರಿತ ಡೇಟಾ ಸೇರಿದಂತೆ, ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಅಳಿಸಲು ಅಥವಾ ಮಾರ್ಪಡಿಸಲು ಇದನ್ನು ಬಳಸಿಕೊಳ್ಳಬಹುದು."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ಒಳಬರುವ ಮತ್ತು ಹೊರಹೋಗುವ ಕರೆಗಳ ಕುರಿತ ಡೇಟಾ ಸೇರಿದಂತೆ ನಿಮ್ಮ Android TV ಸಾಧನದ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಅಳಿಸಲು ಅಥವಾ ಮಾರ್ಪಡಿಸಲು ಇದನ್ನು ಬಳಸಿಕೊಳ್ಳಬಹುದು."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ಒಳಬರುವ ಮತ್ತು ಹೊರಹೋಗುವ ಕರೆಗಳ ಕುರಿತ ಡೇಟಾ ಸೇರಿದಂತೆ, ನಿಮ್ಮ ಫೋನ್ನ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಅಳಿಸಲು ಅಥವಾ ಮಾರ್ಪಡಿಸಲು ಇದನ್ನು ಬಳಸಿಕೊಳ್ಳಬಹುದು."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"ದೇಹ ಸೆನ್ಸರ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ (ಹೃದಯದ ಬಡಿತ ಮಾನಿಟರ್ಗಳಂತಹ)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"ಹೃದಯ ಬಡಿತ, ತಾಪಮಾನ, ರಕ್ತದ ಆಮ್ಲಜನಕದ ಶೇಕಡಾವಾರು ಮುಂತಾದ ದೇಹದ ಸೆನ್ಸರ್ಗಳಿಂದ ಡೇಟಾಗೆ ಪ್ರವೇಶವನ್ನು ನೀಡುತ್ತದೆ."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"ಹಿನ್ನೆಲೆಯಲ್ಲಿರುವ ದೇಹದ ಸೆನ್ಸರ್ಗಳಿಗೆ (ಹೃದಯದ ಬಡಿತ ಮಾನಿಟರ್ಗಳು) ಪ್ರವೇಶ ನೀಡುತ್ತದೆ"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"ಹೃದಯ ಬಡಿತ, ತಾಪಮಾನ, ರಕ್ತದ ಆಮ್ಲಜನಕದ ಶೇಕಡಾವಾರು ಮುಂತಾದ ಹಿನ್ನೆಲೆಯಲ್ಲಿರುವ ದೇಹದ ಸೆನ್ಸರ್ಗಳಿಂದ ಡೇಟಾಗೆ ಪ್ರವೇಶವನ್ನು ನೀಡುತ್ತದೆ."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ಬಳಕೆಯಲ್ಲಿರುವಾಗ ಹೃದಯ ಬಡಿತದಂತಹ ದೇಹದ ಸೆನ್ಸರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿರುವಾಗ ಹೃದಯ ಬಡಿತ, ತಾಪಮಾನ ಮತ್ತು ರಕ್ತದ ಆಮ್ಲಜನಕದ ಶೇಕಡಾವಾರು ಎಂಬಂತಹ ದೇಹದ ಸೆನ್ಸರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ಹಿನ್ನಲೆಯಲ್ಲಿರುವಾಗ ಹೃದಯ ಬಡಿತದಂತಹ ದೇಹದ ಸೆನ್ಸರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ಆ್ಯಪ್ ಹಿನ್ನಲೆಯಲ್ಲಿರುವಾಗ ಹೃದಯ ಬಡಿತ, ತಾಪಮಾನ ಮತ್ತು ರಕ್ತದ ಆಮ್ಲಜನಕದ ಶೇಕಡಾವಾರು ಎಂಬಂತಹ ದೇಹದ ಸೆನ್ಸರ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್ಗಳು ಮತ್ತು ವಿವರಗಳನ್ನು ಓದಿ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಸಂಗ್ರಹವಾಗಿರುವ ಎಲ್ಲಾ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್ಗಳನ್ನು ಓದಬಹುದು ಮತ್ತು ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು ಅಥವಾ ಉಳಿಸಬಹುದು."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹವಾಗಿರುವ ಎಲ್ಲಾ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್ಗಳನ್ನು ಓದಬಹುದು ಮತ್ತು ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು ಅಥವಾ ಉಳಿಸಬಹುದು."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"ನಿಮ್ಮ ಹಂಚಿಕೊಂಡ ಸಂಗ್ರಹಣೆಯಿಂದ ಆಡಿಯೋ ಫೈಲ್ಗಳನ್ನು ಓದಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"ಹಂಚಿಕೊಂಡ ಸಂಗ್ರಹಣೆಯಿಂದ ವೀಡಿಯೊ ಫೈಲ್ಗಳನ್ನು ಓದಿ"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"ನಿಮ್ಮ ಹಂಚಿಕೊಂಡ ಸಂಗ್ರಹಣೆಯಿಂದ ವೀಡಿಯೊ ಫೈಲ್ಗಳನ್ನು ಓದಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"ಹಂಚಿಕೊಂಡ ಸಂಗ್ರಹಣೆಯಿಂದ ಚಿತ್ರದ ಫೈಲ್ಗಳನ್ನು ಓದಿ"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"ನಿಮ್ಮ ಹಂಚಿಕೊಂಡ ಸಂಗ್ರಹಣೆಯಿಂದ ಚಿತ್ರದ ಫೈಲ್ಗಳನ್ನು ಓದಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"ಹಂಚಿಕೊಂಡ ಸಂಗ್ರಹಣೆಯಿಂದ ಚಿತ್ರದ ಫೈಲ್ಗಳನ್ನು ಓದಿ"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"ನಿಮ್ಮ ಹಂಚಿಕೊಂಡ ಸಂಗ್ರಹಣೆಯಿಂದ ಚಿತ್ರದ ಫೈಲ್ಗಳನ್ನು ಓದಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"ನಿಮ್ಮ ಹಂಚಿಕೊಂಡ ಸಂಗ್ರಹಣೆಯ ವಿಷಯಗಳನ್ನು ಮಾರ್ಪಡಿಸಿ ಅಥವಾ ಅಳಿಸಿ"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"ನಿಮ್ಮ ಹಂಚಿಕೊಂಡ ಸಂಗ್ರಹಣೆಯ ವಿಷಯಗಳನ್ನು ಬರೆಯಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"ಎಸ್ಐಪಿ ಕರೆಗಳನ್ನು ಮಾಡಿ/ಸ್ವೀಕರಿಸಿ"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಮೆನು ಒತ್ತಿರಿ ಇಲ್ಲವೇ ತುರ್ತು ಕರೆಯನ್ನು ಮಾಡಿ."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಮೆನು ಒತ್ತಿರಿ."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಪ್ಯಾಟರ್ನ್ ಚಿತ್ರಿಸಿ"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"ತುರ್ತು ಕರೆ"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ತುರ್ತು"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"ಕರೆಗೆ ಹಿಂತಿರುಗು"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"ಸರಿಯಾಗಿದೆ!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"ಎಂದಿಗೂ ಬೇಡ"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"ಈ ಪುಟವನ್ನು ತೆರೆಯಲು ನೀವು ಅನುಮತಿಯನ್ನು ಹೊಂದಿಲ್ಲ."</string>
<string name="text_copied" msgid="2531420577879738860">"ಪಠ್ಯವನ್ನು ಕ್ಲಿಪ್ಬೋರ್ಡ್ಗೆ ನಕಲಿಸಲಾಗಿದೆ."</string>
- <string name="copied" msgid="4675902854553014676">"ನಕಲಿಸಲಾಗಿದೆ"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ಅನ್ನು <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ನಿಂದ ಅಂಟಿಸಲಾಗಿದೆ"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>, ನಿಮ್ಮ ಕ್ಲಿಪ್ಬೋರ್ಡ್ನಲ್ಲಿನ ಡೇಟಾವನ್ನು ಅಂಟಿಸಿದೆ"</string>
<string name="pasted_text" msgid="4298871641549173733">"ನೀವು ನಕಲಿಸಿರುವ ಪಠ್ಯವನ್ನು <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ನಿಂದ ಅಂಟಿಸಲಾಗಿದೆ"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ಈ ಅಪ್ಲಿಕೇಶನ್ಗೆ ಬ್ಯಾಟರಿ ಆಪ್ಟಿಮೈಸೇಶನ್ಗಳನ್ನು ಕಡೆಗಣಿಸುವುದಕ್ಕೆ ಅನುಮತಿಯನ್ನು ಕೇಳಲು ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"ಎಲ್ಲಾ ಪ್ಯಾಕೇಜ್ಗಳ ಕುರಿತಾದ ಮಾಹಿತಿಯನ್ನು ಕೇಳಿ"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿದ ಎಲ್ಲಾ ಪ್ಯಾಕೇಜ್ಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis ಅನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"SupplementalApis ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API ಅನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"AdServices Topics API ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution APIs ಅನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"AdServices Attribution APIs ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API ಅನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"AdServices Custom Audiences API ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ಝೂಮ್ ನಿಯಂತ್ರಿಸಲು ಎರಡು ಬಾರಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ವಿಜೆಟ್ ಸೇರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ."</string>
<string name="ime_action_go" msgid="5536744546326495436">"ಹೋಗು"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ಗೆ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರನ್ನು ಲಾಗ್ ಔಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
<string name="owner_name" msgid="8713560351570795743">"ಮಾಲೀಕರು"</string>
+ <string name="guest_name" msgid="8502103277839834324">"ಅತಿಥಿ"</string>
<string name="error_message_title" msgid="4082495589294631966">"ದೋಷ"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ಈ ಬದಲಾವಣೆಗೆ ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
<string name="app_not_found" msgid="3429506115332341800">"ಈ ಕ್ರಿಯೆಯನ್ನು ನಿರ್ವಹಿಸಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ ಕಂಡುಬಂದಿಲ್ಲ"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ಹೇಗಿದ್ದರೂ ತೆರೆಯಿರಿ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"ಅಪಾಯಕಾರಿ ಅಪ್ಲಿಕೇಶನ್ ಕಂಡುಬಂದಿದೆ"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"ಸಿಸ್ಟಂ ಲಾಗ್ ಪ್ರವೇಶ ವಿನಂತಿ"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"ಎಲ್ಲಾ ಸಾಧನದ ಲಾಗ್ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ಗೆ ಅನುಮತಿಸುವುದೇ?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"ಈ ಬಾರಿ ಮಾತ್ರ"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"ಅನುಮತಿಸಬೇಡಿ"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"ಫಂಕ್ಷನಲ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಗಾಗಿ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ಸಿಸ್ಟಂ ಲಾಗ್ಗಳನ್ನು ವಿನಂತಿಸುತ್ತದೆ. ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿನ ಆ್ಯಪ್ಗಳು ಮತ್ತು ಸೇವೆಗಳು ಬರೆದಿರುವ ಮಾಹಿತಿಯನ್ನು ಈ ಲಾಗ್ಗಳು ಒಳಗೊಂಡಿರಬಹುದು."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"ಸಾಧನವು ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿನ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಲಾಗ್ ಮಾಡುತ್ತದೆ ಸಮಸ್ಯೆಗಳನ್ನು ಪತ್ತೆಹಚ್ಚಲು ಮತ್ತು ಪರಿಹರಿಸಲು ಆ್ಯಪ್ಗಳು ಈ ಲಾಗ್ ಅನ್ನು ಬಳಸಬಹುದು.\n\nಕೆಲವು ಲಾಗ್ಗಳು ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರಬಹುದು, ಆದ್ದರಿಂದ ನಿಮ್ಮ ವಿಶ್ವಾಸಾರ್ಹ ಆ್ಯಪ್ಗಳಿಗೆ ಮಾತ್ರ ಸಾಧನದ ಎಲ್ಲಾ ಲಾಗ್ಗಳಿಗೆ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಅನುಮತಿಸಿ. \n\nಎಲ್ಲಾ ಸಾಧನ ಲಾಗ್ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ನೀವು ಈ ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸದಿದ್ದರೆ, ಅದು ಇನ್ನೂ ತನ್ನದೇ ಆದ ಲಾಗ್ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಬಹುದು ಮತ್ತು ನಿಮ್ಮ ಸಾಧನ ತಯಾರಕರು ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಕೆಲವು ಲಾಗ್ಗಳು ಅಥವಾ ಮಾಹಿತಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಈಗಲೂ ಸಾಧ್ಯವಾಗುತ್ತದೆ. ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"ಮತ್ತೊಮ್ಮೆ ತೋರಿಸಬೇಡಿ"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_2">%2$s</xliff:g> ಸ್ಲೈಸ್ಗಳನ್ನು <xliff:g id="APP_0">%1$s</xliff:g> ತೋರಿಸಲು ಬಯಸಿದೆ"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"ಎಡಿಟ್"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ಬಹಳ ಸಮಯದಿಂದ ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿದೆ. ಪರಿಶೀಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ಸಕ್ರಿಯ ಆ್ಯಪ್ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"ಈ ಸಾಧನದಿಂದ ಕ್ಯಾಮರಾ ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 07d62b5..914e9c9 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"이동통신사에서 SIM <xliff:g id="SIMNUMBER">%d</xliff:g>의 서비스를 일시적으로 사용 중지했습니다."</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"모바일 네트워크에 연결할 수 없습니다."</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"기본 네트워크를 변경해 보세요. 탭하여 변경할 수 있습니다."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"긴급 전화를 사용할 수 없습니다."</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi‑Fi로는 긴급 전화를 걸 수 없습니다."</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"긴급 전화를 사용할 수 없음"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g>에서는 Wi-Fi를 통한 긴급 전화를 지원하지 않습니다. 탭하여 세부정보를 확인하세요."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"알림"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"착신전환"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"긴급 콜백 모드"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"앱에서 수신 및 발신 통화 데이터를 포함하여 태블릿의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 지우거나 수정할 수 있습니다."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"앱이 수신 및 발신 통화에 관한 데이터를 비롯하여 Android TV 기기의 통화 기록을 수정하도록 허용합니다. 이렇게 하면 악성 앱이 통화 기록을 삭제하거나 수정할 수도 있습니다."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"앱에서 수신 및 발신 통화 데이터를 포함하여 휴대전화의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 지우거나 수정할 수 있습니다."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"인체 감지 센서(예: 심박수 모니터)에 액세스"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"심박수, 체온, 혈중 산소 농도와 같은 생체 신호 센서의 데이터에 액세스합니다."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"백그라운드에서 생체 신호 센서(심박수 모니터 등)에 액세스"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"백그라운드에서 심박수, 체온, 혈중 산소 농도 등 생체 신호 센서의 데이터에 액세스합니다."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"사용 중에 심박수와 같은 생체 신호 센서 데이터에 액세스"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"앱이 사용 중에 심박수, 체온, 혈중 산소 농도와 같은 생체 신호 센서 데이터에 액세스하도록 허용합니다."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"백그라운드에서 심박수와 같은 생체 신호 센서 데이터에 액세스"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"앱이 백그라운드에서 심박수, 체온, 혈중 산소 농도와 같은 생체 신호 센서 데이터에 액세스하도록 허용합니다."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"캘린더 일정 및 세부정보 읽기"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"이 앱은 태블릿에 저장된 모든 캘린더 일정을 읽고 캘린더 데이터를 공유하거나 저장할 수 있습니다."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"앱이 Android TV 기기에 저장된 모든 캘린더 일정을 읽고 캘린더 데이터를 공유하거나 저장할 수 있습니다."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"앱이 공유 저장소에서 오디오 파일을 읽도록 허용합니다."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"공유 저장소에서 동영상 파일 읽기"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"앱이 공유 저장소에서 동영상 파일을 읽도록 허용합니다."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"공유 저장소에서 이미지 파일 읽기"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"앱이 공유 저장소에서 이미지 파일을 읽도록 허용합니다."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"공유 저장소에서 이미지 파일 읽기"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"앱이 공유 저장소에서 이미지 파일을 읽도록 허용합니다."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"공유 저장공간의 콘텐츠 수정 또는 삭제"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"앱이 공유 저장공간의 콘텐츠에 쓰도록 허용합니다."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP 통화 발신/수신"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"비상 전화를 걸거나 잠금해제하려면 메뉴를 누르세요."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"잠금해제하려면 메뉴를 누르세요."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"잠금해제를 위해 패턴 그리기"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"긴급 전화"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"긴급 전화"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"통화로 돌아가기"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"맞습니다."</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"다시 시도"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"안함"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"페이지를 열 수 있는 권한이 없습니다."</string>
<string name="text_copied" msgid="2531420577879738860">"텍스트가 클립보드에 복사되었습니다."</string>
- <string name="copied" msgid="4675902854553014676">"복사 완료"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> 앱이 <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> 앱에서 복사하여 붙여넣음"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>에서 클립보드 데이터를 붙여넣음"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>에서 복사한 텍스트를 붙여넣음"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"앱에서 배터리 최적화를 무시할 수 있는 권한을 요청할 수 있도록 허용합니다."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"모든 패키지 쿼리"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"앱이 설치된 패키지를 모두 볼 수 있도록 허용합니다."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis 액세스"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"애플리케이션에서 SupplementalApis에 액세스하도록 허용합니다."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API 액세스"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"애플리케이션이 AdServices Topics API에 액세스하도록 허용합니다."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API 액세스"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"애플리케이션이 AdServices Attribution API에 액세스하도록 허용합니다."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API 액세스"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"애플리케이션이 AdServices Custom Audiences API에 액세스하도록 허용합니다."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"확대/축소하려면 두 번 탭하세요."</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"위젯을 추가할 수 없습니다."</string>
<string name="ime_action_go" msgid="5536744546326495436">"이동"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>로 전환하는 중…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>님을 로그아웃하는 중…"</string>
<string name="owner_name" msgid="8713560351570795743">"소유자"</string>
+ <string name="guest_name" msgid="8502103277839834324">"게스트"</string>
<string name="error_message_title" msgid="4082495589294631966">"오류"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"관리자가 이 변경을 허용하지 않습니다."</string>
<string name="app_not_found" msgid="3429506115332341800">"이 작업을 처리하는 애플리케이션을 찾을 수 없습니다."</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"제거"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"열기"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"유해한 앱 감지됨"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"시스템 로그 액세스 요청"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>에서 모든 기기에 액세스하도록 허용하시겠습니까?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"이번만 허용"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"허용 안함"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> 앱에서 기능 디버깅을 위해 시스템 로그를 요청합니다. 이 로그에는 기기의 앱과 서비스가 작성한 정보가 포함될 수 있습니다."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"기기 로그에 기기에서 발생한 상황이 기록됩니다. 앱은 문제를 찾고 해결하는 데 이 로그를 사용할 수 있습니다.\n\n일부 로그에는 민감한 정보가 포함될 수 있으므로 신뢰할 수 있는 앱만 전체 기기 로그에 액세스하도록 허용하세요. \n\n앱에 전체 기기 로그에 대한 액세스 권한을 부여하지 않아도 앱이 자체 로그에는 액세스할 수 있으며, 기기 제조업체에서 일부 로그 또는 기기 내 정보에 액세스할 수 있습니다. 자세히 알아보기"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"다시 표시 안함"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>에서 <xliff:g id="APP_2">%2$s</xliff:g>의 슬라이스를 표시하려고 합니다"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"수정"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> 앱이 백그라운드에서 오랫동안 실행 중입니다. 확인하려면 탭하세요."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"활성 상태의 앱 확인"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"이 기기에서 카메라에 액세스할 수 없습니다."</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 1111975..c781be2 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> үчүн байланыш оператору тарабынан убактылуу бөгөттөлгөн"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобилдик тармакка туташпай жатат"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Тандалган тармакты өзгөртүп көрүңүз. Өзгөртүү үчүн таптаңыз."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Шашылыш чалуу жеткиликсиз"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi-Fi аркылуу шашылыш чалуулар иштетилген жок"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Шашылыш чалуулар жеткиликсиз болушу мүмкүн"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi аркылуу шашылыш чалууларды колдоого албайт. Чоо-жайын көрүү үчүн таптап коюңуз."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Шашылыш билдирүүлөр"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Чалууну башка номерге багыттоо"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Шашылыш кайра чалуу режими"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Колдонмого планшетиңиздин чалуулар тизмегин, анын ичинде, чыгыш жана кириш чалууларына тиешелүү берилиштерди өзгөртүү уруксатын берет. Зыяндуу колдонмолор муну колдонуп чалуулар тизмегин өзгөртө же жок кыла алышат."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Колдонмого Android TV түзмөгүңүздүн чалуулар тизмесин, анын ичинде кирүүчү жана чыгуучу чалуулар тууралуу маалыматтарды өзгөртүүгө уруксат берет. Зыянкеч колдонмолор ал уруксатты колдонуп чалуулар тизмеңизди тазалап же өзгөртүп коюшу мүмкүн."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Колдонмого телефонуңуздун чалуулар тизмегин, анын ичинде, чыгыш жана кириш чалууларына тиешелүү берилиштерди өзгөртүү уруксатын берет. Зыяндуу колдонмолор муну колдонуп чалуулар тизмегин өзгөртө же жок кыла алышат."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"дене-бой сенсорлоруна (жүрөктүн кагышын өлчөгүчтөр сыяктуу) уруксат"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Жүрөктүн согушу, температура, кандагы кычкылтектин пайыздык үлүшү ж.б. сыяктуу дене сенсорлорунун маалыматын алуу."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"дене сенсорлорун (жүрөктүн согушун өлчөгүчтөр сыяктуу) фондо алуу"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Жүрөктүн согушу, температура, кандагы кычкылтектин пайыздык үлүшү ж.б. сыяктуу дене сенсорлорунун маалыматын фондо алуу."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Иштеп жатканда дене сенсорлорунун дайындарын, мисалы, жүрөктүн согушун көрүү"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Иштеп жатканда колдонмо дене сенсорлорунун дайындарын, мисалы, жүрөктүн согушу, температура жана кандагы кычкылтектин пайызын көрө алат."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Фондо дене сенсорлорунун дайындарын, мисалы, жүрөктүн согушун көрүү"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Колдонмо фондо дене сенсорлорунун дайындарын, мисалы, жүрөктүн согушу, температура жана кандагы кычкылтектин пайызын көрө алат."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Жылнаамадагы иш-чараларды жана алардын чоо-жайын окуу"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Бул колдонмо планшетиңизде сакталган жылнаамадагы иш-чаралардын баарын окуп жана андагы маалыматтарды бөлүшүп же сактай алат."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Бул колдонмо Android TV түзмөгүңүздө сакталган жылнаама иш-чараларынын баарын окуп, ошондой эле жылнаама дайындарын бөлүшүп же сактай алат."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Колдонмого жалпы сактагычыңыздагы аудио файлдарды окуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"жалпы сактагычтагы видеолорду окуу"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Колдонмого жалпы сактагычыңыздагы видеолорду окуу мүмкүнчүлүгүн берет."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"жалпы сактагычтагы сүрөттөрдү окуу"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Колдонмого жалпы сактагычыңыздагы сүрөттөрдү окуу мүмкүнчүлүгүн берет."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"жалпы сактагычтагы сүрөт файлдарды окуу"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Колдонмого жалпы сактагычыңыздагы сүрөт файлдарды окуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"жалпы сактагычыңыздын мазмунун өзгөртүү же жок кылуу"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Колдонмого жалпы сактагычыңыздын мазмунун жазуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP чалуу/чалууну кабыл алуу"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Кулпусун ачып же Шашылыш чалуу аткаруу үчүн менюну басыңыз."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Бөгөттөн чыгаруу үчүн Менюну басыңыз."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Кулпуну ачуу үчүн, үлгүнү тартыңыз"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Шашылыш чалуу"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Шашылыш чалуу"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Чалууга кайтуу"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Туура!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Дагы аракет кылыңыз"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Эч качан"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Бул бетти ачууга уруксат берилген эмес."</string>
<string name="text_copied" msgid="2531420577879738860">"Текст алмашуу буферине көчүрүлдү."</string>
- <string name="copied" msgid="4675902854553014676">"Көчүрүлдү"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> колдонмосунан чапталды"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Алмашуу буфериндеги нерселер <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> колдонмосуна жайгаштырылды"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>: көчүрүлгөн текст чапталды"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Колдонмо батареянын кубатын керектегенден мурун уруксат суралсын."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"бардык топтомдор боюнча сурам жөнөтүү"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Колдонмо бардык орнотулган топтомдорду көрөт."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis\'ке кирүү"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Колдонмого SupplementalApis\'ке кирүү уруксатын берет."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API\'син колдонуу мүмкүнчүлүгү"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Колдонмого AdServices Topics API\'син колдонууга мүмкүнчүлүк берет."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API\'лерин колдонуу мүмкүнчүлүгү"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Колдонмого AdServices Attribution API\'лерин колдонууга мүмкүнчүлүк берет."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API\'син колдонуу мүмкүнчүлүгү"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Колдонмого AdServices Custom Audiences API\'син колдонууга мүмкүнчүлүк берет."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Масштабдын параметрлерин өзгөртүү үчүн бул жерди эки жолу басыңыз."</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Виджетти кошуу мүмкүн болбоду."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Өтүү"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> дегенге которулууда…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> чыгууда…"</string>
<string name="owner_name" msgid="8713560351570795743">"Ээси"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Конок"</string>
<string name="error_message_title" msgid="4082495589294631966">"Ката"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Мындай өзгөртүүгө администраторуңуз тарабынан тыюу салынган"</string>
<string name="app_not_found" msgid="3429506115332341800">"Бул аракетти аткаруучу эч бир колдонмо табылбады"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ЧЫГАРЫП САЛУУ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"БААРЫ БИР АЧЫЛСЫН"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Зыянкеч колдонмо аныкталды"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Тутум таржымалына кирүүгө уруксат суралды"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> колдонмосуна түзмөктөгү бардык таржымалдарды колдонууга уруксат бересизби?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Ушул жолу гана"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Уруксат берилбесин"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> функционалдык мүчүлүштүктөрдү оңдоо үчүн тутум таржымалдарын сурап жатат. Бул таржымалдарда түзмөгүңүздөгү колдонмолор жана кызматтар жазган маалымат камтылышы мүмкүн."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Түзмөктө аткарылган бардык аракеттер түзмөктүн таржымалдарында сакталып калат. Колдонмолор бул таржымалдарды колдонуп, маселелерди оңдошот.\n\nАйрым таржымалдарда купуя маалымат болушу мүмкүн, андыктан түзмөктөгү бардык таржымалдарды ишенимдүү колдонмолорго гана пайдаланууга уруксат бериңиз. \n\nЭгер бул колдонмого түзмөктөгү айрым таржымалдарга кирүүгө тыюу салсаңыз, ал өзүнүн таржымалдарын пайдалана берет. Ал эми түзмөктү өндүрүүчү түзмөгүңүздөгү айрым таржымалдарды же маалыматты көрө берет. Кененирээк"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Экинчи көрүнбөсүн"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> колдонмосу <xliff:g id="APP_2">%2$s</xliff:g> үлгүлөрүн көрсөткөнү жатат"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Түзөтүү"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> колдонмосу көп убакыттан бери фондо иштеп жатат. Көрүү үчүн таптап коюңуз."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Жигердүү колдонмолорду карап чыгуу"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Бул түзмөктөгү камераны колдонууга болбойт"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 0e5a781..a5879e1 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"ຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານປິດໄວ້ສຳລັບຊິມ <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ບໍ່ສາມາດຕິດຕໍ່ເຄືອຂ່າຍມືຖືໄດ້"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ໃຫ້ລອງປ່ຽນເຄືອຂ່າຍທີ່ຕ້ອງການ. ແຕະເພື່ອປ່ຽນ."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ບໍ່ສາມາດໃຊ້ການໂທສຸກເສີນໄດ້"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"ບໍ່ສາມາດໂທສຸກເສີນຜ່ານ Wi‑Fi ໄດ້"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"ການໂທສຸກເສີນອາດບໍ່ສາມາດໃຊ້ໄດ້"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ບໍ່ຮອງຮັບການໂທສຸກເສີນຂ້າມ Wi-Fi. ແຕະເພື່ອເບິ່ງລາຍລະອຽດ."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"ການເຕືອນ"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"ການໂອນສາຍ"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"ໂໝດໂທກັບສຸກເສີນ"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂບັນທຶກການໂທຂອງແທັບເລັດ ຮວມທັງຂໍ້ມູນກ່ຽວກັບການໂທອອກ ແລະໂທເຂົ້ານຳ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄຸນສົມບັດນີ້ເພື່ອລຶບ ຫຼືແກ້ໄຂບັນທຶກການໂທຂອງທ່ານໄດ້."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ອະນຸຍາດໃຫ້ແອັບແກ້ໄຂບັນທຶກການໂທຂອງອຸປະກອນ Android TV ທ່ານ, ຮວມທັງສາຍໂທເຂົ້າ ແລະ ໂທອອກ. ແອັບທີ່ເປັນອັນຕະລາຍສາມາດໃຊ້ຄຸນສົມບັດນີ້ເພື່ອລຶບ ຫຼື ແກ້ໄຂບັນທຶກການໂທຂອງທ່ານໄດ້."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂລາຍການການໂທໃນໂທລະສັບຂອງທ່ານ, ຮວມທັງຂໍ້ມູນກ່ຽວກັບສາຍໂທເຂົ້າ ແລະການໂທອອກ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອລຶບ ຫຼືແກ້ໄຂລາຍການການໂທຂອງທ່ານໄດ້."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"ເຂົ້າຫາເຊັນເຊີກວດຮ່າງກາຍ (ເຊັ່ນ: ຈໍຕິດຕາມອັດຕາການເຕັ້ນຂອງຫົວໃຈ)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"ເຂົ້າເຖິງຂໍ້ມູນຈາກເຊັນເຊີຮ່າງກາຍ ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ອຸນຫະພູມ, ເປີເຊັນອອກຊິເຈນໃນເລືອດ ແລະ ອື່ນໆ."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"ເຂົ້າເຖິງເຊັນເຊີຮ່າງກາຍ (ເຊັ່ນ: ເຄື່ອງວັດແທກອັດຕາການເຕັ້ນຫົວໃຈ) ໃນຂະນະທີ່ຢູ່ໃນພື້ນຫຼັງ"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"ເຂົ້າເຖິງຂໍ້ມູນຈາກເຊັນເຊີຮ່າງກາຍ ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ອຸນຫະພູມ, ເປີເຊັນອອກຊິເຈນໃນເລືອດ ແລະ ອື່ນໆໃນຂະນະທີ່ຢູ່ໃນພື້ນຫຼັງ."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ເຂົ້າເຖິງຂໍ້ມູນເຊັນເຊີຮ່າງກາຍ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ໃນຂະນະທີ່ນຳໃຊ້ຢູ່"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ອະນຸຍາດໃຫ້ແອັບເຂົ້າເຖິງຂໍ້ມູນເຊັນເຊີຮ່າງກາຍ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ອຸນຫະພູມ ແລະ ເປີເຊັນອອກຊິເຈນໃນເລືອດ, ໃນຂະນະທີ່ໃຊ້ແອັບຢູ່."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ເຂົ້າເຖິງຂໍ້ມູນເຊັນເຊີຮ່າງກາຍ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ໃນຂະນະທີ່ແອັບຢູ່ໃນພື້ນຫຼັງ"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ອະນຸຍາດໃຫ້ແອັບເຂົ້າເຖິງຂໍ້ມູນເຊັນເຊີຮ່າງກາຍ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ອຸນຫະພູມ ແລະ ເປີເຊັນອອກຊິເຈນໃນເລືອດ, ໃນຂະນະທີ່ແອັບຢູ່ໃນພື້ນຫຼັງ."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ແອັບນີ້ສາມາດອ່ານນັດໝາຍປະຕິທິນທັງໝົດທີ່ບັນທຶກໄວ້ຢູ່ອຸປະກອນ Android TV ຂອງທ່ານ ແລະ ແບ່ງປັນ ຫຼື ບັນທຶກຂໍ້ມູນປະຕິທິນຂອງທ່ານ."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"ອະນຸຍາດໃຫ້ແອັບອ່ານໄຟລ໌ສຽງຈາກບ່ອນຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນຂອງທ່ານ."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"ອ່ານໄຟລ໌ວິດີໂອຈາກບ່ອນຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນ"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"ອະນຸຍາດໃຫ້ແອັບອ່ານໄຟລ໌ວິດີໂອຈາກບ່ອນຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນຂອງທ່ານ."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"ອ່ານໄຟລ໌ຮູບຈາກບ່ອນຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນ"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"ອະນຸຍາດໃຫ້ແອັບອ່ານໄຟລ໌ຮູບຈາກບ່ອນຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນຂອງທ່ານ."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"ອ່ານໄຟລ໌ຮູບຈາກບ່ອນຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນ"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"ອະນຸຍາດໃຫ້ແອັບອ່ານໄຟລ໌ຮູບຈາກບ່ອນຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນຂອງທ່ານ."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"ແກ້ໄຂ ຫຼືລຶບເນື້ອຫາໃນບ່ອນຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນຂອງທ່ານ"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"ອະນຸຍາດໃຫ້ແອັບຂຽນເນື້ອຫາຕ່າງໆຂອງບ່ອນຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນຂອງທ່ານ."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"ຮັບສາຍ/ໂທອອກ ຜ່ານ SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"ກົດ ເມນູ ເພື່ອປົດລັອກ ຫຼື ໂທອອກຫາເບີສຸກເສີນ."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"ກົດ \"ເມນູ\" ເພື່ອປົດລັອກ."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"ແຕ້ມຮູບແບບເພື່ອປົດລັອກ"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"ການໂທສຸກເສີນ"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ສຸກເສີນ"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"ກັບໄປຫາການໂທ"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"ຖືກຕ້ອງ!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"ລອງໃໝ່ອີກຄັ້ງ"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"ບໍ່ຕ້ອງຈື່"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"ທ່ານບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ເປີດໜ້ານີ້."</string>
<string name="text_copied" msgid="2531420577879738860">"ສຳເນົາຂໍ້ຄວາມໃສ່ຄລິບບອດແລ້ວ."</string>
- <string name="copied" msgid="4675902854553014676">"ສຳເນົາແລ້ວ"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"ວາງ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ຈາກ <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ແລ້ວ"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ວາງຈາກຄລິບບອດຂອງທ່ານແລ້ວ"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ວາງຂໍ້ຄວາມທີ່ທ່ານສຳເນົາແລ້ວ"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ອະນຸຍາດໃຫ້ແອັບຖາມສິດອະນຸຍາດເພື່ອເພີກເສີຍຕໍ່ການປັບແຕ່ງແບັດເຕີຣີສຳລັບແອັບນັ້ນ."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"ຊອກຫາແພັກເກດທັງໝົດ"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"ອະນຸຍາດໃຫ້ແອັບເບິ່ງເຫັນແພັກເກດທີ່ຕິດຕັ້ງແລ້ວທັງໝົດໄດ້."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"ເຂົ້າເຖິງ SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນເຂົ້າເຖິງ SupplementalApis ໄດ້."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"ເຂົ້າເຖິງ AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນເຂົ້າເຖິງ AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"ເຂົ້າເຖິງ AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນເຂົ້າເຖິງ AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"ເຂົ້າເຖິງ AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນເຂົ້າເຖິງ AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ແຕະສອງເທື່ອເພື່ອຄວບຄຸມການຊູມ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ບໍ່ສາມາດເພີ່ມວິດເຈັດໄດ້."</string>
<string name="ime_action_go" msgid="5536744546326495436">"ໄປ"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"ກຳລັງສະຫຼັບໄປຫາ<xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"ກຳລັງອອກຈາກລະບົບ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"ເຈົ້າຂອງ"</string>
+ <string name="guest_name" msgid="8502103277839834324">"ແຂກ"</string>
<string name="error_message_title" msgid="4082495589294631966">"ຜິດພາດ"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ປ່ຽນແປງສິ່ງນີ້"</string>
<string name="app_not_found" msgid="3429506115332341800">"ບໍ່ພົບແອັບພລິເຄຊັນເພື່ອຈັດການເຮັດວຽກນີ້."</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ຖອນການຕິດຕັ້ງ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ຢືນຢັນການເປີດ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"ກວດສອບແອັບທີ່ເປັນອັນຕະລາຍ"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"ຄຳຮ້ອງຂໍການເຂົ້າເຖິງບັນທຶກລະບົບ"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"ອະນຸຍາດໃຫ້ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ເຂົ້າເຖິງບັນທຶກອຸປະກອນທັງໝົດບໍ?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"ສະເພາະເທື່ອນີ້"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"ບໍ່ອະນຸຍາດ"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ຮ້ອງຂໍບັນທຶກລະບົບສຳລັບການດີບັກການເຮັດວຽກ. ບັນທຶກເຫຼົ່ານີ້ອາດມີເນື້ອຫາທີ່ແອັບ ແລະ ບໍລິການຢູ່ອຸປະກອນຂອງທ່ານໄດ້ຂຽນໄວ້."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"ບັນທຶກອຸປະກອນຈະບັນທຶກສິ່ງທີ່ເກີດຂຶ້ນຢູ່ອຸປະກອນຂອງທ່ານ. ແອັບສາມາດໃຊ້ບັນທຶກເຫຼົ່ານີ້ເພື່ອຊອກຫາ ແລະ ແກ້ໄຂບັນຫາໄດ້.\n\nບັນທຶກບາງຢ່າງອາດມີຂໍ້ມູນລະອຽດອ່ອນ, ດັ່ງນັ້ນໃຫ້ອະນຸຍາດສະເພາະແອັບທີ່ທ່ານເຊື່ອຖືໃຫ້ເຂົ້າເຖິງບັນທຶກອຸປະກອນທັງໝົດເທົ່ານັ້ນ. \n\nຫາກທ່ານບໍ່ອະນຸຍາດແອັບນີ້ໃຫ້ເຂົ້າເຖິງບັນທຶກອຸປະກອນທັງໝົດ, ມັນຈະຍັງຄົງສາມາດເຂົ້າເຖິງບັນທຶກຂອງຕົວມັນເອງໄດ້ຢູ່ ແລະ ຜູ້ຜະລິດອຸປະກອນຂອງທ່ານອາດຍັງຄົງສາມາດເຂົ້າເຖິງບັນທຶກ ຫຼື ຂໍ້ມູນບາງຢ່າງຢູ່ອຸປະກອນຂອງທ່ານໄດ້. ສຶກສາເພີ່ມເຕີມ"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"ບໍ່ຕ້ອງສະແດງອີກ"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ຕ້ອງການສະແດງ <xliff:g id="APP_2">%2$s</xliff:g> ສະໄລ້"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"ແກ້ໄຂ"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງເປັນເວລາດົນແລ້ວ. ແຕະເພື່ອກວດສອບ."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ກວດສອບແອັບທີ່ເຄື່ອນໄຫວ"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"ບໍ່ສາມາດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຈາກອຸປະກອນນີ້ໄດ້"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 57efdc7..f3cde46 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -87,8 +87,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM kortelėje <xliff:g id="SIMNUMBER">%d</xliff:g> laikinai išjungė operatorius"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nepavyko pasiekti mobiliojo ryšio tinklo"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Pabandykite pakeisti pageidaujamą tinklą. Palieskite, kad pakeistumėte."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Skambučių pagalbos numeriu paslauga nepasiekiama"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Negalima skambinti pagalbos numeriu naudojant „Wi‑Fi“"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Skambučiai pagalbos numeriu gali būti nepasiekiami"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"„<xliff:g id="SPN">%s</xliff:g>“ nepalaiko skambučių pagalbos numeriu „Wi-Fi“ ryšiu. Palieskite, jei reikia išsamios informacijos."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Įspėjimai"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Skambučio peradresavimas"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Atskambinimo pagalbos numeriu režimas"</string>
@@ -427,10 +427,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Programai leidžiama skaityti planšetinio kompiuterio skambučių žurnalą, įskaitant duomenis apie gaunamuosius ir siunčiamuosius skambučius. Kenkėjiškos programos tai gali naudoti, kad ištrintų ar keistų jūsų skambučių žurnalą."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Programai leidžiama keisti „Android TV“ įrenginio skambučių žurnalą, įskaitant gaunamųjų ir siunčiamųjų skambučių duomenis. Kenkėjiškos programos gali ištrinti arba keisti skambučių žurnalą."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Programai leidžiama skaityti telefono skambučių žurnalą, įskaitant duomenis apie gaunamuosius ir siunčiamuosius skambučius. Kenkėjiškos programos tai gali naudoti, kad ištrintų ar keistų jūsų skambučių žurnalą."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"pas. k. jut. (pvz., pul. dažn. st. įr.)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Pasiekti kūno jutiklių duomenis, pvz., pulso dažnį, temperatūrą, deguonies procentinę dalį kraujyje ir kt."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"pasiekti kūno jutiklių duom. (pvz., pulso dažn. stebėjimo įreng.), veikiant fone"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Pasiekti kūno jutiklių duomenis, pvz., pulso dažnį, temperatūrą, deguonies procentinę dalį kraujyje ir kt., kai veikia fone."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Prieiga prie kūno jutiklių duomenų, pvz., pulso dažnio, kai naudojama"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Leidžiama programai pasiekti kūno jutiklių duomenis, pvz., pulso dažnį, temperatūrą ir deguonies procentinę dalį kraujyje, kai programa naudojama."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Prieiga prie kūno jutiklių duomenų, pvz., pulso dažnio, kai veikia fone"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Leidžiama programai pasiekti kūno jutiklių duomenis, pvz., pulso dažnį, temperatūrą ir deguonies procentinę dalį kraujyje, kai programa veikia fone."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Skaityti kalendoriaus įvykius arba išsamią informaciją"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ši programa gali nuskaityti visus planšetiniame kompiuteryje saugomus kalendoriaus įvykius ir bendrinti arba išsaugoti kalendoriaus duomenis."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ši programa gali nuskaityti visus „Android TV“ įrenginyje saugomus kalendoriaus įvykius ir bendrinti arba išsaugoti kalendoriaus duomenis."</string>
@@ -691,8 +691,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Leidžiama programai nuskaityti garso failus iš bendrinamos saugyklos."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"nuskaityti vaizdo įrašo failus iš bendrinamos saugyklos"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Leidžiama programai nuskaityti vaizdo įrašo failus iš bendrinamos saugyklos."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"nuskaityti vaizdo failus iš bendrinamos saugyklos"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Leidžiama programai nuskaityti vaizdo failus iš bendrinamos saugyklos."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"nuskaityti vaizdo failus iš bendrinamos saugyklos"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Leidžiama programai nuskaityti vaizdo failus iš bendrinamos saugyklos."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"keisti / trinti bendr. atm. t."</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Pr. leidž. raš. bendr. atm. t."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"skambinti / priimti SIP skambučius"</string>
@@ -914,7 +914,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Paspauskite „Meniu“, kad atrakintumėte ar skambintumėte pagalbos numeriu."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Paspauskite „Meniu“, jei norite atrakinti."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Nustatyti modelį, kad atrakintų"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Skambutis pagalbos numeriu"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Skambutis pagalbos numeriu"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"grįžti prie skambučio"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Teisingai!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Bandykite dar kartą"</string>
@@ -1053,7 +1053,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Niekada"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Neturite leidimo atidaryti šį puslapį."</string>
<string name="text_copied" msgid="2531420577879738860">"Tekstas nukopijuotas į iškarpinę."</string>
- <string name="copied" msgid="4675902854553014676">"Nukopijuota"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"„<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>“ įklijuota iš „<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>“"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"„<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>“ įklijuota iš iškarpinės"</string>
<string name="pasted_text" msgid="4298871641549173733">"„<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>“ įklijavo jūsų nukopijuotą tekstą"</string>
@@ -1454,8 +1453,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Programai leidžiama prašyti leidimo nepaisyti tai programai skirto akumuliatoriaus optimizavimo nustatymų."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"Teikti visų paketų užklausą"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Programai leidžiama peržiūrėti visus įdiegtus paketus."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"pasiekti papildomas API"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Leidžiama programai pasiekti papildomas API."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"pasiekti „AdServices Topics“ API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Leidžiama programai pasiekti „AdServices Topics“ API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"pasiekti „AdServices Attribution“ API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Leidžiama programai pasiekti „AdServices Attribution“ API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"pasiekti „AdServices Custom Audiences“ API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Leidžiama programai pasiekti „AdServices Custom Audiences“ API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Bakstelėkite du kartus, kad valdytumėte mastelio keitimą"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nepavyko pridėti."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Pradėti"</string>
@@ -1718,6 +1721,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Perjungiama į <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Atsijungiama (<xliff:g id="NAME">%1$s</xliff:g>)…"</string>
<string name="owner_name" msgid="8713560351570795743">"Savininkas"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Svečias"</string>
<string name="error_message_title" msgid="4082495589294631966">"Klaida"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Administratorius neleidžia atlikti šio pakeitimo"</string>
<string name="app_not_found" msgid="3429506115332341800">"Nerasta programa šiam veiksmui apdoroti"</string>
@@ -2029,10 +2033,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"PAŠALINTI"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"VIS TIEK ATIDARYTI"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Aptikta žalinga programa"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Prieigos prie sistemos žurnalų užklausa"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Leisti „<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>“ pasiekti visus įrenginio žurnalus?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Tik šį kartą"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Neleisti"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"„<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>“ prašo leisti pasiekti sistemos žurnalus funkcinio derinimo tikslais. Šiuose žurnaluose gali būti informacijos, kurią įrašė įrenginyje esančios programos ir paslaugos."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Įrenginyje įrašoma, kas įvyksta jūsų įrenginyje. Programos gali naudoti šiuos žurnalus, kad surastų ir išspręstų problemas.\n\nKai kuriuose žurnaluose gali būti neskelbtinos informacijos, todėl visus įrenginio žurnalus leiskite pasiekti tik programoms, kuriomis pasitikite. \n\nJei neleisite šiai programai pasiekti visų įrenginio žurnalų, ji vis tiek galės pasiekti savo žurnalus, o įrenginio gamintojui vis tiek gali būti leidžiama pasiekti tam tikrus žurnalus ar informaciją jūsų įrenginyje. Sužinokite daugiau"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Daugiau neberodyti"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"„<xliff:g id="APP_0">%1$s</xliff:g>“ nori rodyti „<xliff:g id="APP_2">%2$s</xliff:g>“ fragmentus"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Redaguoti"</string>
@@ -2267,4 +2271,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"„<xliff:g id="APP">%1$s</xliff:g>“ ilgą laiką veikia fone. Palieskite ir peržiūrėkite."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Peržiūrėkite aktyvias programas"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nepavyksta pasiekti fotoaparato iš šio įrenginio"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 11e6cfa..16b7098 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -86,8 +86,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Jūsu mobilo sakaru operators īslaicīgi izslēdza pakalpojumu šai SIM kartei: <xliff:g id="SIMNUMBER">%d</xliff:g>."</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nevar sasniegt mobilo tīklu"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Mēģiniet nomainīt vēlamo tīklu. Pieskarieties, lai to mainītu."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Nav pieejami ārkārtas izsaukumi"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Izmantojot Wi-Fi, nevar veikt ārkārtas izsaukumus"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Ārkārtas izsaukumi var nebūt pieejami"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> neatbalsta ārkārtas izsaukumus Wi-Fi tīklā. Pieskarieties, lai skatītu detalizētu informāciju."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Brīdinājumi"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Zvanu pāradresācija"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Ārkārtas atzvana režīms"</string>
@@ -426,10 +426,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Ļauj lietotnei pārveidot planšetdatora zvanu žurnālu, tostarp ienākošo un izejošo zvanu datus. Ļaunprātīgas lietotnes var to izmantot, lai dzēstu vai pārveidotu savu zvanu žurnālu."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Ļauj lietotnei pārveidot Android TV ierīces zvanu žurnālu, tostarp datus par ienākošajiem un izejošajiem zvaniem. Ļaunprātīgas lietotnes var to izmantot, lai dzēstu vai pārveidotu zvanu žurnālu."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Ļauj lietotnei pārveidot tālruņa zvanu žurnālu, tostarp ienākošo un izejošo zvanu datus. Ļaunprātīgas lietotnes var to izmantot, lai dzēstu vai pārveidotu savu zvanu žurnālu."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"Piekļūt ķermeņa sensoriem (piemēram, sirdsdarbības monitoriem)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Piekļuve ķermeņa sensoru rādītāju datiem (piemēram, sirdsdarbības ātrumam, temperatūrai, procentuālajam skābekļa daudzumam asinīs u.c.)"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"piekļuve ķermeņa sensoru datiem (piemēram, sirdsdarbības ātrumam) fonā"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Piekļuve ķermeņa sensoru rādītāju datiem (piemēram, sirdsdarbības ātrumam, temperatūrai, procentuālajam skābekļa daudzumam asinīs u.c.) fonā."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Piekļuve ķermeņa sensoru datiem, piem., sirdsdarbības ātrumam, lietošanas laikā"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ļauj lietotnei piekļūt ķermeņa sensoru datiem, piemēram, sirdsdarbības ātrumam, temperatūrai un procentuālajam skābekļa daudzumam asinīs, kamēr lietotne tiek izmantota."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Piekļuve ķermeņa sensoru datiem, piemēram, sirdsdarbības ātrumam, fonā"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ļauj lietotnei piekļūt ķermeņa sensoru datiem, piemēram, sirdsdarbības ātrumam, temperatūrai un procentuālajam skābekļa daudzumam asinīs, kamēr lietotne darbojas fonā."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Lasīt kalendāra pasākumus un informāciju"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Šī lietotne var lasīt visus kalendāra pasākumus, kas saglabāti planšetdatorā, un kopīgot vai saglabāt jūsu kalendāra datus."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Šī lietotne var lasīt visus kalendāra pasākumus, kas saglabāti Android TV ierīcē, un kopīgot vai saglabāt jūsu kalendāra datus."</string>
@@ -690,8 +690,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Ļauj lietotnei lasīt audio failus jūsu koplietotajā krātuvē."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"lasīt video failus koplietotajā krātuvē"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Ļauj lietotnei lasīt video failus jūsu koplietotajā krātuvē."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"lasīt attēlu failus koplietotajā krātuvē"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Ļauj lietotnei lasīt attēlu failus jūsu koplietotajā krātuvē."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"lasīt attēlu failus koplietotajā krātuvē"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Ļauj lietotnei lasīt attēlu failus jūsu koplietotajā krātuvē."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"Jūsu kopīgotās krātuves satura pārveidošana vai dzēšana"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Ļauj lietotnei rakstīt jūsu kopīgotās krātuves saturu."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP zvanu veikšana/saņemšana"</string>
@@ -913,7 +913,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Nospiediet Izvēlne, lai atbloķētu, vai veiciet ārkārtas zvanu."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Lai atbloķētu, nospiediet vienumu Izvēlne."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Zīmējiet kombināciju, lai atbloķētu."</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Ārkārtas izsaukums"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Ārkārtas situācija"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Atpakaļ pie zvana"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Pareizi!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Mēģināt vēlreiz"</string>
@@ -1052,7 +1052,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nekad"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Jums nav atļaujas atvērt šo lapu."</string>
<string name="text_copied" msgid="2531420577879738860">"Teksts ir kopēts uz starpliktuvi."</string>
- <string name="copied" msgid="4675902854553014676">"Nokopēts"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Lietotnē <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> tika ielīmēti dati no lietotnes <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>."</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Lietotne <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ielīmēja datus no starpliktuves."</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ielīmēja jūsu nokopēto tekstu"</string>
@@ -1453,8 +1452,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Ļauj lietotnei lūgt atļauju ignorēt akumulatora optimizāciju šai lietotnei."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"pieprasīt atļauju skatīt visas pakotnes"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Ļauj lietotnei skatīt visas instalētās pakotnes."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"piekļuve SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Ļauj lietojumprogrammai piekļūt SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"Piekļuve saskarnei AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Ļauj lietojumprogrammai piekļūt saskarnei AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"Piekļuve AdServices Attribution API saskarnēm"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Ļauj lietojumprogrammai piekļūt AdServices Attribution API saskarnēm."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"Piekļuve saskarnei AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Ļauj lietojumprogrammai piekļūt saskarnei AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Pieskarieties divreiz, lai kontrolētu tālummaiņu."</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nevarēja pievienot logrīku."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Doties uz"</string>
@@ -1717,6 +1720,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Notiek pāriešana uz: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Notiek lietotāja <xliff:g id="NAME">%1$s</xliff:g> atteikšanās…"</string>
<string name="owner_name" msgid="8713560351570795743">"Īpašnieks"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Viesis"</string>
<string name="error_message_title" msgid="4082495589294631966">"Kļūda"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Jūsu administrators neļauj veikt šīs izmaiņas."</string>
<string name="app_not_found" msgid="3429506115332341800">"Netika atrasta neviena lietojumprogramma, kas var veikt šo darbību."</string>
@@ -2028,10 +2032,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ATINSTALĒT"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"TIK UN TĀ ATVĒRT"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Konstatēta kaitīga lietotne"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Pieprasījums piekļūt sistēmas žurnāliem"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vai atļaujat lietotnei <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> piekļūt visiem ierīces žurnāliem?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Tikai šoreiz"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Neatļaut"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"Lietotne <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> pieprasa sistēmas žurnālus funkciju atkļūdošanai. Šie žurnāli var ietvert informāciju, ko ir rakstījušas jūsu ierīces lietotnes un pakalpojumi."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Ierīces žurnālos tiek reģistrēti ierīces procesi un notikumi. Lietotņu izstrādātāji var izmantot šos žurnālus, lai atrastu un izlabotu problēmas savās lietotnēs.\n\nDažos žurnālos var būt ietverta sensitīva informācija, tāpēc atļaujiet tikai uzticamām lietotnēm piekļūt visiem ierīces žurnāliem. \n\nJa neatļausiet šai lietotnei piekļūt visiem ierīces žurnāliem, lietotnes izstrādātājs tik un tā varēs piekļūt pašas lietotnes žurnāliem, savukārt ierīces ražotājs varbūt tik un tā varēs piekļūt noteiktiem žurnāliem vai informācijai jūsu ierīcē. Uzzināt vairāk"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Vairs nerādīt"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Lietotne <xliff:g id="APP_0">%1$s</xliff:g> vēlas rādīt lietotnes <xliff:g id="APP_2">%2$s</xliff:g> sadaļas"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Rediģēt"</string>
@@ -2266,4 +2270,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ilgi darbojas fonā. Pieskarieties, lai to pārskatītu."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Pārbaudiet aktīvās lietotnes"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nevar piekļūt kamerai no šīs ierīces"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 2f00cc7..9085e6e 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Привремено исклучена од вашиот оператор за SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобилната мрежа е недостапна"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Сменете ја претпочитаната мрежа. Допрете за промена."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Итните повици се недостапни"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Не може да остваруваат итни повици преку Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Можно е итните повици да се недостапни"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> не поддржува итни повици преку Wi-Fi. Допрете за детали."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Предупредувања"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Проследување повик"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим на итен повратен повик"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Овозможува апликацијата да го менува дневникот на повици на вашиот таблет, вклучувајќи податоци за дојдовни и појдовни повици. Злонамерните апликации може да го искористат ова да го избришат или да го менуваат вашиот дневник на повици."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Дозволува апликацијата да го менува дневникот на повици на вашиот уред Android TV, вклучувајќи и податоци за дојдовните или појдовните повици. Злонамерните апликации може да го искористат ова за да го избришат или да го менуваат дневникот на повици."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Овозможува апликацијата да го менува дневникот на повици на вашиот телефон, вклучувајќи податоци за дојдовни и појдовни повици. Злонамерните апликации може да го искористат ова да го избришат или да го менуваат вашиот дневник на повици."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"пристап до телесните сензори (како мониторите за пулс)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Пристап до податоци од телесни сензори, како пулс, температура, процент на кислород во крвта итн."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"пристап до телесните сензори (како мониторите за пулс) додека се во заднина"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Пристап до податоци од телесни сензори, како пулс, температура, процент на кислород во крвта итн. додека се во заднина."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Пристап до податоци од телесните сензори, како пулсот, додека се користи"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Дозволува апликацијата да пристапува до податоци од телесните сензори, како што се пулс, температура и процент на кислород во телото, додека апликацијата се користи."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Пристап до податоци од телесните сензори, како пулсот, додека работи во заднина"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Дозволува апликацијата да пристапува до податоци од телесните сензори, како што се пулс, температура и процент на кислород во телото, додека апликацијата работи во заднина."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Чита настани и детали од календарот"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Апликацијава може да ги чита сите настани во календарот складирани во вашиот таблет и да ги споделува или зачувува податоците од календарот."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Апликацијава може да ги чита сите настани во календарот складирани во вашиот уред Android TV и да ги споделува или зачувува податоците од календарот."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Дозволува апликацијата да ги чита аудиодатотеките од споделениот капацитет."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"да чита видеодатотеки од споделениот капацитет"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Дозволува апликацијата да ги чита видеодатотеките од споделениот капацитет."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"да чита датотеки со слики од споделениот капацитет"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Дозволува апликацијата да ги чита датотеките со слики од споделениот капацитет."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"да чита датотеки со слики од споделениот капацитет"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Дозволува апликацијата да ги чита датотеките со слики од споделениот капацитет."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"ги менува или брише содржините на заедничкото место за складирање"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Дозволува апликацијата да ги пишува содржините на заедничкото место за складирање."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"остварува/прима повици преку SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Притисни „Мени“ да се отклучи или да направи итен повик."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Притиснете „Мени“ за да се отклучи."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Употребете ја шемата за да се отклучи"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Итен повик"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Итен случај"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Врати се на повик"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Точно!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Обидете се повторно"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Никогаш"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Немате дозвола да ја отворите страницава."</string>
<string name="text_copied" msgid="2531420577879738860">"Текстот е копиран на таблата со исечоци."</string>
- <string name="copied" msgid="4675902854553014676">"Копирано"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> залепи од <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> залепи од вашата привремена меморија"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> го залепи текстот што го копиравте"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Овозможува апликацијата да побара дозвола за игнорирање на оптимизациите на батеријата за таа апликација."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"пребарување на сите пакети"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Дозволува апликацијата да ги гледа сите инсталирани пакети."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"пристап до SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Дозволува апликацијата да пристапува до SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"да пристапува до AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Дозволува апликацијата да пристапува до AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"да пристапува до AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Дозволува апликацијата да пристапува до AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"да пристапува до AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Дозволува апликацијата да пристапува до AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Допрете двапати за контрола на зумот"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Не може да се додаде виџет."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Оди"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Се префрла на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> се одјавува…"</string>
<string name="owner_name" msgid="8713560351570795743">"Сопственик"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Гостин"</string>
<string name="error_message_title" msgid="4082495589294631966">"Грешка"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Администраторот не ја дозволува промената"</string>
<string name="app_not_found" msgid="3429506115332341800">"Не се пронајдени апликации да се изврши ова дејство"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ДЕИНСТАЛИРАЈ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"СЕПАК ОТВОРИ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Откриена е штетна апликација"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Барање за пристап до системска евиденција"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Да се дозволи <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> да пристапува до целата евиденција на уредот?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Само овој пат"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Не дозволувај"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> бара системска евиденција за отстранување грешка на функција. Оваа евиденција може да содржи податоци запишани од апликациите и услугите на уредот."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Дневниците за евиденција на уредот снимаат што се случува на вашиот уред. Апликациите може да ги користат овие дневници за евиденција за да наоѓаат и поправаат проблеми.\n\nНекои дневници за евиденција може да содржат чувствителни податоци, па затоа дозволете им пристап до сите дневници за евиденција на уредот само на апликациите во кои имате доверба. \n\nАко не ѝ дозволите на апликацијава да пристапува до сите дневници за евиденција на уредот, таа сепак ќе може да пристапува до сопствените дневници за евиденција, а производителот на вашиот уред можеби сепак ќе може да пристапува до некои дневници за евиденција или податоци на уредот. Дознајте повеќе"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Не прикажувај повторно"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> сака да прикажува делови од <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Измени"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> работи во заднина веќе долго време. Допрете за да прегледате."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверете ги активните апликации"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Не може да се пристапи до камерата од уредов"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 7e95a70..403fbc1 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"നിങ്ങളുടെ കാരിയർ, സിം <xliff:g id="SIMNUMBER">%d</xliff:g> താൽക്കാലികമായി ഓഫാക്കി"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"മൊബൈൽ നെറ്റ്വർക്കിലേക്ക് കണക്റ്റ് ചെയ്യാനാവുന്നില്ല"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"തിരഞ്ഞെടുത്ത നെറ്റ്വർക്ക് മാറ്റുന്നത് പരീക്ഷിക്കുക. മാറ്റാൻ ടാപ്പ് ചെയ്യുക."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"എമർജൻസി കോളിംഗ് ലഭ്യമല്ല"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"വൈഫൈ വഴി എമർജൻസി കോളുകൾ ചെയ്യാനാകില്ല"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"എമർജൻസി കോളുകൾ ലഭ്യമായിരിക്കില്ല"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"വൈഫൈ ഉപയോഗിച്ചുള്ള എമർജൻസി കോളുകൾ <xliff:g id="SPN">%s</xliff:g> പിന്തുണയ്ക്കുന്നില്ല. വിശദാംശങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"അലേർട്ടുകൾ"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"കോൾ ഫോർവേഡിംഗ്"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"അടിയന്തര കോൾബാക്ക് മോഡ്"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ഇൻകമ്മിംഗ്-ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റയുൾപ്പെടെയുള്ള നിങ്ങളുടെ ടാബ്ലെറ്റിന്റെ കോൾ ചരിത്രം പരിഷ്ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു.ഇതു വഴി കോൾ ചരിത്ര ഡാറ്റകൾ പരിഷ്ക്കരിക്കാനും ഇല്ലാതാക്കാനും ദോഷകരമായ അപ്ലിക്കേഷനുകൾക്ക് കഴിഞ്ഞേയ്ക്കാം."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ഇൻകമിംഗ്, ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റ ഉൾപ്പെടെ നിങ്ങളുടെ Android TV-യിലെ കോൾ ചരിത്രം പരിഷ്ക്കരിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ കോൾ ചരിത്രം മായ്ക്കാനോ പരിഷ്ക്കരിക്കാനോ ദോഷകരമായ ആപ്പുകൾ ഇത് ഉപയോഗിച്ചേക്കാം."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ഇൻകമ്മിംഗ്-ഔട്ട്ഗോയിംഗ് കോളുകളെക്കുറിച്ചുള്ള ഡാറ്റയുൾപ്പെടെയുള്ള നിങ്ങളുടെ ഫോണിന്റെ കോൾ ചരിത്രം പരിഷ്ക്കരിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു.ഇതു വഴി കോൾ ചരിത്ര ഡാറ്റകൾ പരിഷ്ക്കരിക്കാനും ഇല്ലാതാക്കാനും ദോഷകരമായ അപ്ലിക്കേഷനുകൾക്ക് കഴിഞ്ഞേയ്ക്കാം."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"ശരീര സെൻസറുകൾ (ഹൃദയമിടിപ്പ് നിരക്ക് മോണിറ്ററുകൾ പോലെ) ആക്സസ് ചെയ്യുക"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"ഹൃദയമിടിപ്പ്, താപനില, രക്തത്തിലെ ഓക്സിജന്റെ ശതമാനം മുതലായവ പോലുള്ള ബോഡി സെൻസറുകളിൽ നിന്നുള്ള ഡാറ്റയിലേക്കുള്ള ആക്സസ്."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"പശ്ചാത്തലത്തിൽ ബോഡി സെൻസറുകൾ (ഹൃദയമിടിപ്പ് മോണിറ്ററുകൾ പോലുള്ളവ) ആക്സസ് ചെയ്യുക"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"പശ്ചാത്തലത്തിൽ ആയിരിക്കുമ്പോൾ ഹൃദയമിടിപ്പ്, താപനില, രക്തത്തിലെ ഓക്സിജന്റെ ശതമാനം മുതലായവ പോലുള്ള ബോഡി സെൻസറുകളിൽ നിന്നുള്ള ഡാറ്റയിലേക്കുള്ള ആക്സസ്."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ഉപയോഗത്തിലുള്ളപ്പോൾ, ഹൃദയമിടിപ്പ് പോലുള്ള ബോഡി സെൻസർ ഡാറ്റ ആക്സസ് ചെയ്യുക"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ആപ്പ് ഉപയോഗത്തിലുള്ളപ്പോൾ അതിനെ ഹൃദയമിടിപ്പ്, ശരീരോഷ്മാവ്, രക്തത്തിലെ ഓക്സിജൻ ശതമാനം എന്നിവ പോലുള്ള ബോഡി സെൻസർ ഡാറ്റ ആക്സസ് ചെയ്യാൻ അനുവദിക്കുന്നു."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"പശ്ചാത്തലത്തിലുള്ളപ്പോൾ ഹൃദയമിടിപ്പ് പോലുള്ള ബോഡി സെൻസർ ഡാറ്റ ആക്സസ് ചെയ്യുക"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ആപ്പ് പശ്ചാത്തലത്തിലുള്ളപ്പോൾ അതിനെ ഹൃദയമിടിപ്പ്, ശരീരോഷ്മാവ്, രക്തത്തിലെ ഓക്സിജൻ ശതമാനം എന്നിവ പോലുള്ള ബോഡി സെൻസർ ഡാറ്റ ആക്സസ് ചെയ്യാൻ അനുവദിക്കുന്നു."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"കലണ്ടർ ഇവന്റുകളും വിശദാംശങ്ങളും വായിക്കുക"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ഈ ആപ്പിന് നിങ്ങളുടെ ടാബ്ലെറ്റിൽ സംഭരിച്ചിരിക്കുന്ന എല്ലാ കലണ്ടർ ഇവന്റുകളും വായിക്കാനും നിങ്ങളുടെ കലണ്ടർ വിവരങ്ങൾ പങ്കിടാനും അല്ലെങ്കിൽ സംരക്ഷിക്കാനും കഴിയും."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ഈ ആപ്പിന് നിങ്ങളുടെ Android TV-യിൽ സംഭരിച്ചിരിക്കുന്ന എല്ലാ കലണ്ടർ ഇവന്റുകളും വായിക്കാനും നിങ്ങളുടെ കലണ്ടർ ഡാറ്റ പങ്കിടാനോ സംരക്ഷിക്കാനോ സാധിക്കുകയും ചെയ്യും."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"നിങ്ങളുടെ പങ്കിട്ട സ്റ്റോറേജിൽ നിന്നുള്ള ഓഡിയോ ഫയലുകൾ വായിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"പങ്കിട്ട സ്റ്റോറേജിൽ നിന്നുള്ള വീഡിയോ ഫയലുകൾ വായിക്കുക"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"നിങ്ങളുടെ പങ്കിട്ട സ്റ്റോറേജിൽ നിന്നുള്ള വീഡിയോ ഫയലുകൾ വായിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"പങ്കിട്ട സ്റ്റോറേജിൽ നിന്നുള്ള ചിത്ര ഫയലുകൾ വായിക്കുക"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"നിങ്ങളുടെ പങ്കിട്ട സ്റ്റോറേജിൽ നിന്നുള്ള ചിത്ര ഫയലുകൾ വായിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"പങ്കിട്ട സ്റ്റോറേജിൽ നിന്നുള്ള ചിത്ര ഫയലുകൾ വായിക്കുക"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"നിങ്ങളുടെ പങ്കിട്ട സ്റ്റോറേജിൽ നിന്നുള്ള ചിത്ര ഫയലുകൾ വായിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"നിങ്ങൾ പങ്കിടുന്ന സ്റ്റോറേജിലെ ഉള്ളടക്കങ്ങൾ പരിഷ്ക്കരിക്കുക അല്ലെങ്കിൽ ഇല്ലാതാക്കുക"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"നിങ്ങൾ പങ്കിടുന്ന സ്റ്റോറേജിലെ ഉള്ളടക്കങ്ങൾ എഴുതാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP കോളുകൾ വിളിക്കുക/സ്വീകരിക്കുക"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"അൺലോക്ക് ചെയ്യുന്നതിനായി മെനു അമർത്തുക അല്ലെങ്കിൽ അടിയന്തര കോൾ വിളിക്കുക."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"അൺലോക്കുചെയ്യാൻ മെനു അമർത്തുക."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"അൺലോക്ക് ചെയ്യാൻ പാറ്റേൺ വരയ്ക്കുക"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"എമർജൻസി കോൾ"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"എമർജൻസി"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"കോളിലേക്ക് മടങ്ങുക"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"ശരി!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"വീണ്ടും ശ്രമിക്കുക"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"ഒരിക്കലും"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"ഈ പേജ് തുറക്കുന്നതിന് നിങ്ങൾക്ക് അനുമതിയില്ല."</string>
<string name="text_copied" msgid="2531420577879738860">"ടെക്സ്റ്റ് ക്ലിപ്ബോർഡിലേക്ക് പകർത്തി."</string>
- <string name="copied" msgid="4675902854553014676">"പകർത്തി"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> എന്നതിൽ നിന്ന് <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ഒട്ടിച്ചു"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> നിങ്ങളുടെ ക്ലിപ്പ്ബോർഡിൽ നിന്ന് ഒട്ടിച്ചു"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> നിങ്ങൾ പകർത്തിയ ടെക്സ്റ്റ് ഒട്ടിച്ചു"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ആപ്പിന് വേണ്ടിയുള്ള ബാറ്ററി ഒപ്റ്റിമൈസേഷനുകളെ അവഗണിക്കാനുള്ള അനുമതി ചോദിക്കുന്നതിന് ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"എല്ലാ പാക്കേജുകളും നോക്കുക"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"ഇൻസ്റ്റാൾ ചെയ്ത എല്ലാ പാക്കേജുകളും കാണാൻ ഒരു ആപ്പിനെ അനുവദിക്കുന്നു."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis ആക്സസ് ചെയ്യുക"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"SupplementalApis ആക്സസ് ചെയ്യാൻ ഒരു ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API ആക്സസ് ചെയ്യൂ"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"AdServices Topics API ആക്സസ് ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API-കൾ ആക്സസ് ചെയ്യൂ"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"AdServices Attribution API-കൾ ആക്സസ് ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API ആക്സസ് ചെയ്യൂ"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"AdServices Custom Audiences API ആക്സസ് ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"സൂം നിയന്ത്രണം ലഭിക്കാൻ രണ്ടുതവണ ടാപ്പുചെയ്യുക"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"വിജറ്റ് ചേർക്കാനായില്ല."</string>
<string name="ime_action_go" msgid="5536744546326495436">"പോവുക"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിലേക്ക് മാറുന്നു…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> ലോഗൌട്ട് ചെയ്യുന്നു…"</string>
<string name="owner_name" msgid="8713560351570795743">"ഉടമ"</string>
+ <string name="guest_name" msgid="8502103277839834324">"അതിഥി"</string>
<string name="error_message_title" msgid="4082495589294631966">"പിശക്"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ഈ മാറ്റം നിങ്ങളുടെ അഡ്മിൻ അനുവദിക്കുന്നില്ല"</string>
<string name="app_not_found" msgid="3429506115332341800">"ഈ പ്രവർത്തനം കൈകാര്യം ചെയ്യുന്ന അപ്ലിക്കേഷനുകളൊന്നും കണ്ടെത്തിയില്ല"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"അൺഇൻസ്റ്റാള് ചെയ്യുക"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"എന്തായാലും തുറക്കുക"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"ദോഷകരമായ ആപ്പ് കണ്ടെത്തി"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"സിസ്റ്റം ലോഗ് ആക്സസ് അഭ്യർത്ഥന"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"എല്ലാ ഉപകരണ ലോഗുകളും ആക്സസ് ചെയ്യാൻ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"ഇപ്രാവശ്യം മാത്രം"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"അനുവദിക്കരുത്"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>, ഫംഗ്ഷണൽ ഡീബഗ്ഗിംഗിന് സിസ്റ്റം ലോഗുകൾ അഭ്യർത്ഥിക്കുന്നു. ഈ ലോഗുകളിൽ, നിങ്ങളുടെ ഉപകരണത്തിലെ ആപ്പുകളും സേവനങ്ങളും രേഖപ്പെടുത്തിയ വിവരങ്ങൾ അടങ്ങിയേക്കാം."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"നിങ്ങളുടെ ഉപകരണത്തിൽ എന്തൊക്കെയാണ് സംഭവിക്കുന്നതെന്ന് ഉപകരണ ലോഗുകൾ റെക്കോർഡ് ചെയ്യുന്നു. പ്രശ്നങ്ങൾ കണ്ടെത്തി പരിഹരിക്കുന്നതിന് ആപ്പുകൾക്ക് ഈ ലോഗുകൾ ഉപയോഗിക്കാൻ കഴിയും.\n\nചില ലോഗുകളിൽ സൂക്ഷ്മമായി കൈകാര്യം ചെയ്യേണ്ട വിവരങ്ങൾ അടങ്ങിയിരിക്കാൻ സാധ്യതയുള്ളതിനാൽ, നിങ്ങൾക്ക് വിശ്വാസമുള്ള ആപ്പുകളെ മാത്രം എല്ലാ ഉപകരണ ലോഗുകളും ആക്സസ് ചെയ്യാൻ അനുവദിക്കുക. \n\nഎല്ലാ ഉപകരണ ലോഗുകളും ആക്സസ് ചെയ്യാൻ നിങ്ങൾ ഈ ആപ്പിനെ അനുവദിക്കുന്നില്ലെങ്കിൽ പോലും ആപ്പിന് അതിന്റെ സ്വന്തം ലോഗുകൾ ആക്സസ് ചെയ്യാനാകും, നിങ്ങളുടെ ഉപകരണ നിർമ്മാതാവിന് ഉപകരണത്തിലെ ചില ലോഗുകളോ വിവരങ്ങളോ തുടർന്നും ആക്സസ് ചെയ്യാനായേക്കും. കൂടുതലറിയുക"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"വീണ്ടും കാണിക്കരുത്"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_2">%2$s</xliff:g> സ്ലൈസുകൾ കാണിക്കാൻ <xliff:g id="APP_0">%1$s</xliff:g> താൽപ്പര്യപ്പെടുന്നു"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"എഡിറ്റ് ചെയ്യുക"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"പശ്ചാത്തലത്തിൽ <xliff:g id="APP">%1$s</xliff:g> ആപ്പ് ഒരുപാട് നേരമായി റൺ ചെയ്യുന്നു. അവലോകനം ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"സജീവമായ ആപ്പുകൾ പരിശോധിക്കുക"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"ഈ ഉപകരണത്തിൽ നിന്ന് ക്യാമറ ആക്സസ് ചെയ്യാനാകില്ല"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 98c7ef5..cb7bcaf 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"<xliff:g id="SIMNUMBER">%d</xliff:g> SIM-н оператор компаниас түр унтраасан"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобайл сүлжээнд холбогдох боломжгүй байна"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Сонгосон сүлжээг өөрчлөхөөр оролдоно уу. Өөрчлөхийн тулд товшино уу."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Яаралтай дуудлага хийх боломжгүй"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi‑Fi-р яаралтай дуудлага хийх боломжгүй байна"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Яаралтай дуудлага боломжгүй байж магадгүй"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-р яаралтай дуудлага хийхийг дэмждэггүй. Дэлгэрэнгүйг харахын тулд товшино уу."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Сануулга"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Дуудлага шилжүүлэх"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Яаралтай дуудлага хийх горим"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Апп нь таны таблетын ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг унших боломжтой. Хортой апп нь энийг ашиглан таны дуудлагын логыг өөрчлөх болон арилгах боломжтой."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Аппад таны Android TV төхөөрөмжийн ирсэн болон залгасан дуудлага зэрэг өгөгдөл бүхий дуудлагын жагсаалтыг өөрчлөхийг зөвшөөрнө. Хортой аппууд үүнийг ашиглан таны дуудлагын жагсаалтыг устгаж эсвэл өөрчилж болзошгүй."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Апп нь таны утасны ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг өөрчлөх боломжтой. Хортой апп нь энийг ашиглан таны дуудлагын логыг өөрчлөх болон арилгах боломжтой."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"биеийн мэдрэгчид хандах (зүрхний хэмнэл шалгагч г.м)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Зүрхний хэм, температур, цусны хүчилтөрөгчийн хувь гэх мэт биеийн мэдрэгчийн өгөгдөлд хандана уу"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"арын дэвсгэрт ажиллах үед биеийн мэдрэгчид (зүрхний хэм хянагч гэх мэт) хандах"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Арын дэвсгэрт ажиллах үед зүрхний хэм, температур, цусны хүчилтөрөгчийн хувь гэх мэт биеийн мэдрэгчийн өгөгдөлд хандана уу."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Ашиглаж байх үедээ зүрхний хэм зэрэг биеийн мэдрэгчийн өгөгдөлд хандаарай"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Аппыг ашиглаж байх үедээ зүрхний хэм, температур болон цусны хүчилтөрөгчийн хувь зэрэг биеийн мэдрэгчийн өгөгдөлд хандах боломжтой."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Ард нь байх үед зүрхний хэм зэрэг биеийн мэдрэгчийн өгөгдөлд хандаарай"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Апп ард нь байх үед зүрхний хэм, температур, цусны хүчилтөрөгчийн хувь зэрэг биеийн мэдрэгчийн өгөгдөлд хандах боломжтой."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Календарийн арга хэмжээ, дэлгэрэнгүйг унших"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Энэ апп таны таблетад хадгалсан календарийн бүх арга хэмжээг унших, календарийн өгөгдлийг хуваалцах, хадгалах боломжтой."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Энэ апп таны Android TV төхөөрөмжид хадгалсан календарийн бүх арга хэмжээг унших болон таны календарийн өгөгдлийг хуваалцах эсвэл хадгалах боломжтой."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Аппад таны дундын хадгалах сангаас аудио файлыг унших боломжийг олгодог."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"дундын хадгалах сангаас видео файл унших"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Аппад таны дундын хадгалах сангаас видео файлыг унших боломжийг олгодог."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"дундын хадгалах сангаас зургийн файл унших"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Аппад таны дундын хадгалах сангаас зургийн файлыг унших боломжийг олгодог."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"дундын хадгалах сангаас зургийн файл унших"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Аппад таны дундын хадгалах сангаас зургийн файлыг унших зөвшөөрөл олгодог."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"дундын хадгалах сангийнхаа контентыг өөрчлөх эсвэл устгах"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Аппад таны дундын хадгалах сангийн контентыг бичихийг зөвшөөрдөг."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP дуудлага хийх/хүлээн авах"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Яаралтай дуудлага хийх буюу эсвэл түгжээг тайлах бол цэсийг дарна уу."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Тайлах бол цэсийг дарна уу."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Тайлах хээгээ зурна уу"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Яаралтай дуудлага"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Яаралтай тусламж"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Дуудлагаруу буцах"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Зөв!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Дахин оролдох"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Хэзээ ч үгүй"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Танд энэ хуудсыг нээх зөвшөөрөл байхгүй."</string>
<string name="text_copied" msgid="2531420577879738860">"Текст хуулагдав."</string>
- <string name="copied" msgid="4675902854553014676">"Хуулсан"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>-с буулгасан <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Таны түр санах ойгоос <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>-г буулгасан"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> таны хуулсан текстийг буулгасан"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Тухайн аппaaс батерейны оновчлол алгасах зөвшөөрөл асуухыг зөвшөөрдөг."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"бүх багцыг лавлах"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Аппап бүх суулгасан багцыг харахыг зөвшөөрнө."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis-д хандах"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Аппликэйшнд SupplementalApis-д хандах зөвшөөрлийг олгодог."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API-д хандах"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Аппликэйшнд AdServices Topics API-д хандах зөвшөөрөл олгодог."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API-д хандах"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Аппликэйшнд AdServices Attribution API-д хандах зөвшөөрөл олгодог."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API-д хандах"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Аппликэйшнд AdServices Custom Audiences API-д хандах зөвшөөрөл олгодог."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Өсгөх контрол дээр хоёр удаа товшино уу"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Виджет нэмж чадсангүй."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Очих"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> руу сэлгэж байна…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>-с гарч байна…"</string>
<string name="owner_name" msgid="8713560351570795743">"Эзэмшигч"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Зочин"</string>
<string name="error_message_title" msgid="4082495589294631966">"Алдаа"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Энэ өөрчлөлтийг админ зөвшөөрөөгүй байна"</string>
<string name="app_not_found" msgid="3429506115332341800">"Энэ ажиллагааг зохицуулах аппликейшн олдсонгүй."</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"УСТГАХ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ЯМАР Ч ТОХИОЛДОЛД НЭЭХ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Аюултай апп олдсон"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Системийн логийн хандалтын хүсэлт"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>-д төхөөрөмжийн бүх логт хандахыг зөвшөөрөх үү?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Зөвхөн энэ удаа"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Бүү зөвшөөр"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> функциональ дибаг хийх системийн логийг хүсдэг. Эдгээр лог нь таны төхөөрөмж дээрх апп болон үйлчилгээнүүдийн бичсэн мэдээллийг агуулж болно."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Төхөөрөмжийн лог нь таны төхөөрөмж дээр юу болж байгааг бичдэг. Аппууд эдгээр логийг асуудлыг олох болон засахад ашиглах боломжтой.\n\nЗарим лог эмзэг мэдээлэл агуулж байж магадгүй тул та зөвхөн итгэдэг аппууддаа төхөөрөмжийн бүх логт хандахыг зөвшөөрнө үү. \n\nХэрэв та энэ аппад төхөөрөмжийн бүх логт хандахыг зөвшөөрөхгүй бол энэ нь өөрийн логт хандах боломжтой хэвээр байх бөгөөд таны төхөөрөмж үйлдвэрлэгч таны төхөөрөмж дээрх зарим лог эсвэл мэдээлэлд хандах боломжтой хэвээр байж магадгүй. Нэмэлт мэдээлэл авах"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Дахиж бүү харуул"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> <xliff:g id="APP_2">%2$s</xliff:g>-н хэсгүүдийг (slices) харуулах хүсэлтэй байна"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Засах"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> дэвсгэрт удаан хугацааны турш ажиллаж байна. Хянахын тулд товшино уу."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Идэвхтэй аппуудыг шалгах"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Энэ төхөөрөмжөөс камер луу нэвтрэх боломжгүй байна"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index df8cbc0..0580e4a 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"<xliff:g id="SIMNUMBER">%d</xliff:g> सिमसाठी तुमच्या वाहकाने तात्पुरते बंद केले आहे"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"मोबाइल नेटवर्क उपलब्ध नाही"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"प्राधान्य दिलेले नेटवर्क बदलण्याचा प्रयत्न करा. बदलण्यासाठी टॅप करा."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"आणीबाणी कॉलिंग अनुपलब्ध"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"वाय-फाय वरून आणीबाणी कॉल करू शकत नाही"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"आणीबाणी कॉल कदाचित उपलब्ध नसतील"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> वाय-फाय वर आणीबाणी कॉलना सपोर्ट करत नाही. तपशीलांसाठी टॅप करा."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"अलर्ट"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"कॉल फॉरवर्डिंग"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"इमर्जन्सी कॉलबॅक मोड"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"येणार्या आणि केल्या जाणार्या कॉलविषयीच्या डेटासह, आपल्या टॅब्लेटचा कॉल लॉग सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"येणार्या आणि केल्या जाणार्या कॉलविषयीच्या डेटासह, तुमच्या Android TV डिव्हाइसचा कॉल लॉग सुधारित करण्यासाठी ॲपला अनुमती देते. दुर्भावनापूर्ण अॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"येणार्या आणि केल्या जाणार्या कॉलविषयीच्या डेटासह, आपल्या फोनचा कॉल लॉग सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"शरीर सेन्सर (हृदय गती मॉनिटरसारखे) अॅक्सेस करा"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"हार्ट रेट, तापमान, रक्तातील ऑक्सिजनची टक्केवारी इ. सारख्या शरीर सेन्सरवरील डेटाचा अॅक्सेस आहे."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"बॅकग्राउंडमध्ये असताना शरीर सेन्सर (जसे की हार्ट रेट मॉनिटर) अॅक्सेस करा"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"बॅकग्राउंडमध्ये असताना हार्ट रेट, तापमान, रक्तातील ऑक्सिजनची टक्केवारी इ. सारखा शरीर सेन्सरवरील डेटा अॅक्सेस करा."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"वापरात असताना, हार्ट रेट यासारखा शरीर सेन्सर डेटा अॅक्सेस करा"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ॲप वापरात असताना हार्ट रेट, तापमान आणि रक्तातील ऑक्सिजनची टक्केवारी यांसारखा शरीर सेन्सर डेटा अॅक्सेस करण्याची अनुमती ॲपला द्या."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"बॅकग्राउंडमध्ये असताना, हार्ट रेट यासारखा शरीर सेन्सर डेटा अॅक्सेस करा"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ॲप हे बॅकग्राउंडमध्ये असताना हार्ट रेट, तापमान आणि रक्तातील ऑक्सिजनची टक्केवारी यांसारखा शरीर सेन्सर डेटा अॅक्सेस करण्याची अनुमती ॲपला द्या."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"कॅलेंडर इव्हेंट आणि तपशील वाचा"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"हा अॅप आपल्या टॅब्लेटवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"हे अॅप तुमच्या Android TV डिव्हाइसवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"ॲपला तुमच्या शेअर केलेल्या स्टोरेजमधून ऑडिओ फाइल वाचण्याची अनुमती देते."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"शेअर केलेल्या स्टोरेजमधून व्हिडिओ फाइल वाचा"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"ॲपला तुमच्या शेअर केलेल्या स्टोरेजमधून व्हिडिओ फाइल वाचण्याची अनुमती देते."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"शेअर केलेल्या स्टोरेजमधून इमेज फाइल वाचा"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"ॲपला तुमच्या शेअर केलेल्या स्टोरेजमधून इमेज फाइल वाचण्याची अनुमती देते."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"शेअर केलेल्या स्टोरेजमधून इमेज फाइल वाचा"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"ॲपला तुमच्या शेअर केलेल्या स्टोरेजमधून इमेज फाइल वाचण्याची अनुमती देते."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"तुमच्या शेअर केलेल्या स्टोरेजच्या आशयांमध्ये सुधारणा करा किंवा हटवा"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"ॲपला तुमच्या शेअर केलेल्या स्टोरेजचे आशय लिहिण्याची अनमती देते."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP कॉल करा/प्राप्त करा"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"अनलॉक करण्यासाठी मेनू दाबा किंवा आणीबाणीचा कॉल करा."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"अनलॉक करण्यासाठी मेनू दाबा."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"अनलॉक करण्यासाठी पॅटर्न काढा"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"आणीबाणी कॉल"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"आणीबाणी"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"कॉलवर परत या"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"अचूक!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"पुन्हा प्रयत्न करा"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"कधीही नाही"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"तुम्हाला हे पृष्ठ उघडण्याची परवानगी नाही."</string>
<string name="text_copied" msgid="2531420577879738860">"मजकूर क्लिपबोर्डवर कॉपी केला."</string>
- <string name="copied" msgid="4675902854553014676">"कॉपी केले"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> वरून <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> पेस्ट केले"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ने तुमच्या क्लिपबोर्डवरून पेस्ट केले"</string>
<string name="pasted_text" msgid="4298871641549173733">"तुम्ही कॉपी केलेला मजकूर <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ने पेस्ट केला"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"त्या ॲपसाठी बॅटरी ऑप्टिमायझेशन दुर्लक्षित करण्यासाठी ॲपला परवानगी मागण्याची अनुमती देते."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"सर्व पॅकेजविषयी क्वेरी करा"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"ॲपला इंस्टॉल केलेले सर्व पॅकेज पाहण्याची अनुमती देते."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis अॅक्सेस करा"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"अॅप्लिकेशनला SupplementalApis अॅक्सेस करण्याची अनुमती देते."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API अॅक्सेस करा"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"अॅप्लिकेशनला AdServices Topics API अॅक्सेस करण्याची अनुमती देते."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API अॅक्सेस करा"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"अॅप्लिकेशनला AdServices Attribution API अॅक्सेस करण्याची अनुमती देते."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API अॅक्सेस करा"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"अॅप्लिकेशनला AdServices Custom Audiences API अॅक्सेस करण्याची अनुमती देते."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"झूम नियंत्रणासाठी दोनदा टॅप करा"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"विजेट जोडू शकलो नाही."</string>
<string name="ime_action_go" msgid="5536744546326495436">"जा"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> वर स्विच करत आहे…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> लॉग आउट करत आहे…"</string>
<string name="owner_name" msgid="8713560351570795743">"मालक"</string>
+ <string name="guest_name" msgid="8502103277839834324">"अतिथी"</string>
<string name="error_message_title" msgid="4082495589294631966">"एरर"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"या बदलास आपल्या प्रशासकाद्वारे अनुमती नाही"</string>
<string name="app_not_found" msgid="3429506115332341800">"ही क्रिया हाताळण्यासाठी कोणताही ॲप्लिकेशन आढळला नाही"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"अनइंस्टॉल करा"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"तरीही उघडा"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"हानिकारक अॅप आढळला"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"सिस्टीम लॉगच्या अॅक्सेसची विनंती"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ला सर्व डिव्हाइस लॉग अॅक्सेस करण्याची अनुमती द्यायची आहे का?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"फक्त यावेळी"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"अनुमती देऊ नका"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> हे फंक्शनल डीबगिंगसाठी सिस्टीम लॉगची विनंती करते. या लॉगमध्ये तुमच्या डिव्हाइसवरील ॲप्स आणि सेवांनी लिहिलेली माहिती असू शकते."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"तुमच्या डिव्हाइसवर काय होते ते डिव्हाइस लॉग रेकॉर्ड करते. समस्या शोधण्यासाठी आणि त्यांचे निराकरण करण्याकरिता ॲप्स हे लॉग वापरू शकतात.\n\nकाही लॉगमध्ये संवेदनशील माहिती असू शकते, त्यामुळे फक्त तुमचा विश्वास असलेल्या ॲप्सना सर्व डिव्हाइस लॉग अॅक्सेस करण्याची अनुमती द्या. \n\nतुम्ही या ॲपला सर्व डिव्हाइस लॉग अॅक्सेस करण्याची अनुमती न दिल्यास, ते तरीही त्याचा स्वतःचा लॉग अॅक्सेस करू शकते आणि तुमच्या डिव्हाइसचा उत्पादक तरीही काही लॉग किंवा तुमच्या डिव्हाइसवरील माहिती अॅक्सेस करू शकतो. अधिक जाणून घ्या"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"पुन्हा दाखवू नका"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ला <xliff:g id="APP_2">%2$s</xliff:g> चे तुकडे दाखवायचे आहेत"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"संपादित करा"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> हे बऱ्याच कालावधीपासून बॅकग्राउंडमध्ये रन होत आहे. पुनरावलोकनासाठी टॅप करा."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ॲक्टिव्ह ॲप्स पहा"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"या डिव्हाइसवरून कॅमेरा अॅक्सेस करू शकत नाही"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index b35f61a..d14138a 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Dimatikan untuk sementara waktu oleh pembawa anda untuk SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Tidak dapat mencapai rangkaian mudah alih"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Cuba tukar rangkaian pilihan. Ketik untuk menukar."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Panggilan kecemasan tidak tersedia"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Tidak boleh membuat panggilan kecemasan melalui Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Panggilan kecemasan mungkin tidak tersedia"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> tidak menyokong panggilan kecemasan melalui Wi-Fi. Ketik untuk mendapatkan butiran."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Makluman"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Pemajuan panggilan"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mod paggil balik kecemasan"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Membenarkan apl untuk mengubah suai panggilan tablet anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai log panggilan anda."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Membenarkan apl mengubah suai log panggilan peranti Android TV anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakan keupayaan ini untuk memadamkan atau mengubah suai log panggilan anda."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Membenarkan apl untuk mengubah suai panggilan telefon anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai log panggilan anda."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"akss pndia bdn (spt pmntau kdr dnyt jntg)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Akses kepada data daripada penderia tubuh seperti kadar denyut jantung, suhu, peratusan oksigen darah, dsb."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"akses penderia tubuh (seperti pemantau kadar denyut jantung) semasa di latar"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Akses kepada data daripada penderia tubuh seperti kadar denyut jantung, suhu, peratusan oksigen darah, dsb. semasa di latar."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Akses data penderia tubuh, seperti kadar denyut jantung, semasa digunakan"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Membenarkan apl mengakses data penderia tubuh, seperti kadar denyut jantung, suhu dan peratusan oksigen darah, semasa apl digunakan."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Akses data penderia tubuh, seperti kadar denyut jantung, semasa berjalan di latar belakang"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Membenarkan apl mengakses data penderia tubuh, seperti kadar denyut jantung, suhu dan peratusan oksigen darah, semasa apl berjalan di latar belakang."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Baca acara dan butiran kalendar"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Apl ini boleh membaca semua acara kalendar yang disimpan pada tablet anda dan berkongsi atau menyimpan data kalendar anda."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Apl ini boleh membaca semua acara kalendar yang disimpan pada peranti Android TV anda dan berkongsi atau menyimpan data kalendar anda."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Membenarkan apl membaca fail audio daripada storan kongsi anda."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"baca fail video daripada storan kongsi"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Membenarkan apl membaca fail video daripada storan kongsi anda."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"baca fail imej daripada storan kongsi"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Membenarkan apl membaca fail imej daripada storan kongsi anda."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"baca fail imej daripada storan kongsi"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Membenarkan apl membaca fail imej daripada storan kongsi anda."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"mengubah suai atau memadamkan kandungan storan kongsi anda"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Membenarkan apl menulis kandungan storan kongsi anda."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"buat/terima panggilan SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Tekan Menu untuk menyahsekat atau membuat panggilan kecemasan."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Tekan Menu untuk membuka kunci."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Lukiskan corak untuk membuka kunci"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Panggilan kecemasan"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Kecemasan"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Kembali ke panggilan"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Betul!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Cuba lagi"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Jangan sekali-kali"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Anda tidak mempunyai kebenaran untuk membuka laman ini."</string>
<string name="text_copied" msgid="2531420577879738860">"Teks disalin ke papan keratan"</string>
- <string name="copied" msgid="4675902854553014676">"Disalin"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ditampalkan daripada <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ditampal daripada papan keratan anda"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> telah menampal teks yang anda salin"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Membenarkan apl meminta kebenaran untuk mengabaikan pengoptimuman bateri untuk apl itu."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"buat pertanyaan untuk semua pakej"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Membenarkan apl melihat semua pakej yang dipasang."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"akses SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Membenarkan aplikasi mengakses SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"akses API Topik AdServices"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Membenarkan aplikasi mengakses API Topik AdServices."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"akses API Atribusi AdServices"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Membenarkan aplikasi mengakses API Atribusi AdServices."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"akses API Khalayak Tersuai AdServices"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Membenarkan aplikasi mengakses API Khalayak Tersuai AdServices."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Ketik dua kali untuk mendapatkan kawalan zum"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Tidak dapat menambahkan widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Pergi"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Bertukar kepada <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Log keluar daripada <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Pemilik"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Tetamu"</string>
<string name="error_message_title" msgid="4082495589294631966">"Ralat"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Perubahan ini tidak dibenarkan oleh pentadbir anda"</string>
<string name="app_not_found" msgid="3429506115332341800">"Tidak menemui aplikasi untuk mengendalikan tindakan ini"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"NYAHPASANG"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"BUKA JUGA"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Apl berbahaya dikesan"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Permintaan akses log sistem"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Benarkan <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> mengakses semua log peranti?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Kali ini sahaja"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Jangan benarkan"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> meminta log sistem untuk penyahpepijatan berfungsi. Log ini mungkin mengandungi maklumat yang telah ditulis apl dan perkhidmatan pada peranti anda."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Log peranti merekodkan perkara yang berlaku pada peranti anda. Apl dapat menggunakan log ini untuk menemukan dan membetulkan isu.\n\nSesetengah log mungkin mengandungi maklumat sensitif, jadi benarkan apl yang anda percaya sahaja untuk mengakses semua log peranti. \n\nJika anda tidak membenarkan apl ini mengakses semua log peranti, apl masih boleh mengakses log sendiri dan pengilang peranti anda mungkin masih boleh mengakses sesetengah log atau maklumat pada peranti anda. Ketahui lebih lanjut"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Jangan tunjuk lagi"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> mahu menunjukkan <xliff:g id="APP_2">%2$s</xliff:g> hirisan"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g>sedang berjalan di latar belakang untuk masa yang lama. Ketik untuk menyemak."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Semak apl aktif"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Tidak dapat mengakses kamera daripada peranti ini"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index bcd11a2..3e53812f 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"ဆင်းမ် <xliff:g id="SIMNUMBER">%d</xliff:g> အတွက် သင်၏ ဝန်ဆောင်မှုပေးသူက ယာယီပိတ်ထားပါသည်"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"မိုဘိုင်းကွန်ရက် လိုင်းမရပါ"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ဦးစားပေးကွန်ရက်သို့ ပြောင်းကြည့်ပါ။ ပြောင်းရန် တို့ပါ။"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"အရေးပေါ်ခေါ်ဆိုမှု မရနိုင်ပါ"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi‑Fi ဖြင့် အရေးပေါ်ခေါ်ဆိုမှုများ ပြုလုပ်၍မရပါ"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"အရေးပေါ်ဖုန်းခေါ်ခြင်းများ မရနိုင်ပါ"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"Wi-Fi ဖြင့် အရေးပေါ်ဖုန်းခေါ်ခြင်းကို <xliff:g id="SPN">%s</xliff:g> က ပံ့ပိုးမထားပါ။ အသေးစိတ်အချက်အလက်များအတွက် တို့ပါ။"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"သတိပေးချက်များ"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"အဝင်ခေါ်ဆိုမှုအား ထပ်ဆင့်ပို့ခြင်း"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"အရေးပေါ် ပြန်လည်ခေါ်ဆိုနိုင်သောမုဒ်"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"အပလီကေးရှင်းအား သင့်တက်ဘလက်၏ ဖုန်းခေါ်ဆိုမှု မှတ်တမ်း (အဝင်အထွက်ခေါ်ဆိုမှု အချက်အလက်များ) ကို ပြင်ဆင်ခွင့် ပေးခြင်း။ အန္တရာယ်ရှိ အပလီကေးရှင်းများမှ ဤအချက်ကို အသုံးပြု၍ သင့် ဖုန်းခေါ်ဆိုမှု မှတ်တမ်းကို ဖျက်ပစ်ခြင်း၊ ပြင်ဆင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"အဝင်နှင့် အထွက်ခေါ်ဆိုမှု အချက်အလက်များ အပါအဝင် သင့် Android TV စက်ပစ္စည်းပေါ်ရှိ ခေါ်ဆိုထားသော မှတ်တမ်းကို အက်ပ်အား မွမ်းမံခွင့်ပြုသည်။ သံသယဖြစ်နိုင်ဖွယ်ရှိသည့် အက်ပ်များသည် ၎င်းကို အသုံးပြုပြီး သင်၏ ခေါ်ဆိုထားသော မှတ်တမ်းကို ဖျက်နိုင်သည်။"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"အပလီကေးရှင်းအား သင့်ဖုန်း၏ ဖုန်းခေါ်ဆိုမှု မှတ်တမ်း (အဝင်အထွက်ခေါ်ဆိုမှု အချက်အလက်များ) ကို ပြင်ဆင်ခွင့် ပေးခြင်း။ အန္တရာယ်ရှိ အပလီကေးရှင်းများမှ ဤအချက်ကို အသုံးပြု၍ သင့် ဖုန်းခေါ်ဆိုမှု မှတ်တမ်းကို ဖျက်ပစ်ခြင်း၊ ပြင်ဆင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"ခန္ဓာကိုယ် အာရုံကိရိယာများကို (နှလုံးခုန်နှုန်း မော်နီတာလို)ကို ရယူသုံးရန်"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"နှလုံးခုန်နှုန်း၊ အပူချိန်၊ သွေးတွင်း အောက်ဆီဂျင် ရာခိုင်နှုန်း စသည့် ခန္ဓာကိုယ် အာရုံခံကိရိယာများမှ ဒေတာသုံးခွင့်။"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"(နှလုံးခုန်နှုန်း စောင့်ကြည့်ခြင်းကဲ့သို့) ခန္ဓာကိုယ် အာရုံခံကိရိယာများကို နောက်ခံ၌သုံးခွင့်"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"နှလုံးခုန်နှုန်း၊ အပူချိန်၊ သွေးတွင်း အောက်ဆီဂျင် ရာခိုင်နှုန်း စသည့် ခန္ဓာကိုယ် အာရုံခံကိရိယာများမှ ဒေတာကို နောက်ခံ၌သုံးခွင့်။"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"သုံးနေစဉ် နှလုံးခုန်နှုန်းကဲ့သို့ ခန္ဓာကိုယ်အာရုံခံစနစ် ဒေတာ သုံးခြင်း"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"အက်ပ်သုံးစဉ် နှလုံးခုန်နှုန်း၊ အပူချိန်၊ သွေးတွင်း အောက်ဆီဂျင်ရာခိုင်နှုန်းကဲ့သို့ ခန္ဓာကိုယ်အာရုံခံစနစ် ဒေတာများသုံးရန် အက်ပ်ကိုခွင့်ပြုသည်။"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"နောက်ခံတွင်ဖွင့်စဉ် နှလုံးခုန်နှုန်းကဲ့သို့ ခန္ဓာကိုယ်အာရုံခံစနစ် ဒေတာ သုံးခြင်း"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"နောက်ခံတွင်အက်ပ်ဖွင့်စဉ် နှလုံးခုန်နှုန်း၊ အပူချိန်၊ သွေးတွင်း အောက်ဆီဂျင်ရာခိုင်နှုန်းကဲ့သို့ ခန္ဓာကိုယ်အာရုံခံစနစ် ဒေတာများသုံးရန် အက်ပ်ကိုခွင့်ပြုသည်။"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"ပြက္ခဒိန်ဖြစ်ရပ်များနှင့် အသေးစိတ်အချက်အလက်များကို ဖတ်ခြင်း"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ဤအက်ပ်သည် သင့်တက်ဘလက်တွင် သိမ်းဆည်းထားသည့် ပြက္ခဒိန်ဖြစ်ရပ်များကို ကြည့်ရှုနိုင်ပြီး သင့်ပြက္ခဒိန်ဒေတာများကို မျှဝေခြင်းနှင့် သိမ်းဆည်းခြင်းတို့ ပြုလုပ်နိုင်ပါသည်။"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ဤအက်ပ်သည် သင့် Android TV စက်ပစ္စည်းတွင် သိမ်းဆည်းထားသည့် ပြက္ခဒိန်ဖြစ်ရပ်များအားလုံးကို ဖတ်နိုင်ပြီး သင်၏ ပြက္ခဒိန်ဒေတာများကို မျှဝေခြင်း သို့မဟုတ် သိမ်းဆည်းခြင်းတို့ ပြုလုပ်နိုင်သည်။"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"သင်၏မျှဝေထားသော သိုလှောင်ခန်းမှ အသံဖိုင်များဖတ်ရန် အက်ပ်ကိုခွင့်ပြုသည်။"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"မျှဝေထားသော သိုလှောင်ခန်းမှ ဗီဒီယိုဖိုင်များဖတ်ရန်"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"သင်၏မျှဝေထားသော သိုလှောင်ခန်းမှ ဗီဒီယိုဖိုင်များဖတ်ရန် အက်ပ်ကိုခွင့်ပြုသည်။"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"မျှဝေထားသော သိုလှောင်ခန်းမှ ပုံပါဝင်သောဖိုင်များဖတ်ရန်"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"သင်၏မျှဝေထားသော သိုလှောင်ခန်းမှ ပုံပါဝင်သောဖိုင်များဖတ်ရန် အက်ပ်ကိုခွင့်ပြုသည်။"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"မျှဝေထားသည့် သိုလှောင်ခန်းမှ ပုံပါဝင်သောဖိုင်များဖတ်ရန်"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"သင်၏မျှဝေထားသည့် သိုလှောင်ခန်းမှ ပုံပါဝင်သောဖိုင်များဖတ်ရန် အက်ပ်ကို ခွင့်ပြုသည်။"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"မျှဝေသိုလှောင်ခန်းမှ အရာများ ပြုပြင်/ဖျက်ခြင်း"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"မျှဝေသိုလှောင်ခန်းမှ အရာများ ရေးခွင့်ပြုသည်။"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP ခေါ်ဆိုမှုများ ခေါ်ရန်/လက်ခံရန်"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"ဖွင့်ရန်သို့မဟုတ်အရေးပေါ်ခေါ်ဆိုခြင်းပြုလုပ်ရန် မီနူးကိုနှိပ်ပါ"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"မီးနူးကို နှိပ်ခြင်းဖြင့် သော့ဖွင့်ပါ"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"ဖွင့်ရန်ပုံစံဆွဲပါ"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"အရေးပေါ် ခေါ်ဆိုမှု"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"အရေးပေါ်"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"ခေါ်ဆိုမှုထံပြန်သွားရန်"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"မှန်ပါသည်"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"ထပ် စမ်းပါ"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"လုံးဝ မလုပ်ပါ"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"သင့်ဆီမှာ ဒီစာမျက်နှာကို ဖွင့်ရန် ခွင့်ပြုချက် မရှိပါ။"</string>
<string name="text_copied" msgid="2531420577879738860">"clipboardထံ စာသားအားကူးယူမည်"</string>
- <string name="copied" msgid="4675902854553014676">"မိတ္တူကူးပြီးပါပြီ"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> မှ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> သို့ ကူးထည့်ထားသည်"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> က သင့်ကလစ်ဘုတ်မှ ကူးထည့်ထားသည်"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> က သင်မိတ္တူကူးထားသော စာသားကို ထည့်လိုက်သည်"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ဘက်ထရီ ပိုမိုကောင်းမွန်အောင် ပြုလုပ်ခြင်းကို လျစ်လျူရှုရန်အတွက် ခွင့်ပြုချက်တောင်းရန် အက်ပ်ကို ခွင့်ပြုပါ။"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"ပက်ကေ့ဂျ်အားလုံးကို မေးမြန်းခြင်း"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"ထည့်သွင်းထားသော ပက်ကေ့ဂျ်အားလုံး ကြည့်ရန် အက်ပ်ကို ခွင့်ပြုပါ။"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis သုံးခွင့်"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"အပလီကေးရှင်းအား SupplementalApis သုံးခွင့်ပေးနိုင်သည်။"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API သုံးခွင့်"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"AdServices Topics API ကို အပလီကေးရှင်းတစ်ခုအား သုံးခွင့်ပေးနိုင်သည်။"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API များ သုံးခွင့်"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"AdServices Attribution API များကို အပလီကေးရှင်းတစ်ခုအား သုံးခွင့်ပေးနိုင်သည်။"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API သုံးခွင့်"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"AdServices Custom Audiences API ကို အပလီကေးရှင်းတစ်ခုအား သုံးခွင့်ပေးနိုင်သည်။"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ဇူးမ်အသုံးပြုရန် နှစ်ချက်တို့ပါ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ဝဒ်ဂျက်ထည့်လို့ မရပါ"</string>
<string name="ime_action_go" msgid="5536744546326495436">"သွားပါ"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>သို့ ပြောင်းနေ…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>ကို ထွက်ပစ်ပါတော့မည်..."</string>
<string name="owner_name" msgid="8713560351570795743">"ပိုင်ရှင်"</string>
+ <string name="guest_name" msgid="8502103277839834324">"ဧည့်သည်"</string>
<string name="error_message_title" msgid="4082495589294631966">"အမှား"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ဤပြောင်းလဲမှုကို သင်၏ စီမံခန့်ခွဲသူက ခွင့်မပြုပါ"</string>
<string name="app_not_found" msgid="3429506115332341800">"ဤလုပ်ဆောင်ချက်ကို ပြုလုပ်ပေးမည့် အပလီကေးရှင်းမရှိပါ။"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ဖြုတ်ရန်"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ဘာဖြစ်ဖြစ် ဖွင့်ရန်"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"အန္တရာယ်ရှိသော အက်ပ်ကို တွေ့ရှိထားသည်"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"စနစ်မှတ်တမ်းသုံးခွင့် တောင်းဆိုခြင်း"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ကို စက်မှတ်တမ်းအားလုံး သုံးခွင့်ပြုမလား။"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"ဤတစ်ကြိမ်သာ"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"ခွင့်မပြုပါ"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"အမှားရှာပြင်မှု လုပ်ဆောင်နိုင်ရန်အတွက် စနစ်မှတ်တမ်းများကို <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> က တောင်းဆိုသည်။ ဤမှတ်တမ်းများတွင် သင်၏စက်ပေါ်ရှိအက်ပ်နှင့် ဝန်ဆောင်မှုများ ရေးထားသော အချက်အလက်များ ပါဝင်နိုင်သည်။"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"သင့်စက်ရှိ အဖြစ်အပျက်များကို စက်မှတ်တမ်းများက မှတ်တမ်းတင်သည်။ အက်ပ်များက ပြဿနာများ ရှာဖွေပြီးဖြေရှင်းရန် ဤမှတ်တမ်းများကို သုံးနိုင်သည်။\n\nအချို့မှတ်တမ်းများတွင် သတိထားရမည့်အချက်အလက်များ ပါဝင်နိုင်သဖြင့် စက်မှတ်တမ်းအားလုံးကို ယုံကြည်ရသည့် အက်ပ်များကိုသာ သုံးခွင့်ပြုပါ။ \n\nဤအက်ပ်ကို စက်မှတ်တမ်းအားလုံး သုံးခွင့်မပြုသော်လည်း ၎င်းက ကိုယ်ပိုင်မှတ်တမ်းကို သုံးနိုင်ဆဲဖြစ်ပြီး သင့်စက်ရှိ အချို့မှတ်တမ်းများ (သို့) အချက်အလက်များကို သင့်စက်ထုတ်လုပ်သူက သုံးနိုင်ပါသေးသည်။ ပိုမိုလေ့လာရန်"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"နောက်ထပ်မပြပါနှင့်"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> သည် <xliff:g id="APP_2">%2$s</xliff:g> ၏အချပ်များကို ပြသလိုသည်"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"တည်းဖြတ်ရန်"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> သည် နောက်ခံတွင် အချိန်အတော်ကြာပွင့်နေသည်။ ပြန်ကြည့်ရန် တို့ပါ။"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ပွင့်နေသည့်အက်ပ်များ စစ်ဆေးရန်"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"ကင်မရာကို ဤစက်မှ အသုံးမပြုနိုင်ပါ"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index b6e2121..27fa108 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Midlertidig deaktivert av operatøren din for SIM-kortet <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Får ikke kontakt med mobilnettverket"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prøv å endre foretrukket nettverk. Trykk for å endre."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Nødanrop er utilgjengelig"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Kan ikke ringe nødnumre via Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Nødanrop kan være utilgjengelig"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> støtter ikke nødanrop via Wi-Fi. Trykk for å se mer informasjon."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Varsler"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Viderekobling"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modusen nødsamtale-tilbakeringing"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Lar appen endre nettbrettets samtalelogg, inkludert data om innkommende og utgående anrop. Skadelige apper kan utnytte denne tillatelsen til å slette eller endre samtaleloggen din."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Lar appen endre samtaleloggen på Android TV-enheten din, inkludert data om innkommende og utgående anrop. Skadelige apper kan bruke denne tillatelsen til å slette eller endre samtaleloggen din."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Lar appen endre telefonens samtalelogg, inkludert data om innkommende og utgående anrop. Skadelige apper kan utnytte denne tillatelsen til å slette eller endre samtaleloggen din."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"få tilgang til kroppssensorer (f.eks. pulsmålere)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Tilgang til data fra kroppssensorer, for eksempel puls, temperatur, oksygenmetning i blodet osv."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"få tilgang til kroppssensorer (f.eks. pulsmålere) i bakgrunnen"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Tilgang til data fra kroppssensorer, for eksempel puls, temperatur, oksygenmetning i blodet osv., i bakgrunnen."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Tilgang til data fra kroppssensorer, for eksempel puls, når den er i bruk"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gir appen tilgang til data fra kroppssensorer, for eksempel puls, temperatur og oksygenmetning i blodet, når den er i bruk."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Tilgang til data fra kroppssensorer, for eksempel puls, når den er i bakgrunnen"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gir appen tilgang til data fra kroppssensorer, for eksempel puls, temperatur og oksygenmetning i blodet, når den er i bakgrunnen."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Les kalenderaktivitet og detaljer"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Denne appen kan lese all kalenderaktivitet som er lagret på nettbrettet ditt, og dele eller lagre kalenderdataene."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Denne appen kan lese all kalenderaktivitet som er lagret på Android TV-enheten din, og dele eller lagre kalenderdataene."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Lar appen lese lydfiler fra den delte lagringsplassen din."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"lese videofiler fra delt lagringsplass"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Lar appen lese videofiler fra den delte lagringsplassen din."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"lese bildefiler fra delt lagringsplass"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Lar appen lese bildefiler fra den delte lagringsplassen din."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"lese bildefiler fra delt lagringsplass"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Lar appen lese bildefiler fra den delte lagringsplassen din."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"endre eller slette innholdet i den delte lagringen din"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Lar appen skrive innholdet i den delte lagringen din."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"foreta/motta SIP-anrop"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Trykk på menyknappen for å låse opp eller ringe et nødnummer."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Trykk på menyknappen for å låse opp."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Tegn mønster for å låse opp"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Nødanrop"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Nødssituasjon"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Tilbake til samtale"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Riktig!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Prøv på nytt"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Aldri"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Du har ikke tillatelse til å åpne denne siden."</string>
<string name="text_copied" msgid="2531420577879738860">"Kopierte tekst til utklippstavlen."</string>
- <string name="copied" msgid="4675902854553014676">"Kopiert"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> limte inn fra <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> har limt inn fra utklippstavlen"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> limte inn tekst du kopierte"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Gjør det mulig for apper å be om tillatelse til å ignorere batterioptimaliseringer for disse appene."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"søk i alle pakker"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Lar en app se alle installerte pakker."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"tilgang til SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Gir appen tilgang til SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"bruke AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Gir en app tilgang til AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"bruke AdServices Attribution-API-er"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Gir en app tilgang til AdServices Attribution-API-er."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"bruke AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Gir en app tilgang til AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Trykk to ganger for zoomkontroll"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Kunne ikke legge til modulen."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Utfør"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Bytter til <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Logger av <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="owner_name" msgid="8713560351570795743">"Eier"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gjest"</string>
<string name="error_message_title" msgid="4082495589294631966">"Feil"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Denne endringen er ikke tillatt av administratoren"</string>
<string name="app_not_found" msgid="3429506115332341800">"Finner ingen apper som kan utføre denne handlingen"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"AVINSTALLER"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ÅPNE LIKEVEL"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"En skadelig app ble oppdaget"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Forespørsel om tilgang til systemlogg"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vil du gi <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> tilgang til alle enhetslogger?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Bare denne gangen"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ikke tillat"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ber om systemlogger for funksjonell feilsøking. Disse loggene kan inneholde informasjon som apper og tjenester på enheten din har skrevet."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Enhetslogger registrerer det som skjer på enheten din. Apper kan bruke disse loggene til å finne og løse problemer.\n\nNoen logger kan inneholde sensitiv informasjon, så du bør bare gi tilgang til alle enhetslogger til apper du stoler på. \n\nHvis du ikke gir denne appen tilgang til alle enhetslogger, har den fremdeles tilgang til sine egne logger, og enhetsprodusenten kan fremdeles ha tilgang til noen logger eller noe informasjon på enheten din. Finn ut mer"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ikke vis igjen"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> vil vise <xliff:g id="APP_2">%2$s</xliff:g>-utsnitt"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Endre"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> kjører lenge i bakgrunnen. Trykk for å gjennomgå."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Sjekk aktive apper"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Du har ikke tilgang til kameraet fra denne enheten"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 0ecf8a7..6f1d72e 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> का लागि तपाईंको सेवा प्रदायकले अस्थायी रूपमा निष्क्रिय पार्नुभएको"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"मोबाइल नेटवर्कमाथि पहुँच राख्न सकिएन"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"रुचाइएको नेटवर्क परिवर्तन गरी हेर्नुहोस्। परिवर्तन गर्न ट्याप गर्नुहोस्।"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"आपत्कालीन कल सेवा अनुपलब्ध छ"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi‑Fi मार्फत आपत्कालीन कल गर्न सकिँदैन"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"आपत्कालीन कल गर्ने सुविधा उपलब्ध नहुन सक्छ"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> प्रयोग गरेर Wi-Fi मार्फत आपत्कालीन कल गर्न मिल्दैन। विवरणहरू हेर्न ट्याप गर्नुहोस्।"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"अलर्टहरू"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"कल फर्वार्ड गर्ने सेवा"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"आपत्कालीन कलब्याक मोड"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"आगमन तथा बहर्गमन डेटासहित तपाईँको ट्याब्लेटको कल लगको परिमार्जन गर्न एपलाई अनुमति दिन्छ। खराब एपहरूले यसलाई तपाईँको कल लग परिमार्जन गर्न वा मेटाउन प्रयोग गर्न सक्छन्।"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"एपलाई तपाईंको Android टिभी डिभाइसको आगमन र बहिर्गमन कलसम्बन्धी डेटासहित कल लग परिमार्जन गर्ने अनुमति दिन्छ। हानिकारक एपहरूले यसलाई तपाईंको कल लग मेटाउन वा परिमार्जन गर्न प्रयोग गर्न सक्छन्।"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"एपलाई तपाईंको फोनको आउने र बाहिर जाने कलहरूको बारेको डेटा सहित कल लग परिमार्जन गर्न अनुमति दिन्छ। खराब एपहरूले यसलाई तपाईंको कल लग मेटाउन वा परिमार्जन गर्न प्रयोग गर्न सक्दछ।"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"शरीरका सेन्सरहरूमा पहुँच गराउनुहोस् (जस्तै हृदय धड्कन निगरानीहरू)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"बडी सेन्सरका सहायताले हृदयको गति, शरीरको तापक्रम, रगतमा रहेको अक्सिजनको प्रतिशतलगायतका डेटा हेर्ने अनुमति।"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"ब्याकग्राउन्डमा काम गर्ने बडी सेन्सरका सहायताले (हृदयको गति मापन जस्ता) डेटा हेर्ने अनुमति"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"ब्याकग्राउन्डमा काम गर्ने बडी सेन्सरका सहायताले हृदयको गति, शरीरको तापक्रम, रगतमा रहेको अक्सिजनको प्रतिशतलगायतका डेटा हेर्ने अनुमति।"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"प्रयोग गरिएका बेला हृदयको गति जस्ता बडी सेन्सरसम्बन्धी डेटा हेरियोस् र प्रयोग गरियोस्"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"यसले यो एप प्रयोग गरिँदै गरेका बेला यसलाई हृदयको गति, शरीरको तापक्रम तथा रगतमा रहेको अक्सिजनको प्रतिशत जस्ता बडी सेन्सरसम्बन्धी डेटा हेर्ने तथा प्रयोग गर्ने अनुमति दिन्छ।"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ब्याकग्राउन्डमा चलेका बेला हृदयको गति जस्ता बडी सेन्सरसम्बन्धी डेटा हेरियोस् र प्रयोग गरियोस्"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"यसले यो एप ब्याकग्राउन्डमा चलेका बेला यसलाई हृदयको गति, शरीरको तापक्रम तथा रगतमा रहेको अक्सिजनको प्रतिशत जस्ता बडी सेन्सरसम्बन्धी डेटा हेर्ने तथा प्रयोग गर्ने अनुमति दिन्छ।"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"पात्रोका कार्यक्रम र विवरणहरू पढ्ने"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"यस एपले तपाईंको ट्याब्लेटमा भण्डारण गरिएका पात्रो सम्बन्धी सबै कार्यक्रमहरू पढ्न र तपाईंको पात्रोको डेटा आदान प्रदान वा सुरक्षित गर्न सक्छ।"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"यस एपले तपाईंको Android टिभी डिभाइसमा भण्डार गरिएका पात्रोसम्बन्धी सबै कार्यक्रमहरू पढ्न र तपाईंको पात्रोको डेटा आदान प्रदान वा सुरक्षित गर्न सक्छ।"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"एपलाई तपाईंको साझा भण्डारणमा भएका अडियो फाइलहरू पढ्ने अनुमति दिन्छ।"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"साझा भण्डारणमा भएका भिडियो फाइलहरू पढ्ने"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"एपलाई तपाईंको साझा भण्डारणमा भएका भिडियो फाइलहरू पढ्ने अनुमति दिन्छ।"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"साझा भण्डारणमा भएका फोटो फाइलहरू पढ्ने"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"एपलाई तपाईंको साझा भण्डारणमा भएका फोटो फाइलहरू पढ्ने अनुमति दिन्छ।"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"साझा भण्डारणमा भएका फोटो फाइलहरू पढ्ने"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"एपलाई तपाईंको साझा भण्डारणमा भएका फोटो फाइलहरू पढ्ने अनुमति दिन्छ।"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"तपाईंको आदान प्रदान गरिएको भण्डारणको विषयवस्तुहरूलाई परिमार्जन गर्नहोस् वा मेटाउनुहोस्"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"एपलाई तपाईंको आदान प्रदान गरिएको भण्डारणको सामग्री लेख्न अनुमति दिन्छ।"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP कलहरू प्राप्त/बनाउन"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"अनलक वा आपत्कालीन कल गर्न मेनु थिच्नुहोस्।"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"अनलक गर्न मेनु थिच्नुहोस्।"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"अनलक गर्नु ढाँचा खिच्नुहोस्"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"आपत्कालीन कल"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"आपत्कालीन"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"कलमा फर्किनुहोस्"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"सही!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"फेरि प्रयास गर्नुहोस्"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"कहिल्यै पनि होइन"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"यो पृष्ठ खोल्न तपाईँलाई अनुमति छैन।"</string>
<string name="text_copied" msgid="2531420577879738860">"क्लिपबोर्डमा प्रतिलिप गरिएको पाठ।"</string>
- <string name="copied" msgid="4675902854553014676">"प्रतिलिपि गरियो"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> मा रहेको डेटा कपी गरी <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> मा पेस्ट गरियो"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ले तपाईंको क्लिपबोर्डमा रहेको जानकारी पेस्ट गरेको छ"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ले तपाईंले कपी गरेको टेक्स्ट पेस्ट गरेको छ"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"कुनै एपलाई त्यसका ब्याट्री सम्बन्धी अनुकूलनहरूलाई बेवास्ता गर्नाका लागि अनुमति माग्न दिन्छ।"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"सबै प्याकेजहरू खोज्नुहोस्"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"यसले यस एपलाई इन्स्टल गरिएका सबै प्याकेजहरू हेर्ने अनुमति दिन्छ।"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis प्रयोग गर्ने अनुमति"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"एपलाई SupplementalApis प्रयोग गर्ने अनुमति दिन्छ।"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API प्रयोग गर्ने अनुमति"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"एपलाई AdServices Topics API प्रयोग गर्ने अनुमति दिन्छ।"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API प्रयोग गर्ने अनुमति"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"एपलाई AdServices Attribution API प्रयोग गर्ने अनुमति दिन्छ।"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API प्रयोग गर्ने अनुमति"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"एपलाई AdServices Custom Audiences API प्रयोग गर्ने अनुमति दिन्छ।"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"जुम नियन्त्रणको लागि दुई चोटि ट्याप गर्नुहोस्"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"विजेट थप गर्न सकिँदैन।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"जानुहोस्"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"स्विच गरेर <xliff:g id="NAME">%1$s</xliff:g> बनाइँदै..."</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"लग आउट गर्दै <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"मालिक"</string>
+ <string name="guest_name" msgid="8502103277839834324">"अतिथि"</string>
<string name="error_message_title" msgid="4082495589294631966">"त्रुटि"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"तपाईंका प्रशासकले यो परिवर्तनलाई अनुमति दिनुहुन्न"</string>
<string name="app_not_found" msgid="3429506115332341800">"यस कार्य सम्हालने कुनै एप भेटिएन"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"स्थापना रद्द गर्नु…"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"जे भए पनि खोल्नुहोस्"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"हानिकारक एप भेटियो"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"सिस्टम लग प्रयोग गर्ने अनुमति"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> लाई डिभाइसका सबै लग हेर्ने अनुमति दिने हो?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"यस पटक मात्र"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"अनुमति नदिनुहोस्"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ले फङ्सनल डिबग प्रक्रियाका लागि सिस्टम लगहरू हेर्ने तथा प्रयोग गर्ने अनुमति माग्दै छ। यी लगहरूमा तपाईंको डिभाइसमा रहेका एप र सेवाहरूले राइट गरेको जानकारी समावेश हुन सक्छ।"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"डिभाइसका लगमा तपाईंको डिभाइसमा भएका विभिन्न गतिविधिको अभिलेख राखिन्छ। एपहरू यी लगका आधारमा समस्या पत्ता लगाउन र तिनको समाधान गर्न सक्छन्।\n\nकेही लगहरूमा संवेदनशील जानकारी समावेश हुन सक्ने भएकाले आफूले भरोसा गर्ने एपलाई मात्र डिभाइसका सबै लग हेर्ने अनुमति दिनुहोस्। \n\nतपाईंले यो एपलाई डिभाइसका सबै लग हेर्ने अनुमति दिनुभएन भने पनि यसले आफ्नै लग भने हेर्न सक्छ। यसै गरी तपाईंको डिभाइसको उत्पादकले पनि तपाईंको डिभाइसमा भएका केही लग वा जानकारी हेर्न सक्ने सम्भावना हुन्छ। थप जान्नुहोस्"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"फेरि नदेखाइयोस्"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ले <xliff:g id="APP_2">%2$s</xliff:g> का स्लाइसहरू देखाउन चाहन्छ"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"सम्पादन गर्नुहोस्"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> लामो समयदेखि ब्याकग्राउन्डमा चलिरहेको छ। समीक्षा गर्न ट्याप गर्नुहोस्।"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"कुन कुन एप सक्रिय छ भन्ने कुरा जाँच्नुहोस्"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"यो डिभाइसमा भएको क्यामेरा प्रयोग गर्न सकिएन"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 508200f..cbd2f54 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Tijdelijk uitgezet door je provider voor sim <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Kan mobiel netwerk niet bereiken"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probeer een ander voorkeursnetwerk. Tik om te wijzigen."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Noodoproepen niet beschikbaar"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Er kunnen geen noodoproepen worden gemaakt via wifi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Noodoproepen zijn misschien niet beschikbaar"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> biedt geen ondersteuning voor noodoproepen via wifi. Tik voor details."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Meldingen"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Gesprek doorschakelen"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modus voor noodoproepen"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Toestaan dat de app de gesprekslijst van je tablet aanpast, waaronder gegevens over inkomende en uitgaande gesprekken. Schadelijke apps kunnen hiermee je gesprekslijst wissen of aanpassen."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Toestaan dat de app de gesprekslijst van je Android TV-apparaat aanpast, waaronder gegevens over inkomende en uitgaande gesprekken. Schadelijke apps kunnen hiermee je gesprekslijst wissen of aanpassen."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Toestaan dat de app de gesprekslijst van je telefoon aanpast, waaronder gegevens over inkomende en uitgaande gesprekken. Schadelijke apps kunnen hiermee je gesprekslijst wissen of aanpassen."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"toegang tot lichaamssensoren (zoals hartslagmeters)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Toegang tot gegevens van lichaamssensoren, zoals hartslag, temperatuur en zuurstofpercentage in het bloed."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"toegang tot lichaamssensoren (zoals hartslagmeters) op de achtergrond"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Toegang tot gegevens van lichaamssensoren, zoals hartslag, temperatuur en zuurstofpercentage in het bloed, terwijl de app op de achtergrond wordt uitgevoerd."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Toegang tot gegevens van lichaamssensoren, zoals hartslag, tijdens gebruik"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"De app heeft toegang tot gegevens van lichaamssensoren, zoals hartslag, temperatuur en zuurstofpercentage in het bloed, terwijl de app wordt gebruikt."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Toegang tot gegevens van lichaamssensoren, zoals hartslag, op de achtergrond"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"De app heeft toegang tot gegevens van lichaamssensoren, zoals hartslag, temperatuur en zuurstofpercentage in het bloed, terwijl de app op de achtergrond wordt uitgevoerd."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Agenda-afspraken en -gegevens lezen"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Deze app kan alle agenda-afspraken lezen die zijn opgeslagen op je tablet en je agendagegevens delen of opslaan."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Deze app kan alle agenda-afspraken lezen die zijn opgeslagen op je Android TV-apparaat en je agendagegevens delen of opslaan."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Hiermee kan de app audiobestanden in je gedeelde opslag lezen."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"videobestanden in gedeelde opslag lezen"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Hiermee kan de app videobestanden in je gedeelde opslag lezen."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"afbeeldingsbestanden in gedeelde opslag lezen"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Hiermee kan de app afbeeldingsbestanden in je gedeelde opslag lezen."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"afbeeldingsbestanden in gedeelde opslag lezen"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Hiermee kan de app afbeeldingsbestanden in je gedeelde opslag lezen."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"de content van je gedeelde opslag aanpassen of verwijderen"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Hiermee kan de app de content van je gedeelde opslag schrijven."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"Bellen of gebeld worden via SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Druk op \'Menu\' om te ontgrendelen of noodoproep te plaatsen."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Druk op \'Menu\' om te ontgrendelen."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Patroon tekenen om te ontgrendelen"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Noodoproep"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Noodgeval"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Terug naar gesprek"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Juist!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Opnieuw proberen"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nooit"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Je hebt geen rechten om deze pagina te openen."</string>
<string name="text_copied" msgid="2531420577879738860">"Tekst naar klembord gekopieerd."</string>
- <string name="copied" msgid="4675902854553014676">"Gekopieerd"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> geplakt vanuit <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> heeft geplakt vanaf het klembord"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> heeft door jou gekopieerde tekst geplakt"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Hiermee kan een app rechten vragen om batterijoptimalisatie voor die app te negeren."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"alle pakketten opvragen"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Hiermee kan een app alle geïnstalleerde pakketten zien."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"toegang tot SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Geeft een app toegang tot SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"toegang tot de AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Geeft een app toegang tot de AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"toegang tot AdServices Attribution API\'s"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Geeft een app toegang tot AdServices Attribution API\'s."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"toegang tot de AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Geeft een app toegang tot de AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tik twee keer voor zoomregeling"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Kan widget niet toevoegen."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ga"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Overschakelen naar <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> uitloggen…"</string>
<string name="owner_name" msgid="8713560351570795743">"Eigenaar"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gast"</string>
<string name="error_message_title" msgid="4082495589294631966">"Fout"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Deze wijziging is niet toegestaan door je beheerder"</string>
<string name="app_not_found" msgid="3429506115332341800">"Er is geen app gevonden om deze actie uit te voeren"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"VERWIJDEREN"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"TOCH OPENEN"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Schadelijke app gevonden"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Verzoek om toegang tot systeemlogboeken"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> toegang geven tot alle apparaatlogboeken?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Alleen deze keer"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Niet toestaan"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> vraagt om systeemlogboeken voor functionele foutopsporing. Deze logboeken kunnen informatie bevatten die apps en services op je apparaat hebben geschreven."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Apparaatlogboeken leggen vast wat er op je apparaat gebeurt. Apps kunnen deze logboeken gebruiken om problemen op te sporen en te verhelpen.\n\nSommige logboeken kunnen gevoelige informatie bevatten, dus geef alleen apps die je vertrouwt toegang tot alle apparaatlogboeken. \n\nAls je deze app geen toegang tot alle apparaatlogboeken geeft, heeft de app nog wel toegang tot de eigen logboeken. De fabrikant van je apparaat heeft misschien nog steeds toegang tot bepaalde logboeken of informatie op je apparaat. Meer informatie"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Niet opnieuw tonen"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wil segmenten van <xliff:g id="APP_2">%2$s</xliff:g> tonen"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Bewerken"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> wordt al lange tijd uitgevoerd op de achtergrond. Tik om te bekijken."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Actieve apps checken"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Kan geen toegang krijgen tot de camera vanaf dit apparaat"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 5a684a85..775d320 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> ପାଇଁ ଆପଣଙ୍କ କେରିଅର୍ ଦ୍ୱାରା ଅସ୍ଥାୟୀ ରୂପେ ବନ୍ଦ କରାଯାଇଛି"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ମୋବାଇଲ୍ ନେଟ୍ୱର୍କ ମିଳୁନାହିଁ"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ନିଜ ପସନ୍ଦର ନେଟ୍ୱର୍କକୁ ଯିବାପାଇଁ ଚେଷ୍ଟା କରନ୍ତୁ। ବଦଳାଇବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ଜରୁରୀକାଳୀନ କଲ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"ୱାଇ-ଫାଇ ସାହାଯ୍ୟରେ ଜରୁରୀକାଳୀନ କଲ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"ଜରୁରୀକାଳୀନ କଲଗୁଡ଼ିକ ଉପଲବ୍ଧ ହୋଇନପାରେ"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ୱାଇ-ଫାଇ ମାଧ୍ୟମରେ ଜରୁରୀକାଳୀନ କଲଗୁଡ଼ିକୁ ସମର୍ଥନ କରେ ନାହିଁ। ବିବରଣୀ ପାଇଁ ଟାପ କରନ୍ତୁ।"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"ଆଲର୍ଟ"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"କଲ୍ ଫରୱାର୍ଡିଂ"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"ଜରୁରୀକାଳୀନ କଲବ୍ୟାକ୍ ମୋଡ୍"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ଇନ୍କମିଙ୍ଗ ତଥା ଆଉଟ୍ଗୋଇଙ୍ଗ କଲ୍ ଡାଟା ସହ ଆପଣଙ୍କ ଟାବ୍ଲେଟ୍ର କଲ୍ ଲଗ୍ ବଦଳାଇବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦିଏ। ହାନୀକାରକ ଆପ୍ ଆପଣଙ୍କ କଲ୍ ଲଗ୍ ଲିଭାଇବାକୁ କିମ୍ବା ବଦଳାଇବାକୁ ଏହା ବ୍ୟବହାର କରିପାରନ୍ତି।"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ଇନ୍କମିଂ ତଥା ଆଉଟ୍ଗୋଇଂ କଲ୍ ଡାଟା ସହ ଆପଣଙ୍କ Android TV ଡିଭାଇସ୍ର କଲ୍ ଲଗ୍ ସଂଶୋଧନ କରିବାକୁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ। କ୍ଷତିକାରକ ଆପ୍ଗୁଡ଼ିକ ଆପଣଙ୍କ କଲ୍ ଲଗ୍ ଲିଭାଇବାକୁ କିମ୍ବା ସଂଶୋଧନ କରିବା ପାଇଁ ଏହାକୁ ବ୍ୟବହାର କରିପାରନ୍ତି।"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ଇନ୍କମିଙ୍ଗ ତଥା ଆଉଟ୍ଗୋଇଙ୍ଗ କଲ୍ ଡାଟା ସହ ଆପଣଙ୍କ ଫୋନ୍ର କଲ୍ ଲଗ୍ ବଦଳାଇବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦିଏ। ହାନୀକାରକ ଆପ୍ ଆପଣଙ୍କ କଲ୍ ଲଗ୍ ଲିଭାଇବାକୁ କିମ୍ବା ବଦଳାଇବାକୁ ଏହା ବ୍ୟବହାର କରିପାରନ୍ତି।"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"ବଡୀ ସେନ୍ସର୍ ଆକ୍ସେସ୍ କରେ (ଯେପରିକି ହୃଦ୍ ହାର ମନିଟର୍)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"ହାର୍ଟ ରେଟ, ତାପମାତ୍ରା, ରକ୍ତରେ ଅମ୍ଳଜାନ ଶତକଡ଼ା ଇତ୍ୟାଦି ପରି ବଡି ସେନ୍ସରରୁ ଡାଟାକୁ ଆକ୍ସେସ।"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"ପୃଷ୍ଠପଟରେ ଥିବା ସମୟରେ (ହାର୍ଟ ରେଟ ମନିଟର ପରି) ବଡି ସେନ୍ସରକୁ ଆକ୍ସେସ"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"ପୃଷ୍ଠପଟରେ ଥିବା ସମୟରେ ହାର୍ଟ ରେଟ, ତାପମାତ୍ରା, ରକ୍ତରେ ଅମ୍ଳଜାନ ଶତକଡ଼ା ଇତ୍ୟାଦି ପରି ବଡି ସେନ୍ସରରୁ ଡାଟାକୁ ଆକ୍ସେସ।"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ବ୍ୟବହାରରେ ଥିବା ସମୟରେ, ହାର୍ଟ ରେଟ ପରି ବଡି ସେନ୍ସର ଡାଟାକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ଏହି ଆପଟି ବ୍ୟବହାରରେ ଥିବା ସମୟରେ, ହାର୍ଟ ରେଟ ଏବଂ ତାପମାତ୍ରା, ରକ୍ତରେ ଅମ୍ଳଜାନ ଶତକଡ଼ା ପରି ବଡି ସେନ୍ସର ଡାଟାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ପୃଷ୍ଠପଟରେ ଥିବା ସମୟରେ, ହାର୍ଟ ରେଟ ପରି ବଡି ସେନ୍ସର ଡାଟାକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ଏହି ଆପଟି ପୃଷ୍ଠପଟରେ ଥିବା ସମୟରେ, ହାର୍ଟ ରେଟ, ତାପମାତ୍ରା ଏବଂ ରକ୍ତରେ ଅମ୍ଳଜାନ ଶତକଡ଼ା ପରି ବଡି ସେନ୍ସର ଡାଟାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"କ୍ୟାଲେଣ୍ଡର୍ ଇଭେଣ୍ଟ ଏବଂ ବିବରଣୀ ପଢ଼େ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ଆପଣଙ୍କ ଟାବଲେଟ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ସମସ୍ତ କ୍ୟାଲେଣ୍ଡର ଇଭେଣ୍ଟ ଏହି ଆପ୍ ପଢ଼ିପାରେ ଏବଂ ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର ଡାଟା ସେୟାର୍ କରିପାରେ କିମ୍ବା ସେଭ୍ କରିପାରେ।"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ଏହି ଆପ୍ ଆପଣଙ୍କ Android TV ଡିଭାଇସ୍ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ସମସ୍ତ କ୍ୟାଲେଣ୍ଡର ଇଭେଣ୍ଟ ପଢ଼ିପାରେ ଏବଂ ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର ଡାଟା ସେୟାର୍ କରିପାରେ କିମ୍ବା ସେଭ୍ କରିପାରେ।"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"ଆପଣଙ୍କ ସେୟାର କରାଯାଇଥିବା ଷ୍ଟୋରେଜରୁ ଅଡିଓ ଫାଇଲଗୁଡ଼ିକୁ ପଢ଼ିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"ସେୟାର କରାଯାଇଥିବା ଷ୍ଟୋରେଜରୁ ଭିଡିଓ ଫାଇଲଗୁଡ଼ିକୁ ପଢ଼ନ୍ତୁ"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"ଆପଣଙ୍କ ସେୟାର କରାଯାଇଥିବା ଷ୍ଟୋରେଜରୁ ଭିଡିଓ ଫାଇଲଗୁଡ଼ିକୁ ପଢ଼ିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"ସେୟାର କରାଯାଇଥିବା ଷ୍ଟୋରେଜରୁ ଇମେଜ ଫାଇଲଗୁଡ଼ିକୁ ପଢ଼ନ୍ତୁ"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"ଆପଣଙ୍କ ସେୟାର କରାଯାଇଥିବା ଷ୍ଟୋରେଜରୁ ଇମେଜ ଫାଇଲଗୁଡ଼ିକୁ ପଢ଼ିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"ସେୟାର କରାଯାଇଥିବା ଷ୍ଟୋରେଜରୁ ଇମେଜ ଫାଇଲଗୁଡ଼ିକୁ ପଢ଼ନ୍ତୁ"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"ଆପଣଙ୍କ ସେୟାର କରାଯାଇଥିବା ଷ୍ଟୋରେଜରୁ ଇମେଜ ଫାଇଲଗୁଡ଼ିକୁ ପଢ଼ିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"ଆପଣଙ୍କତ ସେୟାର୍ ହୋଇଥିବା ଷ୍ଟୋରେଜ୍ର ବିଷୟବସ୍ତୁ ସଂଶୋଧନ କିମ୍ବା ଡିଲିଟ୍ କରନ୍ତୁ"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"ଆପଣଙ୍କର ସେୟାର୍ ହୋଇଥିବା ଷ୍ଟୋରେଜ୍ର ବିଷୟବସ୍ତୁ ଲେଖିବାକୁ ଅନୁମତି କରିଥାଏ।"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP କଲ୍ କରନ୍ତୁ ଏବଂ ଗ୍ରହଣ କରନ୍ତୁ"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"ଅନଲକ୍ କରିବା ପାଇଁ ମେନୁକୁ ଦବାନ୍ତୁ କିମ୍ବା ଜରୁରୀକାଳୀନ କଲ୍ କରନ୍ତୁ।"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"ଅନଲକ୍ କରିବା ପାଇଁ ମେନୁକୁ ଦବାନ୍ତୁ।"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"ଅନଲକ୍ କରିବା ପାଇଁ ପାଟର୍ନ ଆଙ୍କନ୍ତୁ"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"ଜରୁରୀକାଳୀନ କଲ୍"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ଜରୁରୀକାଳୀନ"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"କଲ୍କୁ ଫେରନ୍ତୁ"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"ଠିକ୍!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"କଦାପି ନୁହେଁ"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"ଏହି ପୃଷ୍ଠା ଖୋଲିବାକୁ ଆପଣଙ୍କ ପାଖରେ ଅନୁମତି ନାହିଁ।"</string>
<string name="text_copied" msgid="2531420577879738860">"ଟେକ୍ସଟ୍ କ୍ଲିପବୋର୍ଡକୁ କପୀ ହୋଇଯାଇଛି"</string>
- <string name="copied" msgid="4675902854553014676">"କପି କରାଗଲା"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>ରୁ ପେଷ୍ଟ କରିଛି"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ କ୍ଲିପବୋର୍ଡରୁ ପେଷ୍ଟ କରିଛି"</string>
<string name="pasted_text" msgid="4298871641549173733">"ଆପଣ କପି କରିଥିବା ଟେକ୍ସଟକୁ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ପେଷ୍ଟ କରିଛି"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ଆପ୍ ପାଇଁ ବ୍ୟାଟେରୀ ଅନୁକୂଳନ ଏଡ଼ାଇବାର ଅନୁମତି ମାଗିବା ନିମନ୍ତେ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"ସବୁ ପ୍ୟାକେଜ୍ ବିଷୟରେ କ୍ୱେରୀ କରନ୍ତୁ"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"ଇନଷ୍ଟଲ୍ କରାଯାଇଥିବା ସମସ୍ତ ପ୍ୟାକେଜକୁ ଦେଖିବା ପାଇଁ ଏକ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApiଗୁଡ଼ିକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"SupplementalApiଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏକ ଆପ୍ଲିକେସନକୁ ଅନୁମତି ଦିଏ।"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics APIକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"AdServices Topics APIକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏକ ଆପ୍ଲିକେସନକୁ ଅନୁମତି ଦିଏ।"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution APIଗୁଡ଼ିକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"AdServices Attribution APIଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏକ ଆପ୍ଲିକେସନକୁ ଅନୁମତି ଦିଏ।"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences APIକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"AdServices Custom Audiences APIକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏକ ଆପ୍ଲିକେସନକୁ ଅନୁମତି ଦିଏ।"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ଜୁମ୍ ନିୟନ୍ତ୍ରଣ ପାଇଁ ଦୁଇଥର ଟାପ୍ କରନ୍ତୁ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ୱିଜେଟ୍ ଯୋଡ଼ିପାରିବ ନାହିଁ।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ଯାଆନ୍ତୁ"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ରେ ସ୍ୱିଚ୍ କରନ୍ତୁ…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>ଙ୍କୁ ଲଗଆଉଟ୍ କରାଯାଉଛି…"</string>
<string name="owner_name" msgid="8713560351570795743">"ମାଲିକ"</string>
+ <string name="guest_name" msgid="8502103277839834324">"ଅତିଥି"</string>
<string name="error_message_title" msgid="4082495589294631966">"ତ୍ରୁଟି"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ଏହି ପରିବର୍ତ୍ତନ ପାଇଁ ଆପଣଙ୍କ ଆଡମିନ୍ ଅନୁମତି ଦେଇନାହାଁନ୍ତି"</string>
<string name="app_not_found" msgid="3429506115332341800">"ଏହି କାର୍ଯ୍ୟକୁ ନିୟନ୍ତ୍ରଣ କରିବା ପାଇଁ କୌଣସି ଆପ୍ଲିକେଶନ୍ ମିଳିଲା ନାହିଁ"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ଅନଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"କୌଣସିମତେ ଖୋଲନ୍ତୁ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"ହାନିକାରକ ଆପ୍ ଚିହ୍ନଟ ହୋଇଛି"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"ସିଷ୍ଟମ ଲଗକୁ ଆକ୍ସେସ କରିବାର ଅନୁରୋଧ"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"କେବଳ ଏହି ଥର"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ଫଙ୍କସନାଲ ଡିବଗିଂ ପାଇଁ ସିଷ୍ଟମ ଲଗଗୁଡ଼ିକର ଅନୁରୋଧ କରୁଛି। ଆପଣଙ୍କ ଡିଭାଇସରେ ଥିବା ଆପ ଏବଂ ସେବାଗୁଡ଼ିକ ଲେଖିଥିବା ସୂଚନା ଏହି ଲଗଗୁଡ଼ିକରେ ଥାଇପାରେ।"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଯାହା ହୁଏ ତାହା ଡିଭାଇସ ଲଗଗୁଡ଼ିକ ରେକର୍ଡ କରେ। ସମସ୍ୟାଗୁଡ଼ିକୁ ଖୋଜି ସମାଧାନ କରିବାକୁ ଆପ୍ସ ଏହି ଲଗଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିପାରିବ।\n\nକିଛି ଲଗରେ ସମ୍ବେଦନଶୀଳ ସୂଚନା ଥାଇପାରେ, ତେଣୁ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପଣ ବିଶ୍ୱାସ କରୁଥିବା ଆପ୍ସକୁ ହିଁ ଅନୁମତି ଦିଅନ୍ତୁ। \n\nଯଦି ଆପଣ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଅନ୍ତି ନାହିଁ, ତେବେ ବି ଏହା ନିଜର ଡିଭାଇସ ଲଗଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିପାରିବ ଏବଂ ଆପଣଙ୍କ ଡିଭାଇସର ନିର୍ମାତା ଏବେ ବି ଆପଣଙ୍କର ଡିଭାଇସରେ କିଛି ଲଗ କିମ୍ବା ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ସକ୍ଷମ ହୋଇପାରନ୍ତି। ଅଧିକ ଜାଣନ୍ତୁ"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>, <xliff:g id="APP_2">%2$s</xliff:g> ସ୍ଲାଇସ୍କୁ ଦେଖାଇବା ପାଇଁ ଚାହେଁ"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"ଏଡିଟ୍ କରନ୍ତୁ"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ଦୀର୍ଘ ସମୟ ଧରି ପୃଷ୍ଠପଟରେ ଚାଲୁଛି। ସମୀକ୍ଷା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ସକ୍ରିୟ ଆପଗୁଡ଼ିକୁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"ଏହି ଡିଭାଇସରୁ କ୍ୟାମେରାକୁ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 5ee2088..94d1507 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"ਸਿਮ <xliff:g id="SIMNUMBER">%d</xliff:g> ਤੁਹਾਡੇ ਕੈਰੀਅਰ ਵੱਲੋਂ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਹੈ"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ਤਰਜੀਹੀ ਨੈੱਟਵਰਕ ਨੂੰ ਬਦਲ ਕੇ ਦੇਖੋ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ਸੰਕਟਕਾਲੀਨ ਕਾਲਿੰਗ ਉਪਲਬਧ ਨਹੀਂ"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"ਵਾਈ-ਫਾਈ ਰਾਹੀਂ ਸੰਕਟਕਾਲੀਨ ਕਾਲਾਂ ਨਹੀਂ ਕਰ ਸਕਦੇ"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"ਸ਼ਾਇਦ ਐਮਰਜੈਂਸੀ ਕਾਲਾਂ ਉਪਲਬਧ ਨਾ ਹੋਣ"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ਵੱਲੋਂ ਵਾਈ-ਫਾਈ \'ਤੇ ਐਮਰਜੈਂਸੀ ਕਾਲਾਂ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"ਸੁਚੇਤਨਾਵਾਂ"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"ਕਾਲ ਫਾਰਵਰਡਿੰਗ"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"ਸੰਕਟਕਾਲੀਨ ਕਾਲਬੈਕ ਮੋਡ"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਸਮੇਤ। ਖਰਾਬ ਐਪਾਂ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ ਦਾ ਕਾਲ ਲੌਗ ਸੋਧਣ ਦਿੰਦੀ ਹੈ, ਇਸ ਵਿੱਚ ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਵੀ ਸ਼ਾਮਲ ਹੈ। ਭੈੜੀਆਂ ਐਪਾਂ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਕਾਲ ਲੌਗ ਡਾਟਾ ਮਿਟਾ ਜਾਂ ਸੋਧ ਸਕਦੀਆਂ ਹਨ।"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਸਮੇਤ। ਖਰਾਬ ਐਪਾਂ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"ਸਰੀਰ ਸੰਵੇਦਕਾਂ \'ਤੇ ਪਹੁੰਚ ਕਰੋ (ਜਿਵੇਂ ਦਿਲ ਦੀ ਧੜਕਣ ਦੇ ਨਿਰੀਖਕ)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰਾਂ ਜਿਵੇਂ ਕਿ ਦਿਲ ਦੀ ਧੜਕਣ, ਤਾਪਮਾਨ, ਖੂਨ ਵਿੱਚ ਮੌਜੂਦ ਆਕਸੀਜਨ ਦੀ ਫ਼ੀਸਦ ਆਦਿ ਤੋਂ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ।"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਰਹਿੰਦੇ ਹੋਏ (ਜਿਵੇਂ ਕਿ ਦਿਲ ਦੀ ਧੜਕਣ ਮਾਪਣ ਵਾਲੇ ਮਾਨੀਟਰ) ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਰਹਿੰਦੇ ਹੋਏ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰਾਂ ਜਿਵੇਂ ਕਿ ਦਿਲ ਦੀ ਧੜਕਣ, ਤਾਪਮਾਨ, ਖੂਨ ਵਿੱਚ ਮੌਜੂਦ ਆਕਸੀਜਨ ਦੀ ਫ਼ੀਸਦ ਆਦਿ ਤੋਂ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ।"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ਵਰਤੋਂ ਵਿੱਚ ਹੋਣ \'ਤੇ ਦਿਲ ਦੀ ਧੜਕਣ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ਜਦੋਂ ਐਪ ਵਰਤੋਂ ਵਿੱਚ ਹੋਵੇ, ਤਾਂ ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਦਿਲ ਦੀ ਧੜਕਣ, ਤਾਪਮਾਨ, ਖੂਨ ਵਿੱਚ ਮੌਜੂਦ ਆਕਸੀਜਨ ਦੀ ਫ਼ੀਸਦ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ \'ਤੇ ਦਿਲ ਦੀ ਧੜਕਣ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ਜਦੋਂ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੋਵੇ, ਤਾਂ ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਦਿਲ ਦੀ ਧੜਕਣ, ਤਾਪਮਾਨ, ਖੂਨ ਵਿੱਚ ਮੌਜੂਦ ਆਕਸੀਜਨ ਦੀ ਫ਼ੀਸਦ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"ਕੈਲੰਡਰ ਵਰਤਾਰਿਆਂ ਅਤੇ ਵੇਰਵਿਆਂ ਨੂੰ ਪੜ੍ਹੋ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ਇਹ ਐਪ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਸਾਂਝੀ ਕੀਤੀ ਸਟੋਰੇਜ ਤੋਂ ਆਡੀਓ ਫ਼ਾਈਲਾਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"ਸਾਂਝੀ ਕੀਤੀ ਸਟੋਰੇਜ ਤੋਂ ਵੀਡੀਓ ਫ਼ਾਈਲਾਂ ਪੜ੍ਹੋ"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਸਾਂਝੀ ਕੀਤੀ ਸਟੋਰੇਜ ਤੋਂ ਵੀਡੀਓ ਫ਼ਾਈਲਾਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"ਸਾਂਝੀ ਕੀਤੀ ਸਟੋਰੇਜ ਤੋਂ ਚਿੱਤਰ ਫ਼ਾਈਲਾਂ ਪੜ੍ਹੋ"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਸਾਂਝੀ ਕੀਤੀ ਸਟੋਰੇਜ ਤੋਂ ਚਿੱਤਰ ਫ਼ਾਈਲਾਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"ਸਾਂਝੀ ਕੀਤੀ ਸਟੋਰੇਜ ਤੋਂ ਚਿੱਤਰ ਫ਼ਾਈਲਾਂ ਪੜ੍ਹੋ"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਸਾਂਝੀ ਕੀਤੀ ਸਟੋਰੇਜ ਤੋਂ ਚਿੱਤਰ ਫ਼ਾਈਲਾਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"ਸਮੱਗਰੀਆਂ ਦਾ ਸੰਸ਼ੋਧਨ ਕਰੋ ਜਾਂ ਮਿਟਾਓ"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"ਐਪ ਨੂੰ ਸਮੱਗਰੀਆਂ ਲਿਖਣ ਦਿੰਦੀ ਹੈ।"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP ਕਾਲਾਂ ਕਰੋ/ਪ੍ਰਾਪਤ ਕਰੋ"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਮੀਨੂ ਦਬਾਓ ਜਾਂ ਸੰਕਟਕਾਲੀਨ ਕਾਲ ਕਰੋ।"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਮੀਨੂ ਦਬਾਓ।"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਪੈਟਰਨ ਡ੍ਰਾ ਕਰੋ"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"ਸੰਕਟਕਾਲੀਨ ਕਾਲ"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ਸੰਕਟਕਾਲ"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"ਕਾਲ ਤੇ ਵਾਪਸ ਜਾਓ"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"ਸਹੀ!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"ਕਦੇ ਵੀ ਨਹੀਂ"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"ਤੁਹਾਨੂੰ ਇਸ ਸਫ਼ੇ ਨੂੰ ਖੋਲ੍ਹਣ ਦੀ ਅਨੁਮਤੀ ਨਹੀਂ ਹੈ।"</string>
<string name="text_copied" msgid="2531420577879738860">"ਟੈਕਸਟ ਕਲਿਪਬੋਰਡ ਤੇ ਕਾਪੀ ਕੀਤਾ।"</string>
- <string name="copied" msgid="4675902854553014676">"ਕਾਪੀ ਕੀਤੀ ਗਈ"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ਤੋਂ ਕਾਪੀ ਕੀਤੇ ਡਾਟੇ ਨੂੰ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ਵਿੱਚ ਪੇਸਟ ਕੀਤਾ ਗਿਆ"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ਨੇ ਤੁਹਾਡੇ ਕਲਿੱਪਬੋਰਡ ਤੋਂ ਪੇਸਟ ਕੀਤਾ"</string>
<string name="pasted_text" msgid="4298871641549173733">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਕਾਪੀ ਕੀਤੀ ਗਈ ਲਿਖਤ ਨੂੰ <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ਨੇ ਪੇਸਟ ਕੀਤਾ"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ਕਿਸੇ ਐਪ ਨੂੰ ਉਸ ਵਾਸਤੇ ਬੈਟਰੀ ਸੁਯੋਗਤਾਵਾਂ ਨੂੰ ਅਣਡਿੱਠ ਕਰਨ ਲਈ ਇਜਾਜ਼ਤ ਵਾਸਤੇ ਪੁੱਛਣ ਲਈ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"ਸਾਰੇ ਪੈਕੇਜਾਂ ਬਾਰੇ ਪੁੱਛਗਿੱਛ"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਸਥਾਪਤ ਕੀਤੇ ਸਾਰੇ ਪੈਕੇਜ ਦੇਖਣ ਦੀ ਇਜਾਜ਼ਤ ਮਿਲਦੀ ਹੈ।"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis ਤੱਕ ਪਹੁੰਚ"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"ਕਿਸੇ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ SupplementalApis ਤੱਕ ਪਹੁੰਚ ਦੇ ਯੋਗ ਬਣਾਉਂਦਾ ਹੈ।"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API ਤੱਕ ਪਹੁੰਚ ਮਿਲਦੀ ਹੈ"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ AdServices Topics API ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API ਤੱਕ ਪਹੁੰਚ ਮਿਲਦੀ ਹੈ"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ AdServices Attribution API ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API ਤੱਕ ਪਹੁੰਚ ਮਿਲਦੀ ਹੈ"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ AdServices Custom Audiences API ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ਜ਼ੂਮ ਕੰਟਰੋਲ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ਵਿਜੇਟ ਸ਼ਾਮਲ ਨਹੀਂ ਹੋ ਸਕਿਆ।"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ਜਾਓ"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> \'ਤੇ ਸਵਿਚ ਕਰ ਰਿਹਾ ਹੈ…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> ਨੂੰ ਲਾਗ-ਆਉਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ …"</string>
<string name="owner_name" msgid="8713560351570795743">"ਮਾਲਕ"</string>
+ <string name="guest_name" msgid="8502103277839834324">"ਮਹਿਮਾਨ"</string>
<string name="error_message_title" msgid="4082495589294631966">"ਅਸ਼ੁੱਧੀ"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਇਸ ਤਬਦੀਲੀ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
<string name="app_not_found" msgid="3429506115332341800">"ਇਸ ਕਾਰਵਾਈ ਨੂੰ ਸੰਭਾਲਣ ਲਈ ਕੋਈ ਐਪਲੀਕੇਸ਼ਨ ਨਹੀਂ ਮਿਲੀ।"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ਅਣਸਥਾਪਤ ਕਰੋ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ਫਿਰ ਵੀ ਖੋਲ੍ਹੋ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"ਹਾਨੀਕਾਰਕ ਐਪ ਦਾ ਪਤਾ ਲੱਗਿਆ"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"ਸਿਸਟਮ ਲੌਗ ਤੱਕ ਪਹੁੰਚ ਦੀ ਬੇਨਤੀ"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"ਕੀ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ਨੂੰ ਸਾਰੇ ਡੀਵਾਈਸ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"ਸਿਰਫ਼ ਇਸ ਵਾਰ"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"ਆਗਿਆ ਨਾ ਦਿਓ"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"ਕਾਰਜਾਤਮਿਕ ਡੀਬੱਗਿੰਗ ਲਈ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ਸਿਸਟਮ ਲੌਗਾਂ ਦੀ ਬੇਨਤੀ ਕਰਦੀ ਹੈ। ਇਨ੍ਹਾਂ ਲੌਗਾਂ ਵਿੱਚ ਉਹ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ ਜੋ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਨੇ ਲਿਖੀ ਹੈ।"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"ਡੀਵਾਈਸ ਲੌਗਾਂ ਵਿੱਚ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀਆਂ ਕਾਰਵਾਈਆਂ ਰਿਕਾਰਡ ਹੁੰਦੀਆਂ ਹਨ। ਐਪਾਂ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਲੱਭਣ ਅਤੇ ਉਨ੍ਹਾਂ ਦਾ ਹੱਲ ਕਰਨ ਲਈ ਇਨ੍ਹਾਂ ਲੌਗਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੀਆਂ ਹਨ।\n\nਕੁਝ ਲੌਗਾਂ ਵਿੱਚ ਸੰਵੇਦਨਸ਼ੀਲ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ, ਇਸ ਲਈ ਸਿਰਫ਼ ਆਪਣੀਆਂ ਭਰੋਸੇਯੋਗ ਐਪਾਂ ਨੂੰ ਸਾਰੇ ਡੀਵਾਈਸ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ। \n\nਜੇ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਸਾਰੇ ਡੀਵਾਈਸ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਲਈ ਆਗਿਆ ਨਹੀਂ ਦਿੰਦੇ ਹੋ, ਤਾਂ ਇਹ ਹਾਲੇ ਵੀ ਆਪਣੇ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਨਿਰਮਾਤਾ ਹਾਲੇ ਵੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਮੌਜੂਦ ਕੁਝ ਲੌਗਾਂ ਜਾਂ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦਾ ਹੈ। ਹੋਰ ਜਾਣੋ"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ਦੀ <xliff:g id="APP_2">%2$s</xliff:g> ਦੇ ਹਿੱਸੇ ਦਿਖਾਉਣ ਦੀ ਇੱਛਾ ਹੈ"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"ਸੰਪਾਦਨ ਕਰੋ"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ਲੰਮੇ ਸਮੇਂ ਤੋਂ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੈ। ਸਮੀਖਿਆ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ਕਿਰਿਆਸ਼ੀਲ ਐਪਾਂ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"ਇਸ ਡੀਵਾਈਸ ਤੋਂ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 0244fe0..7cf189d 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -87,8 +87,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Tymczasowo wyłączone przez operatora karty SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Brak zasięgu sieci komórkowej"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Spróbuj zmienić preferowaną sieć. Kliknij, by zmienić."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Połączenia alarmowe są niedostępne"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Nie można nawiązywać połączeń alarmowych przez Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Połączenia alarmowe mogą nie być dostępne."</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> nie obsługuje połączeń alarmowych przez Wi-Fi. Kliknij, aby wyświetlić szczegóły."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerty"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Przekierowanie połączeń"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Tryb alarmowego połączenia zwrotnego"</string>
@@ -427,10 +427,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Zezwala aplikacji na modyfikowanie rejestru połączeń tabletu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Pozwala aplikacji modyfikować rejestr połączeń na urządzeniu z Androidem TV, w tym dane o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wykasować lub zmodyfikować rejestr połączeń."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Zezwala aplikacji na modyfikowanie rejestru połączeń telefonu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"dostęp do czujników ciała (np. monitorujących tętno)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Dostęp do danych pochodzących z czujników na ciele, takich jak tętno, temperatura, procent tlenu we krwi itd."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"dostęp do czujników na ciele (np. monitorujących tętno) podczas pracy w tle"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Dostęp do danych pochodzących z czujników na ciele, takich jak tętno, temperatura, procent tlenu we krwi itd., gdy aplikacja pracuje w tle."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Zezwól na dostęp do danych z czujników na ciele, np. tętna, podczas używania aplikacji"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Zezwala aplikacji na dostęp do danych z czujników na ciele, takich jak tętno, temperatura i poziom saturacji, gdy aplikacja ta jest używana."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Zezwól na dostęp do danych z czujników na ciele, np. tętna, podczas używania aplikacji w tle"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Zezwala aplikacji na dostęp do danych z czujników na ciele, takich jak tętno, temperatura i poziom saturacji, gdy aplikacja ta jest używana w tle."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Odczytywanie wydarzeń i informacji z kalendarza"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ta aplikacja może odczytywać wszystkie zapisane na tablecie wydarzenia z kalendarza i udostępniać oraz zapisywać dane kalendarza."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ta aplikacja może odczytywać wszystkie wydarzenia z kalendarza zapisane na urządzeniu z Androidem TV oraz udostępniać i zapisywać dane z kalendarza."</string>
@@ -691,8 +691,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Zezwala na odczyt przez aplikację plików audio w pamięci współdzielonej."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"odczyt plików wideo z pamięci współdzielonej"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Zezwala na odczyt przez aplikację plików wideo w pamięci współdzielonej."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"odczyt plików graficznych z pamięci współdzielonej"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Zezwala na odczyt przez aplikację plików graficznych w pamięci współdzielonej."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"odczyt plików graficznych z pamięci współdzielonej"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Zezwala na odczyt przez aplikację plików graficznych w pamięci współdzielonej."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modyfikowanie i usuwanie zawartości pamięci współdzielonej"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Zezwala aplikacji na zapis zawartości pamięci współdzielonej."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"wykonywanie/odbieranie połączeń SIP"</string>
@@ -914,7 +914,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Naciśnij Menu, aby odblokować lub wykonać połączenie alarmowe."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Naciśnij Menu, aby odblokować."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Narysuj wzór, aby odblokować"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Połączenie alarmowe"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Alarmowe"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Powrót do połączenia"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Poprawnie!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Spróbuj ponownie."</string>
@@ -1053,7 +1053,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nigdy"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nie masz pozwolenia na otwarcie tej strony."</string>
<string name="text_copied" msgid="2531420577879738860">"Tekst został skopiowany do schowka."</string>
- <string name="copied" msgid="4675902854553014676">"Skopiowano"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła dane z aplikacji <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła dane ze schowka"</string>
<string name="pasted_text" msgid="4298871641549173733">"Aplikacja <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> wkleiła skopiowany tekst"</string>
@@ -1454,8 +1453,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Zezwala aplikacji na proszenie o uprawnienia do ignorowania optymalizacji wykorzystania baterii w przypadku danej aplikacji."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"zapytanie o wszystkie pakiety"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Pozwala aplikacji wyświetlać wszystkie zainstalowane pakiety."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"dostęp do SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Zezwala na dostęp aplikacji do SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"Dostęp do AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Zezwala na dostęp aplikacji do AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"Dostęp do interfejsów AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Zezwala na dostęp aplikacji do interfejsów AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"Dostęp do AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Zezwala na dostęp aplikacji do AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dotknij dwukrotnie, aby sterować powiększeniem"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nie można dodać widżetu."</string>
<string name="ime_action_go" msgid="5536744546326495436">"OK"</string>
@@ -1718,6 +1721,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Przełączam na użytkownika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Wylogowuję użytkownika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Właściciel"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gość"</string>
<string name="error_message_title" msgid="4082495589294631966">"Błąd"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Ta zmiana nie jest dozwolona przez administratora"</string>
<string name="app_not_found" msgid="3429506115332341800">"Nie znaleziono aplikacji do obsługi tej akcji"</string>
@@ -2029,10 +2033,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ODINSTALUJ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OTWÓRZ MIMO TO"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Wykryto szkodliwą aplikację"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Prośba o dostęp do dziennika systemowego"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Zezwolić aplikacji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> na dostęp do wszystkich dzienników urządzenia?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Tylko tym razem"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nie zezwalaj"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"Aplikacja <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> prosi o dzienniki systemowe do funkcjonalnego debugowania. Te dzienniki mogą zawierać informacje zapisane Twoim urządzeniu przez aplikacje i usługi."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Dzienniki urządzenia zapisują, co dzieje się na urządzeniu. Aplikacje mogą ich używać do wykrywania i rozwiązywania problemów.\n\nNiektóre dzienniki mogą zawierać poufne dane, dlatego na dostęp do wszystkich dzienników zezwalaj tylko aplikacjom, którym ufasz. \n\nNawet jeśli nie zezwolisz tej aplikacji na dostęp do wszystkich dzienników na urządzeniu, będzie miała dostęp do własnych, a producent urządzenia będzie mógł korzystać z niektórych dzienników na urządzeniu. Więcej informacji"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Nie pokazuj ponownie"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Aplikacja <xliff:g id="APP_0">%1$s</xliff:g> chce pokazywać wycinki z aplikacji <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Edytuj"</string>
@@ -2267,4 +2271,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> długo działa w tle. Kliknij, aby sprawdzić."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Sprawdź aktywne aplikacje"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nie można uzyskać dostępu do aparatu z tego urządzenia"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 3bd78d0..75b46e5 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Temporariamente desativado pela sua operadora para o chip <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Não foi possível acessar a rede móvel"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tente alterar a rede preferencial. Toque para alterar."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Chamadas de emergência indisponíveis"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Não é possível fazer chamadas de emergência por Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"As chamadas de emergência podem estar indisponíveis"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> não tem suporte a chamadas de emergência por Wi-Fi. Toque para ver detalhes."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Encaminhamento de chamada"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modo de retorno de chamada de emergência"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permite que o app modifique o registro de chamadas de seu tablet, incluindo dados sobre chamadas recebidas e efetuadas. Apps maliciosos podem usar esta permissão para apagar ou modificar seu registro de chamadas."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permite que o app modifique o registro de chamadas do seu dispositivo Android TV, incluindo dados sobre chamadas recebidas e realizadas. Apps maliciosos podem usar essa permissão para apagar ou modificar seu registro de chamadas."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permite que o app modifique o registro de chamadas de seu telefone, incluindo dados sobre chamadas recebidas e efetuadas. Apps maliciosos podem usar esta permissão para apagar ou modificar seu registro de chamadas."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"acessar sensores corporais (como monitores de frequência cardíaca)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Acesso a dados dos sensores corporais, como frequência cardíaca, temperatura, porcentagem de oxigênio no sangue etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"acessar sensores corporais (como monitores de frequência cardíaca) em segundo plano"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Acesso a dados dos sensores corporais, como frequência cardíaca, temperatura, porcentagem de oxigênio no sangue etc. em segundo plano."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Acessar dados do sensor corporal, como a frequência cardíaca, quando está em uso"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em uso."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acessar dados do sensor corporal, como a frequência cardíaca, segundo plano"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em segundo plano."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Ler detalhes e eventos da agenda"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Este app pode ler todos os eventos da agenda armazenados no seu tablet e compartilhar ou salvar os dados da sua agenda."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Este app pode ler todos os eventos da agenda armazenados no seu dispositivo Android TV e compartilhar ou salvar os dados da sua agenda."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permite que o app leia arquivos de áudio do armazenamento compartilhado."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"ler arquivos de vídeo do armazenamento compartilhado"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permite que o app leia arquivos de vídeo do armazenamento compartilhado."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"ler arquivos de imagem do armazenamento compartilhado"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Permite que o app leia arquivos de imagem do armazenamento compartilhado."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"ler arquivos de imagem do armazenamento compartilhado"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permite que o app leia arquivos de imagem do armazenamento compartilhado."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"alterar ou excluir conteúdo do armaz. compartilhado"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Permite que o app grave o conteúdo do armaz. compartilhado."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"fazer/receber chamadas SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Pressione Menu para desbloquear ou fazer uma chamada de emergência."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Pressione Menu para desbloquear."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Desenhe o padrão para desbloquear"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Chamada de emergência"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergência"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Retornar à chamada"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correto!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Tente novamente"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nunca"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Você não tem permissão para abrir esta página."</string>
<string name="text_copied" msgid="2531420577879738860">"Texto copiado para a área de transferência."</string>
- <string name="copied" msgid="4675902854553014676">"Copiado"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Dados do app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> colados no app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou conteúdo da sua área de transferência"</string>
<string name="pasted_text" msgid="4298871641549173733">"O app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou o texto copiado"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite que um app peça permissão para ignorar as otimizações de bateria para esse app."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"consultar todos os pacotes"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permite que um app veja todos os pacotes instalados."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"acessar SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Permite que um aplicativo tenha acesso a SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"acessar a API AdServices Topics"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Permite que um aplicativo tenha acesso à API AdServices Topics."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"acessar APIs AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Permite que um aplicativo tenha acesso a APIs AdServices Attribution."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"acessar a API AdServices Custom Audiences"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Permite que um aplicativo tenha acesso à API AdServices Custom Audiences."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Toque duas vezes para ter controle do zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Não foi possível adicionar widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Alternando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Desconectando <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Proprietário"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Convidado"</string>
<string name="error_message_title" msgid="4082495589294631966">"Erro"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Esta alteração não é permitida pelo administrador"</string>
<string name="app_not_found" msgid="3429506115332341800">"Nenhum app encontrado para executar a ação"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DESINSTALAR"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR MESMO ASSIM"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"App nocivo detectado"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Solicitação de acesso ao registro do sistema"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Apenas esta vez"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Não permitir"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"O app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> solicita registros do sistema para fazer uma depuração funcional. Esses registros podem conter informações que apps e serviços do dispositivo escreveram."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então permita que apenas os apps em que você confia acessem os registros. \n\nSe você não permitir que este app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios registros. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações. Saiba mais"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Não mostrar novamente"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quer mostrar partes do app <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano faz muito tempo. Toque para revisar."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativos"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Não é possível acessar a câmera neste dispositivo"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 27bdde7..5268065 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -51,8 +51,8 @@
<string name="needPuk2" msgid="7032612093451537186">"Introduza o PUK2 para desbloquear o cartão SIM."</string>
<string name="enablePin" msgid="2543771964137091212">"Ação sem êxito. Ative o bloqueio do SIM/RUIM."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
- <item quantity="one">Tem mais <xliff:g id="NUMBER_0">%d</xliff:g> tentativa antes de o cartão SIM ficar bloqueado.</item>
<item quantity="other">Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas antes de o cartão SIM ficar bloqueado.</item>
+ <item quantity="one">Tem mais <xliff:g id="NUMBER_0">%d</xliff:g> tentativa antes de o cartão SIM ficar bloqueado.</item>
</plurals>
<string name="imei" msgid="2157082351232630390">"IMEI"</string>
<string name="meid" msgid="3291227361605924674">"MEID"</string>
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Serviço temporariamente desativado pelo operador no SIM <xliff:g id="SIMNUMBER">%d</xliff:g>."</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Não é possível estabelecer ligação à rede móvel."</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Experimente alterar a rede preferida. Toque para alterar."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Chamadas de emergência indisponíveis"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Não é possível efetuar chamadas de emergência através de Wi‑Fi."</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"As chamadas de emergência podem estar indisponíveis"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> não suporta chamadas de emergência através de Wi-Fi. Toque para obter detalhes."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Reencaminhamento de chamadas"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modo de chamada de retorno de emergência"</string>
@@ -180,7 +180,7 @@
<string name="low_memory" product="watch" msgid="3479447988234030194">"O armazenamento de visualizações está cheio. Elimine alguns ficheiros para libertar espaço."</string>
<string name="low_memory" product="tv" msgid="6663680413790323318">"O armazenamento do dispositivo Android TV está cheio. Elimine alguns ficheiros para libertar espaço."</string>
<string name="low_memory" product="default" msgid="2539532364144025569">"O armazenamento do telemóvel está cheio. Elimine alguns ficheiros para libertar espaço."</string>
- <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{Autoridade de certificação instalada}one{Autoridade(s) de certificação instalada(s)}other{Autoridades de certificação instaladas}}"</string>
+ <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{Autoridade de certificação instalada}other{Autoridades de certificação instaladas}}"</string>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Por um terceiro desconhecido"</string>
<string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Pelo gestor do seu perfil de trabalho"</string>
<string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Por <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
@@ -254,7 +254,7 @@
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Utilize esta opção na maioria das circunstâncias. Permite monitorizar o progresso do relatório, introduzir mais detalhes acerca do problema e tirar capturas de ecrã. Pode omitir algumas secções menos utilizadas que demoram muito tempo a comunicar."</string>
<string name="bugreport_option_full_title" msgid="7681035745950045690">"Relatório completo"</string>
<string name="bugreport_option_full_summary" msgid="1975130009258435885">"Utilize esta opção para uma interferência mínima do sistema quando o dispositivo não responder ou estiver demasiado lento, ou quando precisar de todas as secções de relatório. Não permite introduzir mais detalhes ou tirar capturas de ecrã adicionais."</string>
- <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{A fazer uma captura de ecrã do relatório de erro dentro de # segundo.}one{A fazer uma captura de ecrã do relatório de erro dentro de # segundo(s).}other{A fazer uma captura de ecrã do relatório de erro dentro de # segundos.}}"</string>
+ <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{A fazer uma captura de ecrã do relatório de erro dentro de # segundo.}other{A fazer uma captura de ecrã do relatório de erro dentro de # segundos.}}"</string>
<string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Captura de ecrã tirada com o relatório de erro."</string>
<string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Falha ao fazer captura de ecrã com o relatório de erro."</string>
<string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"Modo silencioso"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permite à app modificar o registo de chamadas do tablet, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para apagar ou modificar o registo de chamadas."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permite à app modificar o registo de chamadas do seu dispositivo Android TV, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para apagar ou modificar o seu registo de chamadas."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permite à app modificar o registo de chamadas do telemóvel, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para apagar ou modificar o seu registo de chamadas."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"aceder a sensores corporais (como monitores do ritmo cardíaco)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Acesso a dados dos sensores de corpo, como o ritmo cardíaco, a temperatura, a percentagem de oxigénio no sangue, etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"aceder a sensores de corpo (como monitores do ritmo cardíaco) em segundo plano"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Acesso a dados dos sensores de corpo, como o ritmo cardíaco, a temperatura, a percentagem de oxigénio no sangue, etc., em segundo plano."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Aceder a dados de sensores de corpo, como ritmo cardíaco, durante a utilização"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite à app aceder a dados de sensores de corpo, como ritmo cardíaco, temperatura e percentagem de oxigénio no sangue, enquanto está a ser usada."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Aceder a dados de sensores de corpo, como ritmo cardíaco, quando em seg. plano"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite à app aceder a dados de sensores de corpo, como ritmo cardíaco, temperatura e percentagem de oxigénio no sangue, enquanto está em segundo plano."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Ler detalhes e eventos do calendário"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta app pode ler todos os eventos do calendário armazenados no seu tablet e partilhar ou guardar os dados do calendário."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta app pode ler todos os eventos do calendário armazenados no seu dispositivo Android TV e partilhar ou guardar os dados do calendário."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permite que a app leia ficheiros de áudio do armazenamento partilhado."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"ler ficheiros de vídeo do armazenamento partilhado"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permite que a app leia ficheiros de vídeo do armazenamento partilhado."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"ler ficheiros de imagem do armazenamento partilhado"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Permite que a app leia ficheiros de imagem do armazenamento partilhado."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"ler ficheiros de imagem do armazenamento partilhado"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permite que a app leia ficheiros de imagem do armazenamento partilhado."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modif./elim. os conteúdos do armazenam. partilhado"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Permite que a apl. escreva conteúd. do armazen. partilhado."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"efetuar/receber chamadas SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Prima Menu para desbloquear ou efectuar uma chamada de emergência."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Prima Menu para desbloquear."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Desenhar padrão para desbloquear"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Chamada de emergência"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergência"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Regressar à chamada"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correcto!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Tentar novamente"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nunca"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Não tem autorização para abrir esta página."</string>
<string name="text_copied" msgid="2531420577879738860">"Texto copiado para a área de transferência."</string>
- <string name="copied" msgid="4675902854553014676">"Copiado"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"A app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou da app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"A app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou a partir da área de transferência"</string>
<string name="pasted_text" msgid="4298871641549173733">"A app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou o texto que copiou"</string>
@@ -1080,7 +1079,7 @@
<string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> pretende ativar a funcionalidade Explorar Através do Toque. Quando a funcionalidade Explorar Através do Toque estiver ativada, pode ouvir ou visualizar descrições sobre o que está por baixo do seu dedo ou executar gestos para interagir com o telemóvel."</string>
<string name="oneMonthDurationPast" msgid="4538030857114635777">"Há 1 mês"</string>
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Há mais de 1 mês"</string>
- <string name="last_num_days" msgid="2393660431490280537">"{count,plural, =1{# dia anterior}one{# dia(s) anterior(es)}other{# dias anteriores}}"</string>
+ <string name="last_num_days" msgid="2393660431490280537">"{count,plural, =1{# dia anterior}other{# dias anteriores}}"</string>
<string name="last_month" msgid="1528906781083518683">"Último mês"</string>
<string name="older" msgid="1645159827884647400">"Mais antiga"</string>
<string name="preposition_for_date" msgid="2780767868832729599">"a <xliff:g id="DATE">%s</xliff:g>"</string>
@@ -1107,14 +1106,14 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"em <xliff:g id="COUNT">%d</xliff:g> h"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"em <xliff:g id="COUNT">%d</xliff:g> d"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"em <xliff:g id="COUNT">%d</xliff:g> a"</string>
- <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Há # minuto}one{Há # minutos(s)}other{Há # minutos}}"</string>
- <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Há # hora}one{Há # hora(s)}other{Há # horas}}"</string>
- <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Há # dia}one{Há # dia(s)}other{Há # dias}}"</string>
- <string name="duration_years_relative" msgid="8731202348869424370">"{count,plural, =1{Há # ano}one{Há # ano(s)}other{Há # anos}}"</string>
- <string name="duration_minutes_relative_future" msgid="5259574171747708115">"{count,plural, =1{# minuto}one{# minuto(s)}other{# minutos}}"</string>
- <string name="duration_hours_relative_future" msgid="6670440478481140565">"{count,plural, =1{# hora}one{# hora(s)}other{# horas}}"</string>
- <string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# dia}one{# dia(s)}other{# dias}}"</string>
- <string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# ano}one{# ano(s)}other{# anos}}"</string>
+ <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Há # minuto}other{Há # minutos}}"</string>
+ <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Há # hora}other{Há # horas}}"</string>
+ <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Há # dia}other{Há # dias}}"</string>
+ <string name="duration_years_relative" msgid="8731202348869424370">"{count,plural, =1{Há # ano}other{Há # anos}}"</string>
+ <string name="duration_minutes_relative_future" msgid="5259574171747708115">"{count,plural, =1{# minuto}other{# minutos}}"</string>
+ <string name="duration_hours_relative_future" msgid="6670440478481140565">"{count,plural, =1{# hora}other{# horas}}"</string>
+ <string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# dia}other{# dias}}"</string>
+ <string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# ano}other{# anos}}"</string>
<string name="VideoView_error_title" msgid="5750686717225068016">"Problema com o vídeo"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"Este vídeo não é válido para transmissão neste aparelho."</string>
<string name="VideoView_error_text_unknown" msgid="7658683339707607138">"Não é possível reproduzir este vídeo."</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite que uma app solicite autorização para ignorar as otimizações da bateria para a mesma."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"consultar todos os pacotes"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permite a uma app ver todos os pacotes instalados."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"aceder a SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Permite a uma aplicação aceder a SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"aceder à API AdServices Topics"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Permite a uma aplicação aceder à API AdServices Topics."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"aceder às APIs AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Permite a uma aplicação aceder às APIs AdServices Attribution."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"aceder à API AdServices Custom Audiences"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Permite a uma aplicação aceder à API AdServices Custom Audiences."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tocar duas vezes para controlar o zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Não foi possível adicionar widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
@@ -1504,7 +1507,7 @@
<string name="skip_button_label" msgid="3566599811326688389">"Ignorar"</string>
<string name="no_matches" msgid="6472699895759164599">"Sem correspondências"</string>
<string name="find_on_page" msgid="5400537367077438198">"Localizar na página"</string>
- <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# correspondência}one{# de {total}}other{# de {total}}}"</string>
+ <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# correspondência}other{# de {total}}}"</string>
<string name="action_mode_done" msgid="2536182504764803222">"Concluído"</string>
<string name="progress_erasing" msgid="6891435992721028004">"A apagar o armazenamento partilhado…"</string>
<string name="share" msgid="4157615043345227321">"Partilhar"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"A mudar para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"A terminar a sessão de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Proprietário"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Convidado"</string>
<string name="error_message_title" msgid="4082495589294631966">"Erro"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"O gestor não permite esta alteração"</string>
<string name="app_not_found" msgid="3429506115332341800">"Não foram encontradas aplicações para executar esta ação"</string>
@@ -1857,14 +1861,14 @@
<string name="data_saver_description" msgid="4995164271550590517">"Para ajudar a reduzir a utilização de dados, a Poupança de dados impede que algumas apps enviem ou recebam dados em segundo plano. Uma determinada app que esteja a utilizar atualmente pode aceder aos dados, mas é possível que o faça com menos frequência. Isto pode significar, por exemplo, que as imagens não são apresentadas até que toque nas mesmas."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Pretende ativar a Poupança de dados?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string>
- <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Durante um minuto (até à[s] {formattedTime})}one{Durante # minuto(s) (até à[s] {formattedTime})}other{Durante # minutos (até à[s] {formattedTime})}}"</string>
- <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{Durante 1 min (até à[s] {formattedTime})}one{Durante # min (até à[s] {formattedTime})}other{Durante # min (até à[s] {formattedTime})}}"</string>
- <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{Durante 1 hora (até à[s] {formattedTime})}one{Durante # hora(s) (até à[s] {formattedTime})}other{Durante # horas (até à[s] {formattedTime})}}"</string>
- <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{Durante 1 h (até à[s] {formattedTime})}one{Durante # h (até à[s] {formattedTime})}other{Durante # h (até à[s] {formattedTime})}}"</string>
- <string name="zen_mode_duration_minutes" msgid="2340007982276569054">"{count,plural, =1{Durante um minuto}one{Durante # minuto(s)}other{Durante # minutos}}"</string>
- <string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{Durante 1 min}one{Durante # min}other{Durante # min}}"</string>
- <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{Durante 1 hora}one{Durante # hora(s)}other{Durante # horas}}"</string>
- <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{Durante 1 h}one{Durante # h}other{Durante # h}}"</string>
+ <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Durante um minuto (até à[s] {formattedTime})}other{Durante # minutos (até à[s] {formattedTime})}}"</string>
+ <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{Durante 1 min (até à[s] {formattedTime})}other{Durante # min (até à[s] {formattedTime})}}"</string>
+ <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{Durante 1 hora (até à[s] {formattedTime})}other{Durante # horas (até à[s] {formattedTime})}}"</string>
+ <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{Durante 1 h (até à[s] {formattedTime})}other{Durante # h (até à[s] {formattedTime})}}"</string>
+ <string name="zen_mode_duration_minutes" msgid="2340007982276569054">"{count,plural, =1{Durante um minuto}other{Durante # minutos}}"</string>
+ <string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{Durante 1 min}other{Durante # min}}"</string>
+ <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{Durante 1 hora}other{Durante # horas}}"</string>
+ <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{Durante 1 h}other{Durante # h}}"</string>
<string name="zen_mode_until_next_day" msgid="1403042784161725038">"Até <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_until" msgid="2250286190237669079">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_alarm" msgid="7046911727540499275">"Até <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próximo alarme)"</string>
@@ -1980,7 +1984,7 @@
<string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Guardar para o Preenchimento automático"</string>
<string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Não é possível preencher automaticamente o conteúdo"</string>
<string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Sem sugestões do preenchimento automático"</string>
- <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{Uma sugestão do preenchimento automático}one{# sugestão(ões) de preenchimento automático}other{# sugestões de preenchimento automático}}"</string>
+ <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{Uma sugestão do preenchimento automático}other{# sugestões de preenchimento automático}}"</string>
<string name="autofill_save_title" msgid="7719802414283739775">"Pretende guardar em "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_type" msgid="3002460014579799605">"Pretende guardar <xliff:g id="TYPE">%1$s</xliff:g> em "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Pretende guardar <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> em "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DESINSTALAR"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR MESMO ASSIM"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Aplicação prejudicial detetada"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Pedido de acesso ao registo do sistema"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Permitir que a app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aceda a todos os registos do dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Apenas desta vez"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Não permitir"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"A app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> solicita registos do sistema para depuração funcional. Estes registos podem conter informações escritas por apps e serviços no seu dispositivo."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Os registos do dispositivo documentam o que ocorre no seu dispositivo. As apps podem usar esses registos para detetar e corrigir problemas.\n\nAlguns registos podem conter informações confidenciais, pelo que o acesso a todos os registos do dispositivo deve apenas ser permitido às apps nas quais confia. \n\nSe não permitir o acesso desta app a todos os registos do dispositivo, a mesma pode ainda assim aceder aos seus próprios registos e o fabricante do dispositivo pode continuar a aceder a alguns registos ou informações no seu dispositivo. Saiba mais"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Não mostrar de novo"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"A app <xliff:g id="APP_0">%1$s</xliff:g> pretende mostrar partes da app <xliff:g id="APP_2">%2$s</xliff:g>."</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string>
@@ -2086,7 +2090,7 @@
<string name="mime_type_presentation_ext" msgid="8761049335564371468">"Apresentação <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"O Bluetooth continuará ativado durante o modo de avião."</string>
<string name="car_loading_profile" msgid="8219978381196748070">"A carregar…"</string>
- <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # ficheiro}one{{file_name} + # ficheiro(s)}other{{file_name} + # ficheiros}}"</string>
+ <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # ficheiro}other{{file_name} + # ficheiros}}"</string>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Não existem pessoas recomendadas com quem partilhar"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista de aplicações"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Esta app não recebeu autorização de gravação, mas pode capturar áudio através deste dispositivo USB."</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"A app <xliff:g id="APP">%1$s</xliff:g> está a ser executada em segundo plano há muito tempo. Toque para analisar."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativas"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Não é possível aceder à câmara a partir deste dispositivo"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 3bd78d0..75b46e5 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Temporariamente desativado pela sua operadora para o chip <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Não foi possível acessar a rede móvel"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tente alterar a rede preferencial. Toque para alterar."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Chamadas de emergência indisponíveis"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Não é possível fazer chamadas de emergência por Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"As chamadas de emergência podem estar indisponíveis"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> não tem suporte a chamadas de emergência por Wi-Fi. Toque para ver detalhes."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Encaminhamento de chamada"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modo de retorno de chamada de emergência"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permite que o app modifique o registro de chamadas de seu tablet, incluindo dados sobre chamadas recebidas e efetuadas. Apps maliciosos podem usar esta permissão para apagar ou modificar seu registro de chamadas."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permite que o app modifique o registro de chamadas do seu dispositivo Android TV, incluindo dados sobre chamadas recebidas e realizadas. Apps maliciosos podem usar essa permissão para apagar ou modificar seu registro de chamadas."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permite que o app modifique o registro de chamadas de seu telefone, incluindo dados sobre chamadas recebidas e efetuadas. Apps maliciosos podem usar esta permissão para apagar ou modificar seu registro de chamadas."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"acessar sensores corporais (como monitores de frequência cardíaca)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Acesso a dados dos sensores corporais, como frequência cardíaca, temperatura, porcentagem de oxigênio no sangue etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"acessar sensores corporais (como monitores de frequência cardíaca) em segundo plano"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Acesso a dados dos sensores corporais, como frequência cardíaca, temperatura, porcentagem de oxigênio no sangue etc. em segundo plano."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Acessar dados do sensor corporal, como a frequência cardíaca, quando está em uso"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em uso."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acessar dados do sensor corporal, como a frequência cardíaca, segundo plano"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em segundo plano."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Ler detalhes e eventos da agenda"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Este app pode ler todos os eventos da agenda armazenados no seu tablet e compartilhar ou salvar os dados da sua agenda."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Este app pode ler todos os eventos da agenda armazenados no seu dispositivo Android TV e compartilhar ou salvar os dados da sua agenda."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permite que o app leia arquivos de áudio do armazenamento compartilhado."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"ler arquivos de vídeo do armazenamento compartilhado"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permite que o app leia arquivos de vídeo do armazenamento compartilhado."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"ler arquivos de imagem do armazenamento compartilhado"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Permite que o app leia arquivos de imagem do armazenamento compartilhado."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"ler arquivos de imagem do armazenamento compartilhado"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permite que o app leia arquivos de imagem do armazenamento compartilhado."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"alterar ou excluir conteúdo do armaz. compartilhado"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Permite que o app grave o conteúdo do armaz. compartilhado."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"fazer/receber chamadas SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Pressione Menu para desbloquear ou fazer uma chamada de emergência."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Pressione Menu para desbloquear."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Desenhe o padrão para desbloquear"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Chamada de emergência"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergência"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Retornar à chamada"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Correto!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Tente novamente"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nunca"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Você não tem permissão para abrir esta página."</string>
<string name="text_copied" msgid="2531420577879738860">"Texto copiado para a área de transferência."</string>
- <string name="copied" msgid="4675902854553014676">"Copiado"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Dados do app <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> colados no app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou conteúdo da sua área de transferência"</string>
<string name="pasted_text" msgid="4298871641549173733">"O app <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> colou o texto copiado"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite que um app peça permissão para ignorar as otimizações de bateria para esse app."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"consultar todos os pacotes"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permite que um app veja todos os pacotes instalados."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"acessar SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Permite que um aplicativo tenha acesso a SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"acessar a API AdServices Topics"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Permite que um aplicativo tenha acesso à API AdServices Topics."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"acessar APIs AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Permite que um aplicativo tenha acesso a APIs AdServices Attribution."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"acessar a API AdServices Custom Audiences"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Permite que um aplicativo tenha acesso à API AdServices Custom Audiences."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Toque duas vezes para ter controle do zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Não foi possível adicionar widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Ir"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Alternando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Desconectando <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Proprietário"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Convidado"</string>
<string name="error_message_title" msgid="4082495589294631966">"Erro"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Esta alteração não é permitida pelo administrador"</string>
<string name="app_not_found" msgid="3429506115332341800">"Nenhum app encontrado para executar a ação"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DESINSTALAR"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR MESMO ASSIM"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"App nocivo detectado"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Solicitação de acesso ao registro do sistema"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Apenas esta vez"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Não permitir"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"O app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> solicita registros do sistema para fazer uma depuração funcional. Esses registros podem conter informações que apps e serviços do dispositivo escreveram."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então permita que apenas os apps em que você confia acessem os registros. \n\nSe você não permitir que este app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios registros. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações. Saiba mais"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Não mostrar novamente"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quer mostrar partes do app <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano faz muito tempo. Toque para revisar."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativos"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Não é possível acessar a câmera neste dispositivo"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 15a368b..0c9e87a 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -86,8 +86,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Dezactivat temporar de operator pentru numărul de card SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nu se poate stabili conexiunea la rețeaua mobilă"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Încercați să schimbați rețeaua preferată. Atingeți pentru a schimba."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Apelurile de urgență nu sunt disponibile"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Nu puteți efectua apeluri de urgență prin Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Este posibil ca apelurile de urgență să nu fie disponibile"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> nu acceptă apelurile de urgență prin Wi-Fi. Atingeți pentru detalii."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerte"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Redirecționarea apelurilor"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mod de apelare inversă de urgență"</string>
@@ -426,10 +426,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permite aplicației să modifice jurnalul de apeluri al tabletei dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicațiile rău intenționate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permite aplicației să modifice jurnalul de apeluri al dispozitivului Android TV, inclusiv datele despre apelurile primite sau efectuate. Aplicațiile rău intenționate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul de apeluri."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permite aplicației să modifice jurnalul de apeluri al telefonului dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicațiile rău intenționate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"să acceseze senzorii corporali (cum ar fi monitoarele cardiace)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Acces la date de la senzori corporali, cum ar fi senzorii pentru puls, temperatură, procentul de oxigen din sânge etc."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"Acces la senzorii corporali (cum ar fi monitoarele cardiace) din fundal"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Acces din fundal la date de la senzori corporali, cum ar fi senzorii pentru puls, temperatură, procentul de oxigen din sânge etc."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Să acceseze date de la senzorii corporali, cum ar fi pulsul, în timpul folosirii"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite aplicației să acceseze date de la senzorii corporali, cum ar fi pulsul, temperatura și procentul de oxigen din sânge, în timpul folosirii aplicației."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Să acceseze date de la senzorii corporali, precum pulsul, când rulează în fundal"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite aplicației să acceseze date de la senzorii corporali, cum ar fi pulsul, temperatura și procentul de oxigen din sânge, în timp ce aplicația rulează în fundal."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"să citească evenimentele din calendar și detaliile"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Această aplicație poate să citească toate evenimentele din calendar stocate pe tabletă și să trimită sau să salveze datele din calendar."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Această aplicație poate să citească toate evenimentele din calendar stocate pe dispozitivul Android TV și să trimită sau să salveze datele din calendar."</string>
@@ -690,8 +690,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permite aplicației să citească fișiere audio din spațiul de stocare comun."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"să citească fișiere video din spațiul de stocare comun"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permite aplicației să citească fișiere video din spațiul de stocare comun."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"să citească fișiere imagine din spațiul de stocare comun"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Permite aplicației să citească fișiere imagine din spațiul de stocare comun."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"să citească fișiere imagine din spațiul de stocare comun"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permite aplicației să citească fișiere imagine din spațiul de stocare comun."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"să modifice sau să șteargă conținutul spațiului de stocare comun"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Permite aplicației scrierea conținutul spațiului de stocare comun."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"efectuarea/primirea apelurilor SIP"</string>
@@ -913,7 +913,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Apăsați Meniu pentru a debloca sau pentru a efectua apeluri de urgență."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Apăsați Meniu pentru deblocare."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Desenați modelul pentru a debloca"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Apel de urgență"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Urgență"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Reveniți la apel"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Corect!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Încercați din nou"</string>
@@ -1052,7 +1052,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Niciodată"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nu aveți permisiunea de a deschide această pagină."</string>
<string name="text_copied" msgid="2531420577879738860">"Text copiat în clipboard."</string>
- <string name="copied" msgid="4675902854553014676">"Copiat"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a inserat date din <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a inserat din clipboard"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a inserat textul copiat"</string>
@@ -1453,8 +1452,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permite unei aplicații să solicite permisiunea de a ignora optimizările bateriei pentru aplicația respectivă."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"să interogheze toate pachetele"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permite unei aplicații să vadă toate pachetele instalate."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"să acceseze SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Permite unei aplicații să acceseze SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"să acceseze API-ul AdServices Topics"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Permite unei aplicații să acceseze API-ul AdServices Topics."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"să acceseze API-urile AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Permite unei aplicații să acceseze API-urile AdServices Attribution."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"să acceseze API-ul AdServices Custom Audiences"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Permite unei aplicații să acceseze API-ul AdServices Custom Audiences."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Apăsați de două ori pentru a controla mărirea/micșorarea"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nu s-a putut adăuga widgetul."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Accesați"</string>
@@ -1717,6 +1720,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Se comută la <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Se deconectează utilizatorul <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Proprietar"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Invitat"</string>
<string name="error_message_title" msgid="4082495589294631966">"Eroare"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Această modificare nu este permisă de administratorul dvs."</string>
<string name="app_not_found" msgid="3429506115332341800">"Nicio aplicație pentru gestionarea acestei acțiuni"</string>
@@ -2028,10 +2032,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DEZINSTALAȚI"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"Deschideți oricum"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Aplicație dăunătoare detectată"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Solicitare de acces la jurnale de sistem"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Permiteți ca <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> să acceseze toate jurnalele dispozitivului?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Doar de data aceasta"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nu permiteți"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> solicită jurnale de sistem pentru remedierea erorilor de funcționare. Aceste jurnale pot conține informații scrise de aplicațiile și serviciile de pe dispozitiv."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Jurnalele dispozitivului înregistrează activitatea de pe dispozitivul dvs. Aplicațiile pot folosi aceste jurnale pentru a identifica și a remedia probleme.\n\nUnele jurnale pot să conțină informații sensibile, prin urmare permiteți accesul la toate jurnalele dispozitivului doar aplicațiilor în care aveți încredere. \n\nDacă nu permiteți accesul aplicației la toate jurnalele dispozitivului, aceasta poate în continuare să acceseze propriile jurnale și este posibil ca producătorul dispozitivului să acceseze în continuare unele jurnale sau informații de pe dispozitiv. Aflați mai multe"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Nu mai afișa"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> vrea să afișeze porțiuni din <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Editați"</string>
@@ -2266,4 +2270,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> rulează în fundal mult timp. Atingeți pentru a examina."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificați aplicațiile active"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nu se poate accesa camera foto de pe acest dispozitiv"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index bf8e83d..04ffd3b 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -87,8 +87,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Временно отключено оператором связи для SIM-карты <xliff:g id="SIMNUMBER">%d</xliff:g>."</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобильная сеть недоступна"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Нажмите, чтобы выбрать другую сеть."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Экстренные вызовы недоступны"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Экстренные вызовы по Wi‑Fi недоступны."</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Экстренные вызовы могут быть недоступны"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> не поддерживает экстренные вызовы по Wi-Fi. Нажмите, чтобы узнать больше."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Оповещения"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Переадресация вызовов"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим экстренных обратных вызовов"</string>
@@ -427,10 +427,14 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Приложение сможет вносить изменения в список вызовов планшетного ПК и данные о входящих и исходящих звонках. Вредоносные приложения смогут воспользоваться этим для удаления или изменения информации о звонках."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Приложение сможет изменять список вызовов и данные о входящих и исходящих звонках на устройстве Android TV. Вредоносные программы смогут воспользоваться этим для удаления или изменения информации о звонках."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Приложение сможет вносить изменения в список вызовов телефона и данные о входящих и исходящих звонках. Вредоносные приложения смогут воспользоваться этим для удаления или изменения информации о звонках."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"Датчики (например, пульсометр)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Доступ к данным датчиков на теле (например, пульсу, температуре, уровню кислорода в крови)."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"Доступ к датчикам на теле (например, пульсометру) в фоновом режиме"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Доступ к данным датчиков на теле (например, пульсу, температуре, уровню кислорода в крови) в фоновом режиме."</string>
+ <!-- no translation found for permlab_bodySensors (662918578601619569) -->
+ <skip />
+ <!-- no translation found for permdesc_bodySensors (7652650410295512140) -->
+ <skip />
+ <!-- no translation found for permlab_bodySensors_background (4912560779957760446) -->
+ <skip />
+ <!-- no translation found for permdesc_bodySensors_background (8870726027557749417) -->
+ <skip />
<string name="permlab_readCalendar" msgid="6408654259475396200">"Чтение мероприятий и данных"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Приложение может считывать, отправлять и сохранять информацию о мероприятиях в календаре планшета."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Приложение может считывать, отправлять и сохранять информацию о мероприятиях в календаре устройства Android TV."</string>
@@ -691,8 +695,10 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Приложение сможет считывать аудиофайлы из общего хранилища."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"считывание видеофайлов из общего хранилища"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Приложение сможет считывать видеофайлы из общего хранилища."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"считывание изображений из общего хранилища"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Приложение сможет считывать изображения из общего хранилища."</string>
+ <!-- no translation found for permlab_readMediaImages (4057590631020986789) -->
+ <skip />
+ <!-- no translation found for permdesc_readMediaImages (5836219373138469259) -->
+ <skip />
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"Изменение или удаление данных на общем накопителе"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Приложение сможет записывать данные на общий накопитель."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"Входящие и исходящие вызовы SIP"</string>
@@ -914,7 +920,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Нажмите \"Меню\", чтобы разблокировать экран или вызвать службу экстренной помощи."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Для разблокировки нажмите \"Меню\"."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Введите графический ключ"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Экстренный вызов"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Экстренный вызов"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Вернуться к вызову"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Правильно!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Повторите попытку"</string>
@@ -1053,7 +1059,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Никогда"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"У вас нет доступа к этой странице."</string>
<string name="text_copied" msgid="2531420577879738860">"Текст скопирован в буфер обмена."</string>
- <string name="copied" msgid="4675902854553014676">"Скопировано"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Данные из приложения \"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>\" вставлены в приложение \"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>\"."</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Приложение \"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>\" вставило данные из буфера обмена."</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>: скопированный текст вставлен"</string>
@@ -1454,8 +1459,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Разрешает приложению игнорировать ограничение на расход заряда батареи."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"Запрос информации обо всех пакетах"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Приложение сможет просматривать все установленные пакеты."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"Доступ к SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Приложение сможет получать доступ к SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"доступ к AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Приложение сможет получать доступ к AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"доступ к AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Приложение сможет получать доступ к AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"доступ к AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Приложение сможет получать доступ к AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Нажмите дважды для изменения масштаба"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Не удалось добавить виджет."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Выбрать"</string>
@@ -1718,6 +1727,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Смена профиля на \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Выход из аккаунта <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Владелец"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Гость"</string>
<string name="error_message_title" msgid="4082495589294631966">"Ошибка"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Это действие запрещено администратором"</string>
<string name="app_not_found" msgid="3429506115332341800">"Невозможно обработать это действие"</string>
@@ -2029,10 +2039,11 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"УДАЛИТЬ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ОТКРЫТЬ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Обнаружено вредоносное приложение"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Запрос на доступ к системным журналам"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Разрешить приложению \"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>\" доступ ко всем журналам устройства?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Только в этот раз"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Запретить"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> запрашивает доступ к системным журналам для отладки функций. В этих журналах может содержаться информация, записанная приложениями и сервисами на вашем устройстве."</string>
+ <!-- no translation found for log_access_confirmation_body (4483075525611652922) -->
+ <skip />
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Больше не показывать"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Приложение \"<xliff:g id="APP_0">%1$s</xliff:g>\" запрашивает разрешение на показ фрагментов приложения \"<xliff:g id="APP_2">%2$s</xliff:g>\"."</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Изменить"</string>
@@ -2267,4 +2278,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Приложение \"<xliff:g id="APP">%1$s</xliff:g>\" работает в фоновом режиме уже длительное время. Нажмите, чтобы узнать подробности."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверить активные приложения"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Камера на этом устройстве недоступна."</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 63976d6..419e9f5 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> සඳහා ඔබේ වාහකය විසින් තාවකාලිකව ක්රියාවිරහිත කරන ලදී"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ජංගම ජාලය වෙත ළඟා විය නොහැකිය"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"කැමති ජාලය වෙනස් කිරීමට උත්සාහ කරන්න. වෙනස් කිරීමට තට්ටු කරන්න."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"හදිසි ඇමතුම් ලබා ගත නොහැකිය"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi-Fi හරහා හදිසි ඇමතුම් ලබා ගත නොහැකිය"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"හදිසි ඇමතුම් ලබා ගත නොහැකි වීමට ඉඩ ඇත"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi හරහා හදිසි ඇමතුම් සඳහා සහාය නොදක්වයි. විස්තර සඳහා තට්ටු කරන්න."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"ඇඟවීම්"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"ඇමතුම ප්රතියොමු කිරීම"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"හදිසි අවස්ථා පසු ඇමතුම් ප්රකාරය"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ලැබෙන ඇමතුම් සහ පිටවන ඇමතුම් දත්ත ඇතුළත්ව ඔබගේ ටැබ්ලටයේ ඇමතුම් ලොගය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ ඇමතුම් ලොගය මැකීමට හෝ වෙනස් කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිතා කෙරේ."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ලැබෙන ඇමතුම් සහ පිටවන ඇමතුම් දත්ත ඇතුළත්ව ඔබගේ Android TV උපාංගයෙහි ඇමතුම් ලොගය වෙනස් කිරීමට යෙදුමට ඉඩ දෙයි. ඔබගේ ඇමතුම් ලොගය මැකීමට හෝ වෙනස් කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කළ හැකිය."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"පැමිණෙන සහ පිටවෙන ඇමතුම් දත්ත ඇතුළුව ඔබගේ දුරකථනයේ ඇමතුම් ලොගය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ ඇමතුම් ලොගය මැකීමට හෝ වෙනස් කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කල හැක."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"දේහ සංවේදකවලට (හෘද ස්පන්දන වේග මොනිටර වැනි) පිවිසීම"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"හෘද ස්පන්දන වේගය, උෂ්ණත්වය, රුධිර ඔක්සිජන් ප්රතිශතය වැනි ශරීර සංවේදකවලින් දත්ත වෙත ප්රවේශය."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"පසුබිමේ සිටියදී ශරීර සංවේදක (හෘද ස්පන්දන වේග මොනිටර වැනි) වෙත ප්රවේශය"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"පසුබිමේ සිටියදී, හෘද ස්පන්දන වේගය, උෂ්ණත්වය, රුධිර ඔක්සිජන් ප්රතිශතය වැනි ශරීර සංවේදකවලින් දත්ත වෙත ප්රවේශය."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"භාවිතයේ ඇති අතරතුර හෘද ස්පන්දන වේගය වැනි ශරීර සංවේදක දත්ත වෙත ප්රවේශ වන්න"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"යෙදුම භාවිතයේ පවතින අතරතුර හෘද ස්පන්දන වේගය, උෂ්ණත්වය සහ රුධිර ඔක්සිජන් ප්රතිශතය වැනි ශරීර සංවේදක දත්ත වෙත ප්රවේශ වීමට යෙදුමට අවසර දෙයි."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"පසුබිමේ ඇති අතරතුර හෘද ස්පන්දන වේගය වැනි ශරීර සංවේදක දත්ත වෙත ප්රවේශ වන්න"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"යෙදුම පසුබිමේ ඇති අතර හෘද ස්පන්දන වේගය, උෂ්ණත්වය සහ රුධිර ඔක්සිජන් ප්රතිශතය වැනි ශරීර සංවේදක දත්ත වෙත ප්රවේශ වීමට යෙදුමට අවසර දෙයි."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"දින දර්ශන සිදුවීම් හා විස්තර කියවන්න"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"මෙම යෙදුමට ඔබගේ ටැබ්ලට් පරිගණකය මත ගබඩා වී ඇති සියලු දින දර්ශන කියවීමට සහ සහ ඔබගේ දින දර්ශන දත්ත බෙදා ගැනීමට සහ සුරැකීමට හැකිය."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"මෙම යෙදුමට ඔබගේ Android TV මත ගබඩා කර ඇති සියලු දින දර්ශන සිදුවීම් කියවීමට සහ ඔබගේ දින දර්ශන දත්ත බෙදා ගැනීමට හෝ සුරැකීමට හැකිය."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"ඔබගේ බෙදා ගත් ගබඩාවෙන් ශ්රව්ය ගොනු කියවීමට යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"බෙදා ගත් ගබඩාවෙන් වීඩියෝ ගොනු කියවන්න"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"ඔබගේ බෙදා ගත් ගබඩාවෙන් වීඩියෝ ගොනු කියවීමට යෙදුමට ඉඩ දෙයි."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"බෙදා ගත් ගබඩාවෙන් රූප ගොනු කියවන්න"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"ඔබගේ බෙදා ගත් ගබඩාවෙන් රූප ගොනු කියවීමට යෙදුමට ඉඩ දෙයි."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"බෙදා ගත් ගබඩාවෙන් රූප ගොනු කියවන්න"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"ඔබගේ බෙදා ගත් ගබඩාවෙන් රූප ගොනු කියවීමට යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"ඔබේ බෙදා ගත් ගබඩාවේ අන්තර්ගත වෙනස් කරන්න නැතහොත් මකන්න"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"යෙදුමට ඔබේ බෙදා ගත් ගබඩාවේ අන්තර්ගත කියවීමට ඉඩ දෙයි."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP ඇමතුම් සිදුකිරීමට/ලබාගැනීමට"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"අගුළු හැරීමට මෙනුව ඔබන්න හෝ හදිසි ඇමතුම ලබාගන්න."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"අගුළු හැරීමට මෙනු ඔබන්න."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"අගුළු ඇරීමට රටාව අඳින්න"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"හදිසි ඇමතුම"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"හදිසි"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"ඇමතුම වෙත නැවත යන්න"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"නිවැරදියි!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"නැවත උත්සාහ කරන්න"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"කවදාවත් නොවේ"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"මෙම පිටුව විවෘත කිරීමට ඔබට අවසර නැත."</string>
<string name="text_copied" msgid="2531420577879738860">"පෙළ පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
- <string name="copied" msgid="4675902854553014676">"පිටපත් කළා"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> වෙතින් අලවන ලදි"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"ඔබගේ පසුරු පුවරුව වෙතින් <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> පිටපත් කරන ලදි"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ඔබ පිටපත් කළ පෙළ ඇලවීය"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"යෙදුමකට එම යෙදුම සඳහා බැටරි ප්රශස්තකරණ නොසලකා හැරීමට අවසර ඉල්ලීමට ඉඩ දෙයි."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"සියලු පැකේජ විමසන්න"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"ස්ථාපනය කර ඇති සියලු පැකේජ බැලීමට යෙදුමකට ඉඩ දෙයි."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis වෙත ප්රවේශ වන්න"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"SupplementalApis වෙත ප්රවේශ වීමට යෙදුමකට ඉඩ දෙයි."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API වෙත ප්රවේශ වන්න"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"AdServices Topics API වෙත ප්රවේශ වීමට යෙදුමකට ඉඩ දෙයි."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API වෙත ප්රවේශ වන්න"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"AdServices Attribution API වෙත ප්රවේශ වීමට යෙදුමකට ඉඩ දෙයි."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API වෙත ප්රවේශ වන්න"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"AdServices Custom Audiences API වෙත ප්රවේශ වීමට යෙදුමකට ඉඩ දෙයි."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"විශාලන පාලක සඳහා දෙවතාවක් තට්ටු කරන්න"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"විජටය එකතු කිරීමට නොහැකි විය."</string>
<string name="ime_action_go" msgid="5536744546326495436">"යන්න"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> වෙත මාරු කරමින්…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> වරමින්…"</string>
<string name="owner_name" msgid="8713560351570795743">"හිමිකරු"</string>
+ <string name="guest_name" msgid="8502103277839834324">"ආගන්තුක"</string>
<string name="error_message_title" msgid="4082495589294631966">"දෝෂය"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ඔබගේ පරිපාලක විසින් මෙම වෙනස් කිරීමට ඉඩ නොදේ"</string>
<string name="app_not_found" msgid="3429506115332341800">"මෙම ක්රියාව හසුරුවීමට යෙදුමක් සොයාගත්තේ නැත"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"අස්ථාපනය කරන්න"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"කෙසේ වුවත් විවෘත කරන්න"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"හානිකර යෙදුමක් අනාවරණය කර ගන්නා ලදී"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"පද්ධති ලොග ප්රවේශ ඉල්ලීම"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> හට සියලු උපාංග ලොග ප්රවේශ වීමට ඉඩ දෙන්නද?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"මෙම වතාවේ පමණි"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"ඉඩ නොදෙන්න"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ක්රියාකාරී නිදොස් කිරීම සඳහා පද්ධති ලොග ඉල්ලයි. මෙම ලොගවල ඔබගේ උපාංගයේ යෙදුම් සහ සේවා ලියා ඇති තොරතුරු අඩංගු විය හැකිය."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"උපාංග ලොග ඔබගේ උපාංගයේ සිදු වන දේ වාර්තා කරයි. ගැටලු සොයා ගැනීමට සහ විසඳීමට යෙදුම්වලට මෙම ලොග භාවිත කළ හැකිය.\n\nසමහර ලොගවල සංවේදී තොරතුරු අඩංගු විය හැකිය, එබැවින් ඔබ විශ්වාස කරන යෙදුම්වලට පමණක් සියලු උපාංග ලොග වෙත ප්රවේශ වීමට ඉඩ දෙන්න. \n\nඔබ මෙම යෙදුමට සියලු උපාංග ලොග වෙත ප්රවේශ වීමට ඉඩ නොදෙන්නේ නම්, එයට තවමත් එහිම ලොග වෙත ප්රවේශ විය හැකි අතර ඔබගේ උපාංග නිෂ්පාදකයාට තවමත් ඔබගේ උපාංගයේ සමහර ලොග හෝ තොරතුරු වෙත ප්රවේශ විය හැකිය. තව දැන ගන්න"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"නැවත නොපෙන්වන්න"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> හට කොටස් <xliff:g id="APP_2">%2$s</xliff:g>ක් පෙන්වීමට අවශ්යයි"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"සංස්කරණය"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> දිගු වේලාවක් පසුබිමේ ධාවනය වේ. සමාලෝචනය කිරීමට තට්ටු කරන්න."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"සක්රිය යෙදුම් පරීක්ෂා කරන්න"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"මෙම උපාංගයෙන් කැමරාවට ප්රවේශ විය නොහැකිය"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index d06177d..efe468b 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -87,8 +87,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Dočasne vypnuté operátorom pre SIM kartu <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nepodarilo sa pripojiť k mobilnej sieti"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Skúste zmeniť predvolenú sieť. Zmeníte ju klepnutím."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Tiesňové volania nie sú k dispozícii"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Nedajú sa uskutočniť tiesňové volania cez Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Tiesňové volanie môže byť nedostupné"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> nepodporuje tiesňové volanie cez Wi‑Fi. Klepnutím zobrazíte podrobnosti."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozornenia"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Presmerovanie hovorov"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Režim tiesňového spätného volania"</string>
@@ -427,10 +427,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Umožňuje aplikácii upravovať denník hovorov vo vašom tablete vrátane údajov o prichádzajúcich a odchádzajúcich hovoroch. Škodlivé aplikácie to môžu zneužiť na vymazanie alebo úpravu vášho denníka hovorov."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Umožňuje aplikácii upravovať denník hovorov zariadenia Android TV vrátane údajov o prichádzajúcich a odchádzajúcich hovoroch. Škodlivé aplikácie to môžu zneužiť na vymazanie alebo úpravu denníkov hovorov."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Umožňuje aplikácii upravovať zoznam hovorov vo vašom telefóne vrátane údajov o prichádzajúcich a odchádzajúcich hovoroch. Škodlivé aplikácie to môžu zneužiť na vymazanie alebo úpravu vášho zoznamu hovorov."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"prístup k telovým senzorom (ako sú snímače tepu)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Prístup k údajom z telových senzorov, ako sú pulz, teplota, saturácia atď."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"prístup k telovým senzorom (ako sú snímače pulzu) na pozadí"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Prístup k údajom z telových senzorov, ako sú pulz, teplota, saturácia atď., na pozadí."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Prístup k dátam telových senzorov (napríklad pulzu) počas používania"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Poskytne aplikácii prístup k dátam telových senzorov, ako sú pulz, teplota a saturácia krvi kyslíkom počas používania aplikácie."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Prístup k dátam telových senzorov (napríklad pulzu) počas spustenia na pozadí"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Poskytne aplikácii prístup k dátam telových senzorov, ako sú pulz, teplota a saturácia krvi kyslíkom počas spustenia aplikácie na pozadí."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Čítanie udalostí kalendára a podrobností"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Táto aplikácia môže čítať všetky udalosti kalendára uložené vo vašom tablete a zdieľať alebo ukladať dáta kalendára."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Táto aplikácia môže čítať všetky udalosti kalendára uložené vo vašom zariadení Android TV a zdieľať alebo ukladať údaje kalendára."</string>
@@ -691,8 +691,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Umožňuje aplikácii čítať zvukové súbory z vášho zdieľaného priestoru."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"čítať videosúbory zo zdieľaného priestoru"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Umožňuje aplikácii čítať videosúbory z vášho zdieľaného priestoru."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"čítať súbory obrázka zo zdieľaného priestoru"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Umožňuje aplikácii čítať súbory obrázka z vášho zdieľaného priestoru."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"čítať súbory obrázka zo zdieľaného priestoru"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Umožňuje aplikácii čítať súbory obrázka z vášho zdieľaného priestoru."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"upravovanie alebo odstraňovanie obsahu zdieľaného úložiska"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Umožňuje aplikácii zapisovať obsah zdieľaného úložiska."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"uskutočňovanie/príjem hovorov SIP"</string>
@@ -914,7 +914,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Ak chcete odomknúť telefón alebo uskutočniť tiesňové volanie, stlačte Menu."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Telefón odomknete stlačením tlačidla Menu."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Odomknite nakreslením vzoru"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Tiesňové volanie"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Stav tiesne"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Zavolať späť"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Správne!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Skúsiť znova"</string>
@@ -1053,7 +1053,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nikdy"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nemáte povolenie na otvorenie tejto stránky."</string>
<string name="text_copied" msgid="2531420577879738860">"Text bol skopírovaný do schránky."</string>
- <string name="copied" msgid="4675902854553014676">"Skopírované"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Aplikácia <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> prilepila údaje z aplikácie <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Aplikácia <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vložila obsah zo schránky"</string>
<string name="pasted_text" msgid="4298871641549173733">"Aplikácia <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> prilepila text, ktorý ste skopírovali"</string>
@@ -1454,8 +1453,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Umožňuje aplikácii požiadať o povolenie ignorovať optimalizácie výdrže batérie pre danú aplikáciu."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"dopytovať všetky balíky"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Povoľuje aplikácii čítať všetky nainštalované balíky."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"prístup k rozhraniam SupplementalApi"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Umožňuje aplikácii získať prístup k rozhraniam SupplementalApi."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"prístup k rozhraniu AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Umožňuje aplikácii prístup k rozhraniu AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"prístup k rozhraniam AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Umožňuje aplikácii prístup k rozhraniam AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"prístup k rozhraniu AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Umožňuje aplikácii prístup k rozhraniu AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Dvojitým klepnutím môžete ovládať priblíženie"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Miniaplikáciu sa nepodarilo pridať."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Hľadať"</string>
@@ -1718,6 +1721,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Prepína sa na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Prebieha odhlásenie používateľa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Vlastník"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Hosť"</string>
<string name="error_message_title" msgid="4082495589294631966">"Chyba"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Správca túto zmenu zakázal"</string>
<string name="app_not_found" msgid="3429506115332341800">"Aplikácia potrebná na spracovanie tejto akcie sa nenašla"</string>
@@ -2029,10 +2033,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ODINŠTALOVAŤ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OTVORIŤ AJ TAK"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Bola zistená škodlivá aplikácia"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Žiadosť o prístup k denníku systému"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Chcete povoliť aplikácii <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> prístup k všetkým denníkom zariadenia?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Iba tentokrát"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nepovoliť"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> žiada o denníky systému na účely funkčného ladenia. Môžu obsahovať informácie zapísané aplikáciami a službami vo vašom zariadení."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Denníky zariadenia zaznamenávajú, čo sa deje vo vašom zariadení. Aplikácie môžu pomocou týchto denníkov vyhľadávať a riešiť problémy.\n\nNiektoré denníky môžu obsahovať citlivé údaje, preto povoľte prístup k všetkým denníkom zariadenia iba dôveryhodným aplikáciám. \n\nAk tejto aplikácii nepovolíte prístup k všetkým denníkom zariadenia, stále bude mať prístup k vlastným denníkom a výrobca vášho zariadenia bude mať naďalej prístup k niektorým denníkom alebo informáciám vo vašom zariadení. Ďalšie informácie"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Už nezobrazovať"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> chce zobrazovať rezy z aplikácie <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Upraviť"</string>
@@ -2267,4 +2271,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikácia <xliff:g id="APP">%1$s</xliff:g> je dlhodobo spustená na pozadí. Skontrolujte to klepnutím."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Skontrolovať aktívne aplikácie"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"V tomto zariadení nemáte prístup ku kamere"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index c1fbb04..61d3cb6 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -87,8 +87,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Operater je začasno izklopil storitev za kartico SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilnega omrežja ni mogoče doseči"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Poskusite spremeniti prednostno omrežje. Dotaknite se, če ga želite spremeniti."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Klicanje v sili ni na voljo"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Klicev v sili ni mogoče opravljati prek omrežja Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Klici v sili morda niso na voljo."</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ne podpira klicev v sili prek Wi-Fi-ja. Dotaknite se za podrobnosti."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Opozorila"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmerjanje klicev"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Način za povratni klic v sili"</string>
@@ -427,10 +427,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Aplikaciji dovoli spreminjanje dnevnika klicev v tabličnem računalniku, vključno s podatki o dohodnih in odhodnih klicih. Zlonamerne aplikacije lahko tako izbrišejo ali spreminjajo vaš dnevnik klicev."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Aplikaciji dovoljuje spreminjanje dnevnika klicev v napravi Android TV, vključno s podatki o dohodnih in odhodnih klicih. Zlonamerne aplikacije lahko tako izbrišejo ali spreminjajo vaš dnevnik klicev."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Aplikaciji dovoli spreminjanje dnevnika klicev v telefonu, vključno s podatki o dohodnih in odhodnih klicih. Zlonamerne aplikacije lahko tako izbrišejo ali spreminjajo vaš dnevnik klicev."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"dostop do tipal telesnih funkcij (npr. merilnikov srčnega utripa)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Dostop do podatkov iz tipal telesnih funkcij, kot so srčni utrip, temperatura, odstotek kisika v krvi itd."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"dostop do tipal telesnih funkcij (npr. merilnika srčnega utripa) v ozadju"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Dostop do podatkov iz tipal telesnih funkcij, kot so srčni utrip, temperatura, odstotek kisika v krvi itd., med delovanjem v ozadju."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Dostop do podatkov tipal telesnih funkcij, kot je srčni utrip, ko je v uporabi"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Aplikaciji dovoljuje dostop do podatkov tipal telesnih funkcij, kot so srčni utrip, temperatura, odstotek kisika v krvi, ko je aplikacija v uporabi."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Dostop do podatkov tipal telesnih funkcij, kot je srčni utrip, ko je v ozadju"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Aplikaciji dovoljuje dostop do podatkov tipal telesnih funkcij, kot so srčni utrip, temperatura, odstotek kisika v krvi, ko je aplikacija v ozadju."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Branje dogodkov v koledarjih in podrobnosti koledarjev"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ta aplikacija lahko prebere vse dogodke v koledarju, ki so shranjeni v tabličnem računalniku, ter shrani podatke koledarja ali jih deli z drugimi."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ta aplikacija lahko prebere vse dogodke v koledarju, ki so shranjeni v napravi Android TV, ter shrani podatke koledarja ali jih deli z drugimi."</string>
@@ -691,8 +691,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Aplikaciji omogoča branje zvočnih datotek v deljeni shrambi."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"branje videodatotek v deljeni shrambi"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Aplikaciji omogoča branje videodatotek v deljeni shrambi."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"branje slikovnih datotek v deljeni shrambi"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Aplikaciji omogoča branje slikovnih datotek v deljeni shrambi."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"branje slikovnih datotek v deljeni shrambi"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Aplikaciji omogoča branje slikovnih datotek v deljeni shrambi."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"spreminjanje ali brisanje vsebine skupne shrambe"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Aplikaciji omogoča zapisovanje vsebine skupne shrambe."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"opravljanje/sprejemanje klicev SIP"</string>
@@ -914,7 +914,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Če želite odkleniti napravo ali opraviti klic v sili, pritisnite meni."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Če želite odkleniti, pritisnite meni."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Če želite odkleniti, narišite vzorec"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Klic v sili"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Klic v sili"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Nazaj na klic"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Pravilno."</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Poskusi znova"</string>
@@ -1053,7 +1053,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Nikoli"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nimate dovoljenja za odpiranje te strani."</string>
<string name="text_copied" msgid="2531420577879738860">"Besedilo, kopirano v odložišče."</string>
- <string name="copied" msgid="4675902854553014676">"Kopirano"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prilepila iz aplikacije <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>."</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prilepila iz odložišča."</string>
<string name="pasted_text" msgid="4298871641549173733">"Aplikacija <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> je prilepila besedilo iz odložišča."</string>
@@ -1454,8 +1453,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Aplikaciji dovoljuje, da vpraša za dovoljenje, ali naj prezre optimizacije baterije."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"poizvedovanje po vseh paketih"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Aplikaciji dovoli, da vidi vse nameščene pakete."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"dostop do SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Aplikaciji omogoča dostop do SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"dostop do API-ja AdServices Topics"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Aplikaciji omogoča dostop do API-ja AdServices Topics."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"dostop do API-jev AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Aplikaciji omogoča dostop do API-jev AdServices Attribution."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"dostop do API-ja AdServices Custom Audiences"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Aplikaciji omogoča dostop do API-ja AdServices Custom Audiences."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tapnite dvakrat za nadzor povečave/pomanjšave"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Pripomočka ni bilo mogoče dodati."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Pojdi"</string>
@@ -1718,6 +1721,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Preklop na uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Odjavljanje uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="owner_name" msgid="8713560351570795743">"Lastnik"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gost"</string>
<string name="error_message_title" msgid="4082495589294631966">"Napaka"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Skrbnik ne dovoli te spremembe"</string>
<string name="app_not_found" msgid="3429506115332341800">"Najdena ni bila nobena aplikacija za izvedbo tega dejanja"</string>
@@ -2029,10 +2033,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ODMESTI"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"VSEENO ODPRI"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Zaznana je bila škodljiva aplikacija"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Zahteva za dostop do sistemskega dnevnika"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Ali aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> dovolite dostop do vseh dnevnikov naprave?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Samo tokrat"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ne dovoli"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> zahteva sistemske dnevnike za funkcionalno odpravljanje napak. Ti dnevniki lahko vsebujejo podatke, ki so jih zapisale aplikacije in storitve v vaši napravi."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"V dnevnikih naprave se beleži dogajanje v napravi. Aplikacije lahko te dnevnike uporabijo za iskanje in odpravljanje težav.\n\nNekateri dnevniki morda vsebujejo občutljive podatke, zato dostop do vseh dnevnikov naprave omogočite le aplikacijam, ki jim zaupate. \n\nČe tej aplikaciji ne dovolite dostopa do vseh dnevnikov naprave, bo aplikacija kljub temu lahko dostopala do svojih dnevnikov, proizvajalec naprave pa do nekaterih dnevnikov ali podatkov v napravi. Več o tem"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikaži več"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi prikazati izreze aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Uredi"</string>
@@ -2267,4 +2271,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> se dolgo časa izvaja v ozadju. Dotaknite se za pregled."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Preverite aktivne aplikacije"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"V tej napravi ni mogoče dostopati do fotoaparata."</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 6303818..46a6d7b 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Çaktivizuar përkohësisht nga operatori yt celular për kartën SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Rrjeti celular është i paarritshëm"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Provo të ndryshosh rrjetin e preferuar. Trokit për ta ndryshuar."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Telefonatat e urgjencës nuk ofrohen"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Nuk mund të kryhen telefonata urgjence me Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Telefonatat e urgjencës mund të mos ofrohen"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> nuk i mbështet telefonatat e urgjencës nëpërmjet Wi-Fi. Trokit për detaje."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Sinjalizimet"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Transferimi i telefonatave"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modaliteti i \"Kthimit të telefonatës së urgjencës\""</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Lejon aplikacionin të modifikojë ditarin e telefonatave të tabletit tënd, përfshirë të dhëna rreth telefonatave hyrëse dhe dalëse. Aplikacione keqdashëse mund ta përdorin këtë leje për të fshirë ose modifikuar ditarin tënd të telefonatave."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Lejon aplikacionin të modifikojë ditarin e telefonatave të pajisjes sate Android TV, duke përfshirë të dhëna rreth telefonatave hyrëse dhe dalëse. Aplikacionet keqdashëse mund ta përdorin këtë për të spastruar ose modifikuar evidencën tënde të telefonatave."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Lejon aplikacionin të modifikojë ditarin e telefonatave të telefonit tënd, përfshirë të dhënat rreth telefonatave hyrëse dhe dalëse. Aplikacionet keqdashëse mund ta përdorin këtë për të fshirë ose modifikuar ditarin tënd të telefonatave."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"qasu te sensorët e trupit (si monitorimet e rrahjeve të zemrës)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Qasje te të dhënat nga sensorët e trupit, si p.sh. rrahjet e zemrës, temperatura, përqindja e oksigjenit në gjak etj."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"qasje te sensorët e trupit (si p.sh. monitorët e rrahjeve të zemrës) ndërkohë që është në sfond"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Qasje te të dhënat nga sensorët e trupit, si p.sh. rrahjet e zemrës, temperatura, përqindja e oksigjenit në gjak etj. ndërkohë që është në sfond."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Qasje te të dhënat e sensorit të trupit, si p.sh. rrahjet e zemrës kur përdoret"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Lejon aplikacionin që të ketë qasje te të dhënat e sensorit të trupit, si p.sh. rrahjet e zemrës, temperatura dhe përqindja e oksigjenit në gjak ndërkohë që aplikacioni është në përdorim."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Qasje te të dhënat e sensorit të trupit, si rrahjet e zemrës kur është në sfond"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Lejon aplikacionin që të ketë qasje te të dhënat e sensorit të trupit, si p.sh. rrahjet e zemrës, temperatura dhe përqindja e oksigjenit në gjak ndërkohë që aplikacioni është në sfond."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Lexo ngjarjet e kalendarit dhe detajet"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ky aplikacion mund të lexojë të gjitha ngjarjet e kalendarit të ruajtura në tabletin tënd dhe të ndajë ose të ruajë të dhënat e kalendarit."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ky aplikacion mund të lexojë të gjitha ngjarjet e kalendarit të ruajtura në pajisjen tënde Android TV dhe të ndajë ose të ruajë të dhënat e kalendarit."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Lejon që aplikacioni të lexojë skedarët audio nga hapësira ruajtëse e ndarë."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"të lexojë skedarët e videove nga hapësira ruajtëse e ndarë"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Lejon që aplikacioni të lexojë skedarët e videove nga hapësira ruajtëse e ndarë."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"të lexojë skedarët e imazheve nga hapësira ruajtëse e ndarë"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Lejon që aplikacioni të lexojë skedarët e imazheve nga hapësira ruajtëse e ndarë."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"të lexojë skedarët e imazheve nga hapësira ruajtëse e ndarë"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Lejon që aplikacioni të lexojë skedarët e imazheve nga hapësira ruajtëse e ndarë."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"modifiko ose fshi përmbajtjet e hapësirës ruajtëse të ndarë"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Lejon që aplikacioni të shkruajë përmbajtjet e hapësirës ruajtëse të ndarë."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"bëj/merr telefonata SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Shtyp \"Meny\" për të shkyçur ose për të kryer telefonatë urgjence."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Shtyp \"Meny\" për të shkyçur."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Vizato modelin për ta shkyçur"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Telefonata e urgjencës"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Urgjenca"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Kthehu te telefonata"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Saktë!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Provo sërish"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Asnjëherë"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Nuk ke leje për ta hapur këtë faqe."</string>
<string name="text_copied" msgid="2531420577879738860">"Teksti u kopjua në kujtesën e fragmenteve."</string>
- <string name="copied" msgid="4675902854553014676">"U kopjua"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> u ngjit nga <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ngjiti përmbajtje nga kujtesa jote e fragmenteve"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ngjiti një tekst që kopjove"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Lejon që një aplikacion të kërkojë leje për të shpërfillur optimizimet e baterisë për atë aplikacion."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"kërko të gjitha paketat"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Lejon një aplikacion të shikojë të gjitha paketat e instaluara."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"qasje te SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Lejon një aplikacion të ketë qasje në SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"qasje në AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Lejon një aplikacion të ketë qasje në AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"qasje në AdServices Attribution APIs"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Lejon një aplikacion që të ketë qasje në AdServices Attribution APIs."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"qasje në AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Lejon një aplikacion të ketë qasje në AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Trokit dy herë për të kontrolluar zmadhimin"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Nuk mundi të shtonte miniaplikacion."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Shko"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Po kalon në \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> po del…"</string>
<string name="owner_name" msgid="8713560351570795743">"Zotëruesi"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Vizitor"</string>
<string name="error_message_title" msgid="4082495589294631966">"Gabim"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Ky ndryshim nuk lejohet nga administratori"</string>
<string name="app_not_found" msgid="3429506115332341800">"Nuk u gjet asnjë aplikacion për të menaxhuar këtë veprim"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ÇINSTALO"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"HAPE GJITHSESI"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"U gjet aplikacion i dëmshëm"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Kërkesë për qasje te evidenca e sistemit"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Të lejohet që <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> të ketë qasje te të gjitha evidencat e pajisjes?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Vetëm këtë herë"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Mos lejo"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> kërkon evidenca të sistemit për korrigjim funksional. Këto evidenca mund të përmbajnë informacione që kanë shkruar aplikacionet dhe shërbimet në pajisjen tënde."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Evidencat e pajisjes regjistrojnë çfarë ndodh në pajisjen tënde. Aplikacionet mund t\'i përdorin këto evidenca për të gjetur dhe rregulluar problemet.\n\nDisa evidenca mund të përmbajnë informacione delikate, ndaj lejo vetëm aplikacionet që u beson të kenë qasje te të gjitha evidencat e pajisjes. \n\nNëse nuk e lejon këtë aplikacion që të ketë qasje te të gjitha evidencat e pajisjes, ai mund të ketë ende qasje tek evidencat e tij dhe prodhuesi i pajisjes sate mund të jetë ende në gjendje që të ketë qasje te disa evidenca ose informacione në pajisjen tënde. Mëso më shumë"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Mos e shfaq më"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> dëshiron të shfaqë pjesë të <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Modifiko"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> po ekzekutohet në sfond për një kohe të gjatë. Trokit për ta shqyrtuar."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Kontrollo aplikacionet aktive"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nuk mund të qasesh te kamera nga kjo pajisje"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index d9b1931..a49f9a5 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -86,8 +86,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Привремено је искључио мобилни оператер за SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Повезивање са мобилном мрежом није успело"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Пробајте да промените жељену мрежу. Додирните да бисте променили."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Хитни позиви нису доступни"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Не можете да упућујете хитне позиве преко Wi‑Fi-ја"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Хитни позиви можда нису доступни"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> не подржава хитне позиве преко WiFi-ја. Додирните за детаље."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Обавештења"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Преусмеравање позива"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим за хитан повратни позив"</string>
@@ -426,10 +426,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Дозвољава апликацији да мења евиденцију позива на таблету, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би брисале или мењале евиденцију позива."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Дозвољава апликацији да мења евиденцију позива на Android TV уређају, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе за брисање или мењање евиденције позива."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Дозвољава апликацији да мења евиденцију позива на телефону, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би брисале или мењале евиденцију позива."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"приступ сензорима на телу (попут монитора за праћење пулса)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Приступ подацима сензора за тело, попут пулса, температуре, проценат кисеоника у крви итд."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"приступ сензорима на телу (нпр. монитори за праћење пулса) током рада у позадини"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Приступ подацима сензора за тело, попут пулса, температуре, проценат кисеоника у крви итд, током рада у позадини."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Приступ подацима сензора за тело, као што је пулс, у току коришћења"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Дозвољава апликацији да приступа подацима сензора за тело, као што су пулс, температура и проценат кисеоника у крви док се апликација користи."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Приступ подацима сензора за тело, као што је пулс, у позадини"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Дозвољава апликацији да приступа подацима сензора за тело, као што су пулс, температура и проценат кисеоника у крви док је апликација у позадини."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Читање догађаја и података из календара"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ова апликација може да чита све догађаје из календара које чувате на таблету, као и да дели или чува податке из календара."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ова апликација може да чита све догађаје из календара које чувате на Android TV уређају, као и да дели или чува податке из календара."</string>
@@ -690,8 +690,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Омогућава апликацији да чита аудио фајлове из дељеног меморијског простора."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"читање видео фајлова из дељеног меморијског простора"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Омогућава апликацији да чита видео фајлове из дељеног меморијског простора."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"читање фајлова слика из дељеног меморијског простора"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Омогућава апликацији да чита фајлове слика из дељеног меморијског простора."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"читање фајлова слика из дељеног меморијског простора"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Омогућава апликацији да чита фајлове слика из дељеног меморијског простора."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"мењање или брисање садржаја дељеног меморијског простора"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Дозвољава апликацији да уписује садржај дељеног меморијског простора."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"упућивање/пријем SIP позива"</string>
@@ -913,7 +913,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Притисните „Мени“ да бисте откључали телефон или упутите хитан позив."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Притисните „Мени“ за откључавање."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Унесите шаблон за откључавање"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Хитан позив"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Хитне службе"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Назад на позив"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Тачно!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Пробајте поново"</string>
@@ -1052,7 +1052,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Никад"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Немате дозволу да отворите ову страницу."</string>
<string name="text_copied" msgid="2531420577879738860">"Текст је копиран у привремену меморију."</string>
- <string name="copied" msgid="4675902854553014676">"Копирано је"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила податке из апликације <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је прелепио/ла из привремене меморије"</string>
<string name="pasted_text" msgid="4298871641549173733">"Апликација<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> је налепила текст који сте копирали"</string>
@@ -1453,8 +1452,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Дозвољава апликацији да тражи дозволу за игнорисање оптимизација батерије за ту апликацију."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"слање упита за све пакете"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Дозвољава апликацији да види све инсталиране пакете."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"приступ ставци SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Дозвољава апликацији да приступа ставци SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"приступ API-ју за теме услуга огласа"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Дозвољава апликацији да приступа API-ју за теме услуга огласа."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"приступ API-јима за приписивање услуга огласа"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Дозвољава апликацији да приступа API-јима за дистрибуцију услуга огласа."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"приступ API-ју за прилагођене публике услуга огласа"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Дозвољава апликацији да приступа API-ју за прилагођене публике услуга огласа."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Додирните двапут за контролу зумирања"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Није могуће додати виџет."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Иди"</string>
@@ -1717,6 +1720,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Пребацивање на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Одјављује се <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Власник"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Гост"</string>
<string name="error_message_title" msgid="4082495589294631966">"Грешка"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Администратор није дозволио ову промену"</string>
<string name="app_not_found" msgid="3429506115332341800">"Није пронађена ниједна апликација која би могла да обави ову радњу"</string>
@@ -2028,10 +2032,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ДЕИНСТАЛИРАЈ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ИПАК ОТВОРИ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Откривена је штетна апликација"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Захтев за приступ системској евиденцији"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Желите да дозволите апликацији <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> да приступа свим евиденцијама уређаја?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Само овај пут"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Не дозволи"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> захтева евиденције система ради отклањања грешака у функцијама. Те евиденције могу да садрже информације које су апликације и услуге на уређају записале."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Евиденције уређаја региструју шта се дешава на уређају. Апликације могу да користе те евиденције да би пронашле и решиле проблеме.\n\nНеке евиденције могу да садрже осетљиве информације, па приступ свим евиденцијама уређаја треба да дозвољавате само апликацијама у које имате поверења. \n\nАко не дозволите овој апликацији да приступа свим евиденцијама уређаја, она и даље може да приступа сопственим евиденцијама, а произвођач уређаја ће можда и даље моћи да приступа неким евиденцијама или информацијама на уређају. Сазнајте више"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Не приказуј поново"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Апликација <xliff:g id="APP_0">%1$s</xliff:g> жели да приказује исечке из апликације <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Измени"</string>
@@ -2266,4 +2270,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Апликација <xliff:g id="APP">%1$s</xliff:g> је предуго покренута у позадини. Додирните да бисте прегледали."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверите активне апликације"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Не можете да приступите камери са овог уређаја"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index a969fac..a6cad24 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Tillfälligt avstängt av operatören för SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Det går inte att nå mobilnätverket"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Testa att byta föredraget nätverk. Tryck om du vill ändra."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Det går inte att ringa nödsamtal"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Det går inte att ringa nödsamtal via Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Nödsamtal kan vara otillgängligt"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> har inte stöd för nödsamtal via wifi. Tryck här för mer information."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Aviseringar"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Vidarekoppla samtal"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Läget Återuppringning vid nödsamtal"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Tillåter att appen gör ändringar i pekdatorns samtalslista, inklusive i uppgifter om inkommande och utgående samtal. Skadliga program kan använda detta för att radera eller ändra din samtalslista."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Tillåter att appen gör ändringar i Android TV-enhetens samtalshistorik, inklusive i uppgifter om inkommande och utgående samtal. Skadliga appar kan använda detta för att radera eller ändra samtalshistoriken."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Tillåter att appen gör ändringar i mobilens samtalslista, inklusive i uppgifter om inkommande och utgående samtal. Skadliga program kan använda detta för att radera eller ändra din samtalslista."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"få åtkomst till kroppssensorer (till exempel pulsmätare)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Åtkomst till data från kroppssensorer, t.ex. puls, kroppstemperatur, procentandel syre i blodet med mera."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"åtkomst till kroppssensorer (t.ex. pulsmätare) i bakgrunden"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Åtkomst till data från kroppssensorer, t.ex. puls, kroppstemperatur, procentandel syre i blodet med mera, i bakgrunden."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Åtkomst till data från kroppssensorer, t.ex. puls, medan appen används"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Tillåter att appen får åtkomst till data från kroppssensorer, t.ex. puls, kroppstemperatur och blodets syrehalt, medan appen används."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Åtkomst till data från kroppssensorer, t.ex. puls, i bakgrunden"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Tillåter att appen får åtkomst till data från kroppssensorer, t.ex. puls, kroppstemperatur och blodets syrehalt, medan appen är i bakgrunden."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Läsa kalenderhändelser och kalenderuppgifter"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Appen kan läsa alla kalenderhändelser som sparats på surfplattan och dela eller spara uppgifter i din kalender."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Appen kan läsa alla kalenderhändelser som sparats på Android TV-enheten och dela eller spara uppgifter i din kalender."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Tillåter att appen läser ljudfiler från delad lagring."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"läsa videofiler från delad lagring"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Tillåter att appen läser videofiler från delad lagring."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"läsa bildfiler från delad lagring"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Tillåter att appen läser bildfiler från delad lagring."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"läsa bildfiler från delad lagring"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Tillåter att appen läser bildfiler från delad lagring."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"ändra eller ta bort innehåll på delat lagringsutrymme"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Tillåter att appen skriver innehåll på ditt delade lagringsutrymme."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"gör/ta emot SIP-anrop"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Tryck på Menu för att låsa upp eller ringa nödsamtal."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Tryck på Menu för att låsa upp."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Rita mönster för att låsa upp"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Nödsamtal"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Nödsamtal"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Tillbaka till samtal"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Korrekt!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Försök igen"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Aldrig"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Du har inte behörighet att öppna den här sidan."</string>
<string name="text_copied" msgid="2531420577879738860">"Text har kopierats till urklipp."</string>
- <string name="copied" msgid="4675902854553014676">"Kopierat"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> klistrade in från <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> klistrade in från urklipp"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> klistrade in text som du kopierade"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Appen får be om tillstånd att ignorera batterioptimering."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"fråga alla paket"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Tillåter att en app ser alla installerade paket."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"åtkomst till SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Tillåter att en app får åtkomst till SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"få åtkomst till AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Tillåter att en app får åtkomst till AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"få åtkomst till AdServices Attribution API:er"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Tillåter att en app får åtkomst till AdServices Attribution API:er."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"få åtkomst till AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Tillåter att en app får åtkomst till AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Peka två gånger för zoomkontroll"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Det gick inte att lägga till widgeten."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Kör"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Byter till <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Loggar ut <xliff:g id="NAME">%1$s</xliff:g> …"</string>
<string name="owner_name" msgid="8713560351570795743">"Ägare"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Gäst"</string>
<string name="error_message_title" msgid="4082495589294631966">"Fel"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Administratören tillåter inte denna ändring"</string>
<string name="app_not_found" msgid="3429506115332341800">"Ingen app som kan hantera åtgärden hittades"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"AVINSTALLERA"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ÖPPNA ÄNDÅ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"En skadlig app har upptäckts"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Begäran om åtkomst till systemloggar"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vill du tillåta att <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> får åtkomst till alla enhetsloggar?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Bara den här gången"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Tillåt inte"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> begär systemloggar i syfte att felsöka funktioner. Dessa loggar kan innehålla information som har skrivits på enheten av appar och tjänster."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Enhetsloggar registrerar vad som händer på enheten. Appar kan använda dessa loggar för att hitta och åtgärda problem.\n\nVissa loggar kan innehålla känsliga uppgifter, så du ska bara tillåta att appar du litar på får åtkomst till alla enhetsloggar. \n\nOm du inte ger appen åtkomst till alla enhetsloggar har den ändå åtkomst till sina egna loggar, och enhetstillverkare kan fortfarande få åtkomst till vissa loggar eller viss information på enheten. Läs mer"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Visa inte igen"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> vill kunna visa bitar av <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Redigera"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> har körts i bakgrunden under lång tid. Tryck för att granska."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Kontrollera aktiva appar"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Det går inte att komma åt kameran från den här enheten"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 6351769..1d7f182 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Mtoa huduma wako ameizima kwa muda mfupi katika SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Imeshindwa kufikia mtandao wa simu"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Jaribu kutumia mtandao unaopendelea. Gusa ili ubadilishe."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Huduma ya kupiga simu za dharura haipatikani"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Huwezi kupiga simu ya dharura kupitia Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Huenda simu ya dharura isipatikane"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> haitumii simu ya dharura kupitia Wi-Fi Gusa ili upate maelezo."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Arifa"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Kupeleka simu kwenye nambari nyingine"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Hali ya kupiga simu za dharura"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Huruhusu programu kurekebisha rajisi ya kompyuta kibao yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha rajisi ya simu yako."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Huruhusu programu irekebishe kumbukumbu za simu ya kifaa chako cha Android TV, ikiwa ni pamoja na data kuhusu simu zinazoingia na simu unazopiga. Huenda programu hasidi zikatumia ruhusa hii ili kufuta au kurekebisha kumbukumbu zako za simu."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Huruhusu programu kurekebisha rajisi ya simu yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha rajisi ya simu yako."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"fikia vitambua shughuli za mwili (kama vifuatiliaji vya mapigo ya moyo)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Kufikia data katika vitambuzi vya shughuli za mwili kama vile mapigo ya moyo, halijoto, asilimia ya oksijeni kwenye damu n.k."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"kufikia vitambuzi vya shughuli za mwili (kama vile vifuatiliaji vya mapigo ya moyo) inapotumika chinichini"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Kufikia data katika vitambuzi vya shughuli za mwili kama vile mapigo ya moyo, halijoto, asilimia ya oksijeni kwenye damu n.k. inapotumika chinichini."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Fikia data ya vitambuzi shughuli za mwili, kama vile mapigo ya moyo, wakati programu inatumika"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Hurushusu programu ifikie data ya vitambuzi shughuli za mwili, kama vile mapigo ya moyo, halijoto na asilimia ya oksijeni kwenye damu wakati programu inatumika."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Fikia data ya vitambuzi shughuli za mwili, kama vile mapigo ya moyo, wakati programu inatumika chinichini"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Hurushusu programu ifikie data ya vitambuzi shughuli za mwili, kama vile mapigo ya moyo, halijoto na asilimia ya oksijeni kwenye damu wakati programu inatumika chinichini."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Soma matukio na maelezo ya kalenda"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Programu hii inaweza kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye kompyuta yako kibao na kushiriki au kuhifadhi data yako ya kalenda."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Programu hii inaweza kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye kifaa chako cha Android TV na kushiriki au kuhifadhi data ya kalenda yako."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Huruhusu programu kusoma faili za sauti kutoka kwenye hifadhi unayoshiriki."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"soma faili za video kutoka kwenye hifadhi ya kushiriki"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Huruhusu programu kusoma faili za video kutoka kwenye hifadhi unayoshiriki."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"soma faili za picha kutoka kwenye hifadhi ya kushiriki"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Huruhusu programu kusoma faili za picha kutoka kwenye hifadhi unayoshiriki."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"soma faili za picha kutoka kwenye hifadhi iliyoshirikiwa"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Huruhusu programu kusoma faili za picha kutoka kwenye hifadhi yako iliyoshirikiwa."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"irekebishe au ifute maudhui ya hifadhi unayoshiriki"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Huruhusu programu iandike maudhui ya hifadhi unayoshiriki."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"piga/pokea simu za SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Bonyeza Menyu ili kufungua au kupiga simu ya dharura."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Bonyeza Menyu ili kufungua."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Chora ruwaza ili kufungua"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Simu ya dharura"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Dharura"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Rudi kwa kupiga simu"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Sahihi!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Jaribu tena"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Katu"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Hauna idhini ya kufungua ukurasa huu."</string>
<string name="text_copied" msgid="2531420577879738860">"Maandishi yamenakiliwa kwenye ubao wa kunakili."</string>
- <string name="copied" msgid="4675902854553014676">"Umenakili"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> imebandika kutoka <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> imebandika kutoka ubao wako wa kunakili"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> imebandika maandishi uliyonakili"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Huruhusu programu kuomba ruhusa ya kupuuza uimarishaji wa betri katika programu yako."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"kutuma hoja kwa vifurushi vyote"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Huruhusu programu kuona vifurushi vyote vilivyosakinishwa."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"kufikia SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Huruhusu programu kufikia SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"fikia API za Mada za AdServices"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Inaruhusu programu kufikia API za Mada za AdServices."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"fikia API za Maelezo za AdServices"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Inaruhusu programu kufikia API za Maelezo za AdServices."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"fikia API za Hadhira Maalumu za AdServices."</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Inaruhusu programu kufikia API za Hadhira Maalumu za AdServices."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Gusa mara mbili kwa udhibiti wa kuza"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Haikuweza kuongeza wijeti."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Nenda"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Inaenda kwa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Inamwondoa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Mmiliki"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Mgeni"</string>
<string name="error_message_title" msgid="4082495589294631966">"Hitilafu"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Mabadiliko haya hayaruhusiwi na msimamizi wako"</string>
<string name="app_not_found" msgid="3429506115332341800">"Hakuna programu iliyopatikana ili kushughulikia kitendo hiki"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ONDOA"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"FUNGUA TU"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Imetambua programu hatari"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Ombi la ufikiaji wa kumbukumbu ya mfumo"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Ungependa kuruhusu <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ifikie kumbukumbu zote za kifaa?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Mara hii pekee"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Usiruhusu"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> huomba kumbukumbu za mfumo ili kutatua hitilafu za utendaji kazi. Kumbukumbu hizi zinaweza kuwa na maelezo ambayo programu na huduma ziliandika kwenye kifaa chako."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Kumbukumbu za kifaa hurekodi kinachofanyika kwenye kifaa chako. Programu zinaweza kutumia kumbukumbu hizi ili kutambua na kurekebisha hitilafu.\n\nBaadhi ya kumbukumbu huweza kuwa na taarifa nyeti, hivyo ruhusu tu programu unazoziamini kufikia kumbukumbu zote za kifaa. \n\nIwapo hutaruhusu programu hii ifikie kumbukumbu zote za kifaa, bado inaweza kufikia kumbukumbu zake yenyewe na mtengenezaji wa kifaa chako bado anaweza kufikia baadhi ya kumbukumbu au taarifa zilizopo kwenye kifaa chako. Pata maelezo zaidi"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Usionyeshe tena"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> inataka kuonyesha vipengee <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Badilisha"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> inatumika chinichini kwa muda mrefu. Gusa ili ukague."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Angalia programu zinazotumika"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Haiwezi kufikia kamera kwenye kifaa hiki"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 09a361e..f13d177 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"சிம் <xliff:g id="SIMNUMBER">%d</xliff:g>ஐ, உங்கள் மொபைல் நிறுவனம் தற்காலிகமாக ஆஃப் செய்துள்ளது"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"மொபைல் நெட்வொர்க் கிடைக்கவில்லை"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"விருப்ப நெட்வொர்க்கை மாற்றவும். மாற்ற, தட்டவும்."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"அவசர அழைப்பைச் செய்ய முடியாது"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"வைஃபை மூலம் அவசர அழைப்புகளைச் செய்ய முடியாது"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"அவசர அழைப்புகளை மேற்கொள்ள முடியாமல் போகலாம்"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> இல் வைஃபை மூலம் அவசர அழைப்புகளை மேற்கொள்ள முடியாது. விவரங்களைப் பார்க்க தட்டவும்."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"விழிப்பூட்டல்கள்"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"அழைப்பு திருப்பிவிடுதல்"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"அவசரகாலத் திரும்ப அழைக்கும் பயன்முறை"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் டேப்லெட்டின் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"உள்வரும், வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உட்பட உங்கள் Android TVயின் அழைப்புப் பதிவைத் திருத்த ஆப்ஸை அனுமதிக்கும். உங்கள் அழைப்புப் பதிவை அழிக்கவோ திருத்தவோ தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தக்கூடும்."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் மொபைல் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"உடல் உணர்விகளை (இதயத் துடிப்பு மானிட்டர்கள் போன்றவை) அணுகுதல்"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"இதயத் துடிப்பு, வெப்பநிலை, ரத்த ஆக்ஸிஜன் சதவீதம் போன்ற உடல் சென்சார்களில் இருந்து கிடைக்கும் தரவை அணுகலாம்."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"பின்னணியில் உடல் சென்சார்களை (இதயத் துடிப்பைக் கண்காணித்தல் போன்றவை) அணுகுதல்"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"பின்னணியில் இருக்கும்போது இதயத் துடிப்பு, வெப்பநிலை, ரத்த ஆக்ஸிஜன் சதவீதம் போன்ற உடல் சென்சார்களில் இருந்து கிடைக்கும் தரவை அணுகலாம்."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"பயன்பாட்டில் இருக்கும்போது இதயத் துடிப்பு போன்ற உடல் சென்சார் தரவை அணுகுதல்"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ஆப்ஸ் பயன்பாட்டில் இருக்கும்போது இதயத் துடிப்பு, வெப்பநிலை, ரத்த ஆக்ஸிஜன் சதவீதம் போன்ற உடல் சென்சார் தரவை அணுக ஆப்ஸை அனுமதிக்கிறது."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"பின்னணியில் இயங்கும்போது இதயத் துடிப்பு போன்ற உடல் சென்சார் தரவை அணுகுதல்"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ஆப்ஸ் பின்னணியில் இயங்கும்போது இதயத் துடிப்பு, வெப்பநிலை, ரத்த ஆக்ஸிஜன் சதவீதம் போன்ற உடல் சென்சார் தரவை அணுக ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"கேலெண்டர் நிகழ்வுகளையும் விவரங்களையும் படிக்கலாம்"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"இந்த ஆப்ஸ் உங்கள் டேப்லெட்டில் சேமிக்கப்பட்டுள்ள கேலெண்டர் நிகழ்வுகள் அனைத்தையும் படிக்கலாம், உங்கள் கேலெண்டர் தரவைப் பகிரலாம் அல்லது சேமிக்கலாம்."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"உங்கள் Android TVயில் சேமித்துள்ள அனைத்துக் கேலெண்டர் நிகழ்வுகளையும் இந்த ஆப்ஸால் தெரிந்துகொள்ள முடியும். அத்துடன் உங்களின் கேலெண்டர் தரவைப் பகிரவும் சேமிக்கவும் முடியும்."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"உங்கள் பகிர்ந்த சேமிப்பகத்திலுள்ள ஆடியோ ஃபைல்களைப் படிக்க ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"பகிர்ந்த சேமிப்பகத்திலுள்ள வீடியோ ஃபைல்களைப் படித்தல்"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"உங்கள் பகிர்ந்த சேமிப்பகத்திலுள்ள வீடியோ ஃபைல்களைப் படிக்க ஆப்ஸை அனுமதிக்கும்."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"பகிர்ந்த சேமிப்பகத்திலுள்ள பட ஃபைல்களைப் படித்தல்"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"உங்கள் பகிர்ந்த சேமிப்பகத்திலுள்ள பட ஃபைல்களைப் படிக்க ஆப்ஸை அனுமதிக்கும்."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"பகிர்ந்த சேமிப்பகத்திலுள்ள பட ஃபைல்களைப் படித்தல்"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"உங்கள் பகிர்ந்த சேமிப்பகத்திலுள்ள பட ஃபைல்களைப் படிக்க ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"பகிர்ந்த சேமிப்பகத்தின் உள்ளடக்கங்களை மாற்றும் அல்லது நீக்கும்"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"பகிர்ந்த சேமிப்பகத்தின் உள்ளடக்கத்தில் மாற்றங்களைச் செய்ய அனுமதிக்கும்."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP அழைப்புகளைச் செய்தல்/பெறுதல்"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"அன்லாக் செய்ய மெனுவை அழுத்தவும் அல்லது அவசர அழைப்பை மேற்கொள்ளவும்."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"அன்லாக் செய்ய, மெனுவை அழுத்தவும்."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"அன்லாக் செய்ய, வடிவத்தை வரையவும்"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"அவசர அழைப்பு"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"அவசர அழைப்பு"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"அழைப்பிற்குத் திரும்பு"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"சரி!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"மீண்டும் முயற்சிக்கவும்"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"ஒருபோதும் வேண்டாம்"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"இந்தப் பக்கத்தைத் திறக்க, உங்களிடம் அனுமதி இல்லை."</string>
<string name="text_copied" msgid="2531420577879738860">"உரை கிளிப்போர்டிற்கு நகலெடுக்கப்பட்டது."</string>
- <string name="copied" msgid="4675902854553014676">"நகலெடுக்கப்பட்டது"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ஆப்ஸிலிருந்து <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ஒட்டப்பட்டது"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"கிளிப்போர்டில் இருந்து <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ஒட்டப்பட்டது"</string>
<string name="pasted_text" msgid="4298871641549173733">"நீங்கள் நகலெடுத்த உரையை <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ஆப்ஸ் ஒட்டியது"</string>
@@ -1262,8 +1261,8 @@
<string name="dump_heap_notification_detail" msgid="8431586843001054050">"ஹீப் டம்ப் சேகரிக்கப்பட்டது. பகிர, தட்டவும்."</string>
<string name="dump_heap_title" msgid="4367128917229233901">"ஹீப் டம்பைப் பகிரவா?"</string>
<string name="dump_heap_text" msgid="1692649033835719336">"தனது நினைவக வரம்பான <xliff:g id="SIZE">%2$s</xliff:g> அளவை <xliff:g id="PROC">%1$s</xliff:g> செயலாக்கம் மீறியுள்ளது. உங்களுக்கான ஹீப் டம்ப்பினை அதன் டெவெலப்பருடன் பகிரலாம். கவனத்திற்கு: ஆப்ஸ் அணுகக்கூடிய ஏதேனும் தனிப்பட்ட தகவல் இந்த ஹீப் டம்ப்பில் இருக்கக்கூடும்."</string>
- <string name="dump_heap_system_text" msgid="6805155514925350849">"<xliff:g id="SIZE">%2$s</xliff:g> அளவான தனது நினைவக வரம்பை <xliff:g id="PROC">%1$s</xliff:g> செயலாக்கம் மீறியுள்ளது. உங்களுக்கான ஹீப் டம்ப் பகிர்வதற்குக் கிடைக்கிறது. கவனத்திற்கு: நீங்கள் உள்ளிட்டவை உட்பட செயலாக்கத்திற்கு அணுகலுள்ள தனிப்பட்ட தகவல்கள் இந்த ஹீப் டம்பில் இருக்கக்கூடும்"</string>
- <string name="dump_heap_ready_text" msgid="5849618132123045516">"<xliff:g id="PROC">%1$s</xliff:g> செயலாக்கத்திற்கான ஹீப் டம்ப் நீங்கள் பகிர்வதற்குக் கிடைக்கிறது. கவனத்திற்கு: நீங்கள் உள்ளிட்டவை உட்பட செயலாக்கத்திற்கு அணுகலுள்ள தனிப்பட்ட தகவல்கள் இந்த ஹீப் டம்பில் இருக்கக்கூடும்."</string>
+ <string name="dump_heap_system_text" msgid="6805155514925350849">"<xliff:g id="SIZE">%2$s</xliff:g> அளவான தனது நினைவக வரம்பை <xliff:g id="PROC">%1$s</xliff:g> செயலாக்கம் மீறியுள்ளது. உங்களுக்கான ஹீப் டம்ப் பகிர்வதற்குக் கிடைக்கிறது. கவனத்திற்கு: நீங்கள் டைப் செய்தவை உட்பட செயலாக்கத்திற்கு அணுகலுள்ள தனிப்பட்ட பாதுகாக்கப்பட வேண்டிய தகவல்கள் இந்த ஹீப் டம்பில் இருக்கக்கூடும்"</string>
+ <string name="dump_heap_ready_text" msgid="5849618132123045516">"<xliff:g id="PROC">%1$s</xliff:g> செயலாக்கத்திற்கான ஹீப் டம்ப் நீங்கள் பகிர்வதற்குக் கிடைக்கிறது. கவனத்திற்கு: நீங்கள் டைப் செய்தவை உட்பட செயலாக்கத்திற்கு அணுகலுள்ள தனிப்பட்ட பாதுகாக்கப்பட வேண்டிய தகவல்கள் இந்த ஹீப் டம்பில் இருக்கக்கூடும்."</string>
<string name="sendText" msgid="493003724401350724">"உரைக்கான செயலைத் தேர்வுசெய்யவும்"</string>
<string name="volume_ringtone" msgid="134784084629229029">"ரிங்கரின் ஒலியளவு"</string>
<string name="volume_music" msgid="7727274216734955095">"மீடியாவின் ஒலியளவு"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"பயன்பாட்டிற்கான பேட்டரி மேம்படுத்தல்களைப் புறக்கணிப்பதற்கான அனுமதியைக் கோர, ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"அனைத்துப் பேக்கேஜ்களையும் பார்க்க அனுமதித்தல்"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"நிறுவப்பட்டுள்ள அனைத்துப் பேக்கேஜ்களையும் பார்ப்பதற்கு ஆப்ஸை அனுமதிக்கும்."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApiகளை அணுகுதல்"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"SupplementalApiகளை அணுக ஆப்ஸை அனுமதிக்கும்."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics APIயை அணுகுதல்"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"AdServices Topics APIயை அணுக ஆப்ஸை அனுமதிக்கும்."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution APIகளை அணுகுதல்"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"AdServices Attribution APIகளை அணுக ஆப்ஸை அனுமதிக்கும்."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences APIயை அணுகுதல்"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"AdServices Custom Audiences APIயை அணுக ஆப்ஸை அனுமதிக்கும்."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"அளவை மாற்றுவதற்கான கட்டுப்பாட்டிற்கு, இருமுறை தட்டவும்"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"விட்ஜெட்டைச் சேர்க்க முடியவில்லை."</string>
<string name="ime_action_go" msgid="5536744546326495436">"செல்"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>க்கு மாறுகிறது…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> வெளியேறுகிறார்…"</string>
<string name="owner_name" msgid="8713560351570795743">"உரிமையாளர்"</string>
+ <string name="guest_name" msgid="8502103277839834324">"விருந்தினர்"</string>
<string name="error_message_title" msgid="4082495589294631966">"பிழை"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"உங்கள் நிர்வாகி இந்த மாற்றத்தை அனுமதிக்கவில்லை"</string>
<string name="app_not_found" msgid="3429506115332341800">"இந்தச் செயலைச் செய்ய ஆப்ஸ் எதுவுமில்லை"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"நிறுவல் நீக்கு"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"பரவாயில்லை, திற"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"தீங்கிழைக்கும் ஆப்ஸ் உள்ளது"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"சிஸ்டம் பதிவை அணுகுவதற்கான கோரிக்கை"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"சாதனப் பதிவுகள் அனைத்தையும் <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> அணுக அனுமதிக்கவா?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"இப்போது மட்டும்"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"அனுமதிக்க வேண்டாம்"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"பிழைதிருத்தச் செயல்பாட்டிற்கான சிஸ்டம் பதிவுகளை <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ஆப்ஸ் கோருகிறது. இந்தப் பதிவுகள் உங்கள் சாதனத்தில் ஆப்ஸ் மற்றும் சேவைகளில் உள்ள எழுத்துப்பூர்வமான தகவல்களைக் கொண்டிருக்கக்கூடும்."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"உங்கள் சாதனத்தில் நடப்பவற்றைச் சாதனப் பதிவுகள் ரெக்கார்டு செய்யும். சிக்கல்களைக் கண்டறிந்து சரிசெய்ய ஆப்ஸ் இந்தப் பதிவுகளைப் பயன்படுத்தலாம்.\n\nபாதுகாக்கப்பட வேண்டிய தகவல்கள் சில பதிவுகளில் இருக்கக்கூடும் என்பதால் சாதனப் பதிவுகள் அனைத்தையும் அணுக நீங்கள் நம்பும் ஆப்ஸை மட்டுமே அனுமதிக்கவும். \n\nசாதனப் பதிவுகள் அனைத்தையும் அணுக இந்த ஆப்ஸை நீங்கள் அனுமதிக்கவில்லை என்றாலும் அதற்குச் சொந்தமான பதிவுகளைத் தொடர்ந்து அதனால் அணுக முடியும். மேலும் உங்கள் சாதன உற்பத்தியாளர் உங்கள் சாதனத்திலுள்ள சில பதிவுகளையோ தகவல்களையோ தொடர்ந்து அணுகக்கூடும். மேலும் அறிக"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"மீண்டும் காட்டாதே"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_2">%2$s</xliff:g> ஆப்ஸின் விழிப்பூட்டல்களைக் காண்பிக்க, <xliff:g id="APP_0">%1$s</xliff:g> அனுமதி கேட்கிறது"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"திருத்து"</string>
@@ -2060,7 +2064,7 @@
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 பதிப்பில் \'Android சூழலுக்கேற்ற அறிவிப்புகள்\' அம்சத்திற்குப் பதிலாக \'மேம்பட்ட அறிவிப்புகள்\' மாற்றப்பட்டுள்ளது. இந்த அம்சம், பரிந்துரைக்கப்படும் செயல்களையும் பதில்களையும் காட்டுவதுடன் உங்கள் அறிவிப்புகளையும் ஒழுங்கமைக்கும்.\n\nதொடர்புகளின் பெயர்கள், மெசேஜ்கள் போன்ற தனிப்பட்ட தகவல்கள் உட்பட அனைத்து அறிவிப்பு உள்ளடக்கத்தையும் \'மேம்பட்ட அறிவிப்புகள்\' அணுக முடியும். மேலும் இந்த அம்சத்தால் அறிவிப்புகளை நிராகரிக்கவும் அவற்றுக்குப் பதிலளிக்கவும் முடியும் (அழைப்புகளுக்குப் பதிலளிப்பது, \'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தைக் கட்டுப்படுத்துவது போன்றவை)."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"வழக்கமான பேட்டரி சேமிப்பானுக்கான விவர அறிவிப்பு"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"வழக்கமாகச் சார்ஜ் செய்வதற்கு முன்பே பேட்டரி தீர்ந்துபோகக்கூடும்"</string>
- <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"பேட்டரி நிலையை நீட்டிக்க பேட்டரி சேமிப்பான் இயக்கப்பட்டுள்ளது"</string>
+ <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"பேட்டரி ஆயுளை நீட்டிக்க பேட்டரி சேமிப்பான் இயக்கப்பட்டுள்ளது"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"பேட்டரி சேமிப்பு"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"பேட்டரி சேமிப்பான் ஆஃப் செய்யப்பட்டுள்ளது"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"மொபைலில் போதுமான சார்ஜ் உள்ளது. அம்சங்கள் இனி தடையின்றி இயங்கும்."</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ஆப்ஸ் நீண்ட நேரமாகப் பின்னணியில் இயங்குகிறது. பார்க்க தட்டவும்."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"செயலிலுள்ள ஆப்ஸைப் பாருங்கள்"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"இந்தச் சாதனத்திலிருந்து கேமராவை அணுக முடியவில்லை"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 21290e9..30209b1 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> కోసం మీ క్యారియర్ తాత్కాలికంగా ఆఫ్ చేశారు"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"మొబైల్ నెట్వర్క్ అందుబాటులో లేదు"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ప్రాధాన్య నెట్వర్క్ను మార్చుకోవడానికి ప్రయత్నించండి. మార్చడానికి నొక్కండి."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"అత్యవసర కాలింగ్ అందుబాటులో లేదు"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi-Fiతో అత్యవసర కాల్స్ చేయలేరు"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"అత్యవసర కాల్లు అందుబాటులో ఉండకపోవచ్చు"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"Wi-Fi ద్వారా ఎమర్జెన్సీ కాల్స్కు <xliff:g id="SPN">%s</xliff:g> సపోర్ట్ చేయదు. వివరాల కోసం ట్యాప్ చేయండి."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"అలర్ట్లు"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"కాల్ ఫార్వార్డింగ్"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"అత్యవసర కాల్బ్యాక్ మోడ్"</string>
@@ -96,10 +96,10 @@
<string name="notification_channel_wfc" msgid="9048240466765169038">"Wi-Fi కాలింగ్"</string>
<string name="notification_channel_sim" msgid="5098802350325677490">"SIM స్టేటస్"</string>
<string name="notification_channel_sim_high_prio" msgid="642361929452850928">"అధిక ప్రాధాన్యత గల SIM స్టేటస్"</string>
- <string name="peerTtyModeFull" msgid="337553730440832160">"అవతలి వారు FULL TTY మోడ్ని అభ్యర్థించారు"</string>
- <string name="peerTtyModeHco" msgid="5626377160840915617">"అవతలి వారు HCO TTY మోడ్ని అభ్యర్థించారు"</string>
- <string name="peerTtyModeVco" msgid="572208600818270944">"అవతలి వారు VCO TTY మోడ్ని అభ్యర్థించారు"</string>
- <string name="peerTtyModeOff" msgid="2420380956369226583">"అవతలి వారు OFF TTY మోడ్ని అభ్యర్థించారు"</string>
+ <string name="peerTtyModeFull" msgid="337553730440832160">"అవతలి వారు FULL TTY మోడ్ని రిక్వెస్ట్ చేశారు"</string>
+ <string name="peerTtyModeHco" msgid="5626377160840915617">"అవతలి వారు HCO TTY మోడ్ని రిక్వెస్ట్ చేశారు"</string>
+ <string name="peerTtyModeVco" msgid="572208600818270944">"అవతలి వారు VCO TTY మోడ్ని రిక్వెస్ట్ చేశారు"</string>
+ <string name="peerTtyModeOff" msgid="2420380956369226583">"అవతలి వారు OFF TTY మోడ్ని రిక్వెస్ట్ చేశారు"</string>
<string name="serviceClassVoice" msgid="2065556932043454987">"వాయిస్"</string>
<string name="serviceClassData" msgid="4148080018967300248">"డేటా"</string>
<string name="serviceClassFAX" msgid="2561653371698904118">"ఫ్యాక్స్"</string>
@@ -170,7 +170,7 @@
<string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"సురక్షిత కనెక్షన్ను వ్యవస్థాపించడం సాధ్యపడలేదు."</string>
<string name="httpErrorBadUrl" msgid="754447723314832538">"URL చెల్లనిది అయినందువలన పేజీని తెరవడం సాధ్యపడలేదు."</string>
<string name="httpErrorFile" msgid="3400658466057744084">"ఫైల్ను యాక్సెస్ చేయడం సాధ్యపడలేదు."</string>
- <string name="httpErrorFileNotFound" msgid="5191433324871147386">"అభ్యర్థించిన ఫైల్ను కనుగొనడం సాధ్యపడలేదు."</string>
+ <string name="httpErrorFileNotFound" msgid="5191433324871147386">"రిక్వెస్ట్ చేసిన ఫైల్ను కనుగొనడం సాధ్యపడలేదు."</string>
<string name="httpErrorTooManyRequests" msgid="2149677715552037198">"చాలా ఎక్కువ రిక్వెస్ట్లు ప్రాసెస్ చేయబడుతున్నాయి. తర్వాత మళ్లీ ప్రయత్నించండి."</string>
<string name="notification_title" msgid="5783748077084481121">"<xliff:g id="ACCOUNT">%1$s</xliff:g>కు సైన్ఇన్ ఎర్రర్"</string>
<string name="contentServiceSync" msgid="2341041749565687871">"సింక్"</string>
@@ -249,7 +249,7 @@
<string name="global_action_logout" msgid="6093581310002476511">"సెషన్ను ముగించు"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"స్క్రీన్షాట్"</string>
<string name="bugreport_title" msgid="8549990811777373050">"బగ్ రిపోర్ట్"</string>
- <string name="bugreport_message" msgid="5212529146119624326">"ఇది ఇ-మెయిల్ మెసేజ్ రూపంలో పంపడానికి మీ ప్రస్తుత పరికర స్థితి గురించి సమాచారాన్ని సేకరిస్తుంది. బగ్ రిపోర్ట్ను ప్రారంభించడం మొదలుకొని పంపడానికి సిద్ధం చేసే వరకు ఇందుకు కొంత సమయం పడుతుంది; దయచేసి ఓపిక పట్టండి."</string>
+ <string name="bugreport_message" msgid="5212529146119624326">"ఇది ఈమెయిల్ మెసేజ్ రూపంలో పంపడానికి మీ ప్రస్తుత పరికర స్థితి గురించి సమాచారాన్ని సేకరిస్తుంది. బగ్ రిపోర్ట్ను ప్రారంభించడం మొదలుకొని పంపడానికి సిద్ధం చేసే వరకు ఇందుకు కొంత సమయం పడుతుంది; దయచేసి ఓపిక పట్టండి."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ప్రభావశీల రిపోర్ట్"</string>
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"చాలా సందర్భాల్లో దీన్ని ఉపయోగించండి. ఇది రిపోర్ట్ ప్రోగ్రెస్ను ట్రాక్ చేయడానికి, సమస్య గురించి మరిన్ని వివరాలను నమోదు చేయడానికి మరియు స్క్రీన్షాట్లు తీయడానికి మిమ్మల్ని అనుమతిస్తుంది. ఇది నివేదించడానికి ఎక్కువ సమయం పట్టే తక్కువ వినియోగ విభాగాలను విడిచిపెట్టవచ్చు."</string>
<string name="bugreport_option_full_title" msgid="7681035745950045690">"పూర్తి రిపోర్ట్"</string>
@@ -412,9 +412,9 @@
<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="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="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"టాబ్లెట్లో నిల్వ చేసిన మీ కాంటాక్ట్లకు సంబంధించిన డేటాను చదవడానికి యాప్ను అనుమతిస్తుంది. కాంటాక్ట్లను క్రియేట్ చేసిన మీ టాబ్లెట్లోని ఖాతాలకు కూడా యాప్లకు యాక్సెస్ ఉంటుంది. ఇందులో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా క్రియేట్ చేయబడిన ఖాతాలు ఉండవచ్చు. ఈ అనుమతి, మీ కాంటాక్ట్ డేటాను సేవ్ చేయడానికి యాప్లను అనుమతిస్తుంది, హానికరమైన యాప్లు మీకు తెలియకుండానే కాంటాక్ట్ డేటాను షేర్ చేయవచ్చు."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"మీ Android TV పరికరంలో నిల్వ చేసిన కాంటాక్ట్లకు సంబంధించిన డేటాను చదవడానికి యాప్ను అనుమతిస్తుంది. కాంటాక్ట్లను క్రియేట్ చేసిన మీ Android TV పరికరంలోని ఖాతాలకు కూడా యాప్లకు యాక్సెస్ ఉంటుంది. ఇందులో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా క్రియేట్ చేయబడిన ఖాతాలు ఉండవచ్చు. ఈ అనుమతి, మీ కాంటాక్ట్ డేటాను సేవ్ చేయడానికి యాప్లను అనుమతిస్తుంది, హానికరమైన యాప్లు మీకు తెలియకుండానే కాంటాక్ట్ డేటాను షేర్ చేయవచ్చు."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"ఫోన్లో నిల్వ చేసిన మీ కాంటాక్ట్లకు సంబంధించిన డేటాను చదవడానికి యాప్ను అనుమతిస్తుంది. కాంటాక్ట్లను క్రియేట్ చేసిన మీ ఫోన్లోని ఖాతాలను కూడా యాప్లు యాక్సెస్ చేయగలవు. ఇందులో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా క్రియేట్ చేయబడిన ఖాతాలు ఉండవచ్చు. ఈ అనుమతి, మీ కాంటాక్ట్ డేటాను సేవ్ చేయడానికి యాప్లను అనుమతిస్తుంది, హానికరమైన యాప్లు మీకు తెలియకుండానే కాంటాక్ట్ డేటాను షేర్ చేయవచ్చు."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"మీ కాంటాక్ట్లను సవరించడం"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"మీ టాబ్లెట్లో నిల్వ చేసి ఉన్న కాంటాక్ట్లకు సంబంధించిన డేటాను ఎడిట్ చేయడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి, కాంటాక్ట్ డేటాను తొలగించడానికి యాప్లను అనుమతిస్తుంది."</string>
<string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"మీ Android TV పరికరంలో నిల్వ చేసి ఉన్న కాంటాక్ట్లకు సంబంధించిన డేటాను ఎడిట్ చేయడానికి యాప్ను అనుమతిస్తుంది. ఈ అనుమతి, కాంటాక్ట్ డేటాను తొలగించడానికి యాప్లను అనుమతిస్తుంది."</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ఇన్కమింగ్ మరియు అవుట్గోయింగ్ కాల్స్ల గురించిన డేటాతో సహా మీ టాబ్లెట్ యొక్క కాల్ లాగ్ను ఎడిట్ చేయడానికి యాప్ను అనుమతిస్తుంది. హానికరమైన యాప్లు మీ కాల్ లాగ్ను ఎరేజ్ చేయడానికి లేదా ఎడిట్ చేయడానికి దీన్ని ఉపయోగించవచ్చు."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ఇన్కమింగ్ మరియు అవుట్గోయింగ్ కాల్స్కు సంబంధించిన డేటాతో సహా మీ Android TV పరికరం కాల్ లాగ్ను ఎడిట్ చేయడానికి యాప్ని అనుమతిస్తుంది. హానికరమైన యాప్లు మీ కాల్ లాగ్ను తీసివేయడానికి లేదా ఎడిట్ చేయడానికి దీన్ని ఉపయోగించవచ్చు."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ఇన్కమింగ్ మరియు అవుట్గోయింగ్ కాల్స్ల గురించిన డేటాతో సహా మీ ఫోన్ యొక్క కాల్ లాగ్ను ఎడిట్ చేయడానికి యాప్ను అనుమతిస్తుంది. హానికరమైన యాప్లు మీ కాల్ లాగ్ను ఎరేజ్ చేయడానికి లేదా ఎడిట్ చేయడానికి దీన్ని ఉపయోగించవచ్చు."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"శరీర సెన్సార్లను (గుండె స్పందన రేటు మానిటర్ల వంటివి) యాక్సెస్ చేయండి"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"గుండె స్పందన రేటు, ఉష్ణోగ్రత, రక్తంలో ఆక్సిజన్ శాతం మొదలైన శరీర సెన్సార్ల నుండి డేటాను యాక్సెస్ చేయండి."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"బ్యాక్గ్రౌండ్లో శరీర సెన్సార్లను (గుండె రేటు మానిటర్స్) యాక్సెస్ చేయండి"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"బ్యాక్గ్రౌండ్లో ఉన్నప్పుడు గుండె స్పందన రేటు, ఉష్ణోగ్రత, రక్తంలో ఆక్సిజన్ శాతం మొదలైన శరీర సెన్సార్ల నుండి డేటాకు యాక్సెస్ చేయండి."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ఉపయోగంలో ఉన్నప్పుడు గుండె స్పందన రేటు వంటి శరీర సెన్సార్ డేటాను యాక్సెస్ చేయండి"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"యాప్ ఉపయోగంలో ఉన్నప్పుడు గుండె స్పందన రేటు, ఉష్ణోగ్రత, ఇంకా రక్తంలోని ఆక్సిజన్ శాతం వంటి శరీర సెన్సార్ డేటాను యాక్సెస్ చేయడానికి యాప్ను అనుమతిస్తుంది."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"బ్యాక్గ్రౌండ్లో గుండె స్పందన రేటు వంటి శరీర సెన్సార్ డేటాను యాక్సెస్ చేయండి"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"యాప్ బ్యాక్గ్రౌండ్లో ఉన్నప్పుడు గుండె స్పందన రేటు, ఉష్ణోగ్రత, ఇంకా రక్తంలోని ఆక్సిజన్ శాతం వంటి శరీర సెన్సార్ డేటాను యాక్సెస్ చేయడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"క్యాలెండర్ ఈవెంట్లు మరియు వివరాలను చదవడం"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ఈ యాప్ మీ టాబ్లెట్లో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్లన్నీ చదవగలదు మరియు మీ క్యాలెండర్ డేటాను షేర్ చేయగలదు లేదా సేవ్ చేయగలదు."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ఈ యాప్ మీ Android TV పరికరంలో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్లన్నీ చదవగలదు, మీ క్యాలెండర్ డేటాను షేర్ చేయగలదు లేదా సేవ్ చేయగలదు."</string>
@@ -505,13 +505,13 @@
<string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"మీ Android TV పరికరం సమయ మండలిని మార్చడానికి యాప్ని అనుమతిస్తుంది."</string>
<string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"ఫోన్ యొక్క సమయ మండలిని మార్చడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_getAccounts" msgid="5304317160463582791">"పరికరంలో ఖాతాలను కనుగొనడం"</string>
- <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"టాబ్లెట్కు తెలిసిన ఖాతాల లిస్ట్ను పొందడానికి యాప్ను అనుమతిస్తుంది. దీనిలో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా సృష్టించబడిన ఖాతాలు ఏవైనా ఉండవచ్చు."</string>
- <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"మీ Android TV పరికరానికి తెలిసిన ఖాతాల లిస్ట్ను పొందడానికి యాప్ను అనుమతిస్తుంది. దీనిలో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా సృష్టించబడిన ఖాతాలు ఏవైనా ఉండవచ్చు."</string>
- <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"ఫోన్కు తెలిసిన ఖాతాల లిస్ట్ను పొందడానికి యాప్ను అనుమతిస్తుంది. దీనిలో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా సృష్టించబడిన ఖాతాలు ఏవైనా ఉండవచ్చు."</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"టాబ్లెట్కు తెలిసిన ఖాతాల లిస్ట్ను పొందడానికి యాప్ను అనుమతిస్తుంది. దీనిలో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా క్రియేట్ చేయబడిన ఖాతాలు ఏవైనా ఉండవచ్చు."</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"మీ Android TV పరికరానికి తెలిసిన ఖాతాల లిస్ట్ను పొందడానికి యాప్ను అనుమతిస్తుంది. దీనిలో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా క్రియేట్ చేయబడిన ఖాతాలు ఏవైనా ఉండవచ్చు."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"ఫోన్కు తెలిసిన ఖాతాల లిస్ట్ను పొందడానికి యాప్ను అనుమతిస్తుంది. దీనిలో మీరు ఇన్స్టాల్ చేసిన యాప్ల ద్వారా క్రియేట్ చేయబడిన ఖాతాలు ఏవైనా ఉండవచ్చు."</string>
<string name="permlab_accessNetworkState" msgid="2349126720783633918">"నెట్వర్క్ కనెక్షన్లను వీక్షించడం"</string>
<string name="permdesc_accessNetworkState" msgid="4394564702881662849">"ఏ నెట్వర్క్లు ఉన్నాయి మరియు కనెక్ట్ చేయబడ్డాయి వంటి నెట్వర్క్ కనెక్షన్ల గురించి సమాచారాన్ని వీక్షించడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_createNetworkSockets" msgid="3224420491603590541">"నెట్వర్క్ను పూర్తిగా యాక్సెస్ చేయగలగడం"</string>
- <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"నెట్వర్క్ సాకెట్లను సృష్టించడానికి మరియు అనుకూల నెట్వర్క్ ప్రోటోకాల్లను ఉపయోగించడానికి యాప్ను అనుమతిస్తుంది. బ్రౌజర్ మరియు ఇతర యాప్లు ఇంటర్నెట్కు డేటా పంపడానికి మార్గాలను అందిస్తాయి, కనుక ఇంటర్నెట్కు డేటా పంపడానికి ఈ అనుమతి అవసరం లేదు."</string>
+ <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"నెట్వర్క్ సాకెట్లను క్రియేట్ చేయడానికి మరియు అనుకూల నెట్వర్క్ ప్రోటోకాల్లను ఉపయోగించడానికి యాప్ను అనుమతిస్తుంది. బ్రౌజర్ మరియు ఇతర యాప్లు ఇంటర్నెట్కు డేటా పంపడానికి మార్గాలను అందిస్తాయి, కనుక ఇంటర్నెట్కు డేటా పంపడానికి ఈ అనుమతి అవసరం లేదు."</string>
<string name="permlab_changeNetworkState" msgid="8945711637530425586">"నెట్వర్క్ కనెక్టివిటీని మార్చడం"</string>
<string name="permdesc_changeNetworkState" msgid="649341947816898736">"నెట్వర్క్ కనెక్టివిటీ యొక్క స్థితిని మార్చడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_changeTetherState" msgid="9079611809931863861">"టీథర్ చేయబడిన కనెక్టివిటీని మార్చడం"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"మీ షేర్ చేయబడిన స్టోరేజ్ నుండి ఆడియో ఫైల్లను చదవడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"షేర్ చేయబడిన స్టోరేజ్ నుండి వీడియో ఫైల్లను చదవండి"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"మీ షేర్ చేయబడిన స్టోరేజ్ నుండి వీడియో ఫైల్లను చదవడానికి యాప్ను అనుమతిస్తుంది."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"షేర్ చేయబడిన స్టోరేజ్ నుండి ఇమేజ్ ఫైల్లను చదవండి"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"మీ షేర్ చేయబడిన స్టోరేజ్ నుండి ఇమేజ్ ఫైల్లను చదవడానికి యాప్ను అనుమతిస్తుంది."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"షేర్ చేయబడిన స్టోరేజ్ నుండి ఇమేజ్ ఫైల్లను చదవండి"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"మీ షేర్ చేయబడిన స్టోరేజ్ నుండి ఇమేజ్ ఫైల్లను చదవడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"మీ షేర్ చేసిన నిల్వ యొక్క కంటెంట్లను ఎడిట్ చేయండి లేదా తొలగించండి"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"మీ షేర్ చేసిన నిల్వ యొక్క కంటెంట్లను రాయడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP కాల్స్ను చేయడానికి/స్వీకరించడానికి"</string>
@@ -721,8 +721,8 @@
<string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"షరతు ప్రదాత సేవ యొక్క అగ్ర-స్థాయి ఇంటర్ఫేస్కు అనుబంధించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ యాప్లకు ఎప్పటికీ అవసరం ఉండదు."</string>
<string name="permlab_bindDreamService" msgid="4776175992848982706">"డ్రీమ్ సేవకి అనుబంధించడం"</string>
<string name="permdesc_bindDreamService" msgid="9129615743300572973">"డ్రీమ్ సేవ యొక్క అగ్ర-స్థాయి ఇంటర్ఫేస్కు అనుబంధించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ యాప్లకు ఎప్పటికీ అవసరం ఉండదు."</string>
- <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"క్యారియర్ అందించిన కాన్ఫిగరేషన్ యాప్ను అభ్యర్థించడం"</string>
- <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"క్యారియర్ అందించిన కాన్ఫిగరేషన్ యాప్ను అభ్యర్థించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ యాప్ల కోసం ఎప్పటికీ అవసరం ఉండకూడదు."</string>
+ <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"క్యారియర్ అందించిన కాన్ఫిగరేషన్ యాప్ను రిక్వెస్ట్ చేయడం"</string>
+ <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"క్యారియర్ అందించిన కాన్ఫిగరేషన్ యాప్ను రిక్వెస్ట్ చేయడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ యాప్ల కోసం ఎప్పటికీ అవసరం ఉండకూడదు."</string>
<string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"నెట్వర్క్ పరిస్థితులపై పరిశీలనల గురించి తెలుసుకోవడం"</string>
<string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"నెట్వర్క్ పరిస్థితులపై పరిశీలనల గురించి తెలుసుకోవడానికి యాప్ను అనుమతిస్తుంది. సాధారణ యాప్లకు ఎప్పటికీ అవసరం ఉండకూడదు."</string>
<string name="permlab_setInputCalibration" msgid="932069700285223434">"ఇన్పుట్ పరికరం క్రమాంకనాన్ని మార్చండి"</string>
@@ -777,7 +777,7 @@
<string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"విధానాన్ని ప్రారంభించినప్పుడు ఉపయోగించడానికి పరికర గ్లోబల్ ప్రాక్సీని సెట్ చేస్తుంది. పరికర యజమాని మాత్రమే గ్లోబల్ ప్రాక్సీని సెట్ చేయగలరు."</string>
<string name="policylab_expirePassword" msgid="6015404400532459169">"స్క్రీన్ లాక్ పాస్వర్డ్ గడువు ముగింపుని సెట్ చేయండి"</string>
<string name="policydesc_expirePassword" msgid="9136524319325960675">"స్క్రీన్ లాక్ పాస్వర్డ్, పిన్ లేదా నమూనాని తప్పనిసరిగా ఎంత తరచుగా మార్చాలనే దాన్ని మారుస్తుంది."</string>
- <string name="policylab_encryptedStorage" msgid="9012936958126670110">"నిల్వ గుప్తీకరణను సెట్ చేయండి"</string>
+ <string name="policylab_encryptedStorage" msgid="9012936958126670110">"నిల్వ ఎన్క్రిప్షన్ను సెట్ చేయండి"</string>
<string name="policydesc_encryptedStorage" msgid="1102516950740375617">"నిల్వ చేయబడిన యాప్ డేటా గుప్తీకరించబడి ఉండటం అవసరం."</string>
<string name="policylab_disableCamera" msgid="5749486347810162018">"కెమెరాలను నిలిపివేయండి"</string>
<string name="policydesc_disableCamera" msgid="3204405908799676104">"అన్ని పరికర కెమెరాల వినియోగాన్ని నిరోధించండి."</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"అన్లాక్ చేయడానికి లేదా అత్యవసర కాల్ చేయడానికి మెనూ నొక్కండి."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"అన్లాక్ చేయడానికి మెనూ నొక్కండి."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"అన్లాక్ చేయడానికి నమూనాను గీయండి"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"ఎమర్జెన్సీ కాల్"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"అత్యవసరం"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"కాల్కు తిరిగి వెళ్లు"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"సరైనది!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"మళ్లీ ప్రయత్నించండి"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"ఎప్పుడూ వద్దు"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"ఈ పేజీని తెరవడానికి మీకు అనుమతి లేదు."</string>
<string name="text_copied" msgid="2531420577879738860">"వచనం క్లిప్బోర్డ్కు కాపీ చేయబడింది."</string>
- <string name="copied" msgid="4675902854553014676">"కాపీ చేయబడింది"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> నుండి పేస్ట్ చేయబడింది"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"మీ క్లిప్బోర్డ్ నుండి <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> పేస్ట్ చేయబడింది"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> మీరు కాపీ చేసిన టెక్స్ట్ను పేస్ట్ చేసింది"</string>
@@ -1444,16 +1443,20 @@
<string name="permdesc_route_media_output" msgid="1759683269387729675">"మీడియా అవుట్పుట్ను ఇతర బాహ్య పరికరాలకు మళ్లించడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_readInstallSessions" msgid="7279049337895583621">"ఇన్స్టాల్ సెషన్లను చదవడం"</string>
<string name="permdesc_readInstallSessions" msgid="4012608316610763473">"ఇన్స్టాల్ సెషన్లను చదవడానికి యాప్ను అనుమతిస్తుంది. ఇది సక్రియ ప్యాకేజీ ఇన్స్టాలేషన్ల గురించి వివరాలను చూడటానికి యాప్ను అనుమతిస్తుంది."</string>
- <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"ఇన్స్టాల్ ప్యాకేజీలను అభ్యర్థించడం"</string>
- <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"ప్యాకేజీల ఇన్స్టాలేషన్ అభ్యర్థించడానికి యాప్ను అనుమతిస్తుంది."</string>
+ <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"ఇన్స్టాల్ ప్యాకేజీలను రిక్వెస్ట్ చేయడం"</string>
+ <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"ప్యాకేజీల ఇన్స్టాలేషన్ రిక్వెస్ట్ చేయడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_requestDeletePackages" msgid="2541172829260106795">"ప్యాకేజీలను తొలగించడానికి అభ్యర్థించు"</string>
- <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"ప్యాకేజీల తొలగింపును అభ్యర్థించడానికి యాప్ను అనుమతిస్తుంది."</string>
+ <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"ప్యాకేజీల తొలగింపును రిక్వెస్ట్ చేయడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"బ్యాటరీ అనుకూలీకరణలను విస్మరించడానికి అడగాలి"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"ఆ యాప్ కోసం బ్యాటరీ అనుకూలీకరణలు విస్మరించేలా అనుమతి కోరడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"అన్ని ప్యాకేజీలను క్వెరీ చేయండి"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"ఇన్స్టాల్ చేసిన అన్ని ప్యాకేజీలను చూడటానికి యాప్ను అనుమతించండి."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApisని యాక్సెస్ చేయండి"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"SupplementalApisని యాక్సెస్ చేయడానికి యాప్ను అనుమతిస్తుంది."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices టాపిక్స్ APIని యాక్సెస్ చేయండి"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"AdServices టాపిక్స్ APIని యాక్సెస్ చేయడానికి అప్లికేషన్ను అనుమతిస్తుంది."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices అట్రిబ్యూషన్ APIలను యాక్సెస్ చేయండి"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"AdServices అట్రిబ్యూషన్ APIలను యాక్సెస్ చేయడానికి అప్లికేషన్ను అనుమతిస్తుంది."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices అనుకూల ప్రేక్షకుల APIని యాక్సెస్ చేయండి"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"AdServices అనుకూల ప్రేక్షకుల APIని యాక్సెస్ చేయడానికి అప్లికేషన్ను అనుమతిస్తుంది."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"జూమ్ నియంత్రణ కోసం రెండుసార్లు నొక్కండి"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"విడ్జెట్ను జోడించడం సాధ్యపడలేదు."</string>
<string name="ime_action_go" msgid="5536744546326495436">"వెళ్లు"</string>
@@ -1465,13 +1468,13 @@
<string name="ime_action_default" msgid="8265027027659800121">"అమలు చేయి"</string>
<string name="dial_number_using" msgid="6060769078933953531">"<xliff:g id="NUMBER">%s</xliff:g>ని ఉపయోగించి\nనంబర్ డయల్ చేయండి"</string>
<string name="create_contact_using" msgid="6200708808003692594">"<xliff:g id="NUMBER">%s</xliff:g>ని ఉపయోగించి\nకాంటాక్ట్ను క్రియేట్ చేయండి"</string>
- <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"కింది ఒకటి లేదా అంతకంటే ఎక్కువ యాప్లు మీ ఖాతాను యాక్సెస్ చేయడానికి ఇప్పుడు మరియు భవిష్యత్తులో అనుమతిని అభ్యర్థించవచ్చు."</string>
+ <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"కింది ఒకటి లేదా అంతకంటే ఎక్కువ యాప్లు మీ ఖాతాను యాక్సెస్ చేయడానికి ఇప్పుడు మరియు భవిష్యత్తులో అనుమతిని రిక్వెస్ట్ చేయవచ్చు."</string>
<string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"మీరు ఈ రిక్వెస్ట్ను అనుమతించాలనుకుంటున్నారా?"</string>
<string name="grant_permissions_header_text" msgid="3420736827804657201">"యాక్సెస్ రిక్వెస్ట్"</string>
<string name="allow" msgid="6195617008611933762">"అనుమతించండి"</string>
<string name="deny" msgid="6632259981847676572">"తిరస్కరించండి"</string>
- <string name="permission_request_notification_title" msgid="1810025922441048273">"అనుమతి అభ్యర్థించబడింది"</string>
- <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"ఖాతా <xliff:g id="ACCOUNT">%s</xliff:g> కోసం\nఅనుమతి అభ్యర్థించబడింది."</string>
+ <string name="permission_request_notification_title" msgid="1810025922441048273">"అనుమతి రిక్వెస్ట్ చేయబడింది"</string>
+ <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"ఖాతా <xliff:g id="ACCOUNT">%s</xliff:g> కోసం\nఅనుమతి రిక్వెస్ట్ చేయబడింది."</string>
<string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"<xliff:g id="APP">%1$s</xliff:g> ద్వారా అనుమతి రిక్వెస్ట్ చేయబడింది\nఖాతా <xliff:g id="ACCOUNT">%2$s</xliff:g> కోసం."</string>
<string name="forward_intent_to_owner" msgid="4620359037192871015">"మీరు మీ కార్యాలయ ప్రొఫైల్కు వెలుపల ఈ యాప్ను ఉపయోగిస్తున్నారు"</string>
<string name="forward_intent_to_work" msgid="3620262405636021151">"మీరు మీ కార్యాలయ ప్రొఫైల్లో ఈ యాప్ను ఉపయోగిస్తున్నారు"</string>
@@ -1514,7 +1517,7 @@
<string name="find_previous" msgid="4405898398141275532">"మునుపటిదాన్ని కనుగొను"</string>
<string name="gpsNotifTicker" msgid="3207361857637620780">"<xliff:g id="NAME">%s</xliff:g> నుండి లొకేషన్ రిక్వెస్ట్"</string>
<string name="gpsNotifTitle" msgid="1590033371665669570">"లొకేషన్ రిక్వెస్ట్"</string>
- <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) ద్వారా అభ్యర్థించబడింది"</string>
+ <string name="gpsNotifMessage" msgid="7346649122793758032">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) ద్వారా రిక్వెస్ట్ చేయబడింది"</string>
<string name="gpsVerifYes" msgid="3719843080744112940">"అవును"</string>
<string name="gpsVerifNo" msgid="1671201856091564741">"కాదు"</string>
<string name="sync_too_many_deletes" msgid="6999440774578705300">"తొలగింపు పరిమితి మించిపోయింది"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> యూజర్కు స్విచ్ అవుతోంది…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>ని లాగ్ అవుట్ చేస్తోంది…"</string>
<string name="owner_name" msgid="8713560351570795743">"ఓనర్"</string>
+ <string name="guest_name" msgid="8502103277839834324">"గెస్ట్"</string>
<string name="error_message_title" msgid="4082495589294631966">"ఎర్రర్"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ఈ మార్పును మీ నిర్వాహకులు అనుమతించలేదు"</string>
<string name="app_not_found" msgid="3429506115332341800">"ఈ చర్యను నిర్వహించడానికి యాప్ ఏదీ కనుగొనబడలేదు"</string>
@@ -1915,8 +1919,8 @@
<string name="importance_from_user" msgid="2782756722448800447">"మీరు ఈ నోటిఫికేషన్ల ప్రాముఖ్యతను సెట్ చేశారు."</string>
<string name="importance_from_person" msgid="4235804979664465383">"ఇందులో పేర్కొనబడిన వ్యక్తులను బట్టి ఇది చాలా ముఖ్యమైనది."</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"అనుకూల యాప్ నోటిఫికేషన్"</string>
- <string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో కొత్త వినియోగదారుని సృష్టించడానికి <xliff:g id="APP">%1$s</xliff:g>ను అనుమతించాలా (ఈ ఖాతాతో ఇప్పటికే ఒక వినియోగదారు ఉన్నారు) ?"</string>
- <string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో కొత్త వినియోగదారుని సృష్టించడానికి <xliff:g id="APP">%1$s</xliff:g>ను అనుమతించాలా?"</string>
+ <string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో కొత్త వినియోగదారుని క్రియేట్ చేయడానికి <xliff:g id="APP">%1$s</xliff:g>ను అనుమతించాలా (ఈ ఖాతాతో ఇప్పటికే ఒక వినియోగదారు ఉన్నారు) ?"</string>
+ <string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో కొత్త వినియోగదారుని క్రియేట్ చేయడానికి <xliff:g id="APP">%1$s</xliff:g>ను అనుమతించాలా?"</string>
<string name="supervised_user_creation_label" msgid="6884904353827427515">"పర్యవేక్షించబడే యూజర్ను జోడించండి"</string>
<string name="language_selection_title" msgid="52674936078683285">"భాషను జోడించండి"</string>
<string name="country_selection_title" msgid="5221495687299014379">"ప్రాంతం ప్రాధాన్యత"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"అన్ఇన్స్టాల్ చేయండి"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ఏదేమైనా తెరువు"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"హానికరమైన యాప్ గుర్తించబడింది"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"సిస్టమ్ లాగ్ యాక్సెస్ రిక్వెస్ట్"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"అన్ని పరికర లాగ్లను యాక్సెస్ చేయడానికి <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>ను అనుమతించాలా?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"ఈ ఒక్కసారి మాత్రమే"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"అనుమతించవద్దు"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"ఫంక్షనల్ డీబగ్గింగ్ కోసం, <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> సిస్టమ్ లాగ్లను రిక్వెస్ట్ చేస్తుంది. ఈ లాగ్లు, మీ పరికరంలోని యాప్లు, సర్వీస్లు రాసిన సమాచారాన్ని కలిగి ఉండవచ్చు."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"మీ పరికరంలో జరిగే దాన్ని పరికర లాగ్లు రికార్డ్ చేస్తాయి. సమస్యలను కనుగొని, పరిష్కరించడానికి యాప్లు ఈ లాగ్లను ఉపయోగిస్తాయి.\n\nకొన్ని లాగ్లలో గోప్యమైన సమాచారం ఉండవచ్చు, కాబట్టి మీరు విశ్వసించే యాప్లను మాత్రమే అన్ని పరికర లాగ్లను యాక్సెస్ చేయడానికి అనుమతించండి. \n\nఅన్ని పరికర లాగ్లను యాక్సెస్ చేయడానికి మీరు ఈ యాప్ను అనుమతించకపోతే, అది తన స్వంత లాగ్లను యాక్సెస్ చేయగలదు, మీ పరికర తయారీదారు ఇప్పటికీ మీ పరికరంలో కొన్ని లాగ్లు లేదా సమాచారాన్ని యాక్సెస్ చేయగలరు. మరింత తెలుసుకోండి"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"మళ్లీ చూపవద్దు"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> <xliff:g id="APP_2">%2$s</xliff:g> స్లైస్లను చూపించాలనుకుంటోంది"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"ఎడిట్ చేయండి"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> చాలా సమయం నుండి బ్యాక్గ్రౌండ్లో రన్ అవుతోంది. రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"యాక్టివ్గా ఉన్న యాప్లను చెక్ చేయండి"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"ఈ పరికరం నుండి కెమెరాను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 883da19..51b6c8d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"ปิดชั่วคราวโดยผู้ให้บริการของซิม <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"เชื่อมต่อเครือข่ายมือถือไม่ได้"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ลองเปลี่ยนเครือข่ายที่ต้องการ แตะเพื่อเปลี่ยน"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"โทรหาหมายเลขฉุกเฉินไม่ได้"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"โทรหาหมายเลขฉุกเฉินผ่าน Wi‑Fi ไม่ได้"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"หมายเลขฉุกเฉินอาจไม่สามารถใช้งานได้"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> ไม่รองรับการโทรไปยังหมายเลขฉุกเฉินผ่าน Wi-Fi แตะเพื่อดูรายละเอียด"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"การแจ้งเตือน"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"การโอนสาย"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"โหมดติดต่อกลับฉุกเฉิน"</string>
@@ -227,7 +227,7 @@
<string name="reboot_to_update_reboot" msgid="4474726009984452312">"กำลังรีสตาร์ท…"</string>
<string name="reboot_to_reset_title" msgid="2226229680017882787">"รีเซ็ตข้อมูลเป็นค่าเริ่มต้น"</string>
<string name="reboot_to_reset_message" msgid="3347690497972074356">"กำลังรีสตาร์ท…"</string>
- <string name="shutdown_progress" msgid="5017145516412657345">"กำลังปิด..."</string>
+ <string name="shutdown_progress" msgid="5017145516412657345">"กำลังปิดเครื่อง..."</string>
<string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"แท็บเล็ตของคุณจะปิดการทำงาน"</string>
<string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"อุปกรณ์ Android TV จะปิดเครื่อง"</string>
<string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"นาฬิกาจะปิดการทำงาน"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"อนุญาตให้แอปแก้ไขบันทึกการโทรจากแท็บเล็ตของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อลบหรือแก้ไขบันทึกการโทรของคุณ"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"อนุญาตให้แอปแก้ไขบันทึกการโทรจากอุปกรณ์ Android TV รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและสายโทรออก แอปที่เป็นอันตรายอาจใช้สิทธิ์นี้เพื่อลบหรือแก้ไขบันทึกการโทรได้"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"อนุญาตให้แอปแก้ไขบันทึกการโทรจากโทรศัพท์ของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อลบหรือแก้ไขบันทึกการโทรของคุณ"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"เข้าถึงเซ็นเซอร์ร่างกาย (เช่น ตัววัดอัตราการเต้นของหัวใจ)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"เข้าถึงข้อมูลจากเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ อุณหภูมิ เปอร์เซ็นต์ออกซิเจนในเลือด ฯลฯ"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"เข้าถึงเซ็นเซอร์ร่างกาย (เช่น เครื่องวัดอัตราการเต้นของหัวใจ) ในเบื้องหลัง"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"เข้าถึงข้อมูลจากเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ อุณหภูมิ เปอร์เซ็นต์ออกซิเจนในเลือด ฯลฯ ในเบื้องหลัง"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"เข้าถึงข้อมูลเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ ขณะใช้งานแอป"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"อนุญาตให้แอปเข้าถึงข้อมูลเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ อุณหภูมิ และเปอร์เซ็นต์ออกซิเจนในเลือด ขณะใช้งานแอป"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"เข้าถึงข้อมูลเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ ขณะแอปทำงานในเบื้องหลัง"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"อนุญาตให้แอปเข้าถึงข้อมูลเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ อุณหภูมิ และเปอร์เซ็นต์ออกซิเจนในเลือด ขณะที่แอปทำงานในเบื้องหลัง"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"อ่านกิจกรรมในปฏิทินและรายละเอียด"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"แอปนี้สามารถอ่านกิจกรรมทั้งหมดในปฏิทินที่เก็บไว้ในแท็บเล็ต รวมถึงแชร์หรือบันทึกข้อมูลในปฏิทินของคุณ"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"แอปนี้อ่านกิจกรรมทั้งหมดในปฏิทินที่จัดเก็บไว้ในอุปกรณ์ Android TV ได้ รวมถึงแชร์หรือบันทึกข้อมูลในปฏิทินของคุณได้ด้วย"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"อนุญาตให้แอปอ่านไฟล์เสียงจากพื้นที่เก็บข้อมูลที่แชร์"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"อ่านไฟล์วิดีโอจากพื้นที่เก็บข้อมูลที่แชร์"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"อนุญาตให้แอปอ่านไฟล์วิดีโอจากพื้นที่เก็บข้อมูลที่แชร์"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"อ่านไฟล์ภาพจากพื้นที่เก็บข้อมูลที่แชร์"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"อนุญาตให้แอปอ่านไฟล์ภาพจากพื้นที่เก็บข้อมูลที่แชร์"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"อ่านไฟล์ภาพจากพื้นที่เก็บข้อมูลที่แชร์"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"อนุญาตให้แอปอ่านไฟล์ภาพจากพื้นที่เก็บข้อมูลที่แชร์"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"แก้ไขหรือลบเนื้อหาในพื้นที่จัดเก็บข้อมูลที่ใช้ร่วมกัน"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"อนุญาตให้แอปเขียนเนื้อหาในพื้นที่จัดเก็บข้อมูลที่ใช้ร่วมกัน"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"โทร/รับสาย SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"กด เมนู เพื่อปลดล็อกหรือโทรฉุกเฉิน"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"กด เมนู เพื่อปลดล็อก"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"วาดรูปแบบเพื่อปลดล็อก"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"หมายเลขฉุกเฉิน"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"เหตุฉุกเฉิน"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"กลับสู่การโทร"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"ถูกต้อง!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"ลองอีกครั้ง"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"ไม่ต้องเลย"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"คุณไม่ได้รับอนุญาตให้เปิดหน้าเว็บนี้"</string>
<string name="text_copied" msgid="2531420577879738860">"คัดลอกข้อความไปยังคลิปบอร์ด"</string>
- <string name="copied" msgid="4675902854553014676">"คัดลอกแล้ว"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"วาง <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> จาก <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> แล้ว"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ได้วางข้อมูลจากคลิปบอร์ดแล้ว"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> วางข้อความที่คุณคัดลอก"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"อนุญาตให้แอปขอสิทธิ์เพิกเฉยต่อการเพิ่มประสิทธิภาพแบตเตอรี่สำหรับแอปนั้น"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"ค้นหาแพ็กเกจทั้งหมด"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"อนุญาตให้แอปดูแพ็กเกจที่ติดตั้งไว้ทั้งหมด"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"เข้าถึง SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"อนุญาตให้แอปพลิเคชันเข้าถึง SupplementalApis"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"เข้าถึง AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"อนุญาตให้แอปพลิเคชันเข้าถึง AdServices Topics API"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"เข้าถึง AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"อนุญาตให้แอปพลิเคชันเข้าถึง AdServices Attribution API"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"เข้าถึง AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"อนุญาตให้แอปพลิเคชันเข้าถึง AdServices Custom Audiences API"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"แตะสองครั้งเพื่อควบคุมการซูม"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ไม่สามารถเพิ่มวิดเจ็ต"</string>
<string name="ime_action_go" msgid="5536744546326495436">"ไป"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"กำลังเปลี่ยนเป็น <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"กำลังออกจากระบบ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"เจ้าของ"</string>
+ <string name="guest_name" msgid="8502103277839834324">"ผู้มาเยือน"</string>
<string name="error_message_title" msgid="4082495589294631966">"ข้อผิดพลาด"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"ผู้ดูแลระบบไม่อนุญาตให้ทำการเปลี่ยนแปลงนี้"</string>
<string name="app_not_found" msgid="3429506115332341800">"ไม่พบแอปพลิเคชันสำหรับการทำงานนี้"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ถอนการติดตั้ง"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"เปิดต่อไป"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"ตรวจพบแอปที่เป็นอันตราย"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"คำขอเข้าถึงบันทึกของระบบ"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"อนุญาตให้ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> เข้าถึงบันทึกทั้งหมดของอุปกรณ์ใช่ไหม"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"เฉพาะครั้งนี้"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"ไม่อนุญาต"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ขอบันทึกของระบบเพื่อแก้ไขข้อบกพร่องเกี่ยวกับการทำงาน บันทึกเหล่านี้อาจมีข้อมูลที่เขียนโดยแอปและบริการในอุปกรณ์"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"บันทึกของอุปกรณ์เก็บข้อมูลสิ่งที่เกิดขึ้นในอุปกรณ์ แอปสามารถใช้บันทึกนี้เพื่อค้นหาและแก้ไขปัญหา\n\nบันทึกบางรายการอาจมีข้อมูลที่ละเอียดอ่อน ดังนั้นคุณควรอนุญาตเฉพาะแอปที่เชื่อถือได้ให้เข้าถึงบันทึกทั้งหมดของอุปกรณ์ \n\nหากคุณไม่อนุญาตให้แอปนี้เข้าถึงบันทึกทั้งหมดของอุปกรณ์ แอปจะยังเข้าถึงบันทึกของตัวเองได้อยู่ และผู้ผลิตอุปกรณ์อาจยังเข้าถึงบันทึกหรือข้อมูลบางรายการในอุปกรณ์ของคุณได้ ดูข้อมูลเพิ่มเติม"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"ไม่ต้องแสดงอีก"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ต้องการแสดงส่วนต่างๆ ของ <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"แก้ไข"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ทำงานอยู่ในเบื้องหลังเป็นเวลานาน แตะเพื่อตรวจสอบ"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ตรวจสอบแอปที่ใช้งานอยู่"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"เข้าถึงกล้องจากอุปกรณ์นี้ไม่ได้"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 2360951..6b1025a 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Pansamantalang na-off ng iyong carrier para sa SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Hindi makakonekta sa mobile network"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Subukang baguhin ang gustong network. I-tap para baguhin."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hindi available ang pang-emergency na pagtawag"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Hindi makapagsagawa ng mga emergency na tawag sa pamamagitan ng Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Posibleng hindi available ang mga emergency na tawag"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"Hindi sinusuportahan ng <xliff:g id="SPN">%s</xliff:g> ang mga emergency na tawag sa pamamagitan ng Wi-Fi. I-tap para sa mga detalye."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Mga Alerto"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Pagpasa ng tawag"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Emergency callback mode"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Binibigyan-daan ang app na baguhin ang log ng tawag ng iyong tablet, kabilang ang data tungkol sa mga paparating at papalabas na tawag. Maaari itong gamitin ng nakakahamak na apps upang burahin o baguhin ang iyong log ng tawag."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Nagbibigay-daan sa app na baguhin ang log ng tawag ng iyong Android TV device, kasama ang data tungkol sa mga papasok at papalabas na tawag. Puwede itong gamitin ng mga mapaminsalang app para burahin o baguhin ang iyong log ng tawag."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Binibigyan-daan ang app na baguhin ang log ng tawag ng iyong telepono, kabilang ang data tungkol sa mga paparating at papalabas na tawag. Maaari itong gamitin ng nakakahamak na apps upang burahin o baguhin ang iyong log ng tawag."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"i-access ang mga sensor sa katawan (tulad ng mga monitor ng bilis ng tibok ng puso)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Access sa data mula sa mga sensor ng katawan gaya ng bilis ng tibok ng puso, temperatura, porsyento ng oxygen sa dugo, atbp."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"i-access ang body sensors (tulad ng heart rate monitors) habang nasa background"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Access sa data mula sa mga sensor ng katawan gaya ng bilis ng tibok ng puso, temperatura, porsyento ng oxygen sa dugo, atbp. habang nasa background."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"I-access ang data ng sensor ng katawan, gaya ng heart rate, habang ginagamit"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Nagpapahintulot sa app na i-access ang data ng sensor ng katawan, gaya ng bilis ng tibok ng puso, temperatura, at porsyento ng oxygen sa dugo, habang ginagamit ang app."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"I-access ang data ng sensor ng katawan gaya ng heart rate habang nasa background"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Nagpapahintulot sa app na i-access ang data ng sensor ng katawan, gaya ng bilis ng tibok ng puso, temperatura, at porsyento ng oxygen sa dugo, habang nasa background ang app."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Magbasa ng mga event sa kalendaryo at detalye"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Mababasa ng app na ito ang lahat ng event sa kalendaryo na naka-store sa iyong tablet at maibabahagi o mase-save nito ang data ng iyong kalendaryo."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Mababasa ng app na ito ang lahat ng event sa kalendaryo na naka-store sa iyong Android TV device at maibabahagi o mase-save nito ang data ng kalendaryo mo."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Nagbibigay-daan sa app na magbasa ng mga audio file mula sa iyong nakabahaging storage."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"magbasa ng mga video file mula sa nakabahaging storage"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Nagbibigay-daan sa app na magbasa ng mga video file mula sa iyong nakabahaging storage."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"magbasa ng mga image file mula sa nakabahaging storage"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Nagbibigay-daan sa app na magbasa ng mga image file mula sa iyong nakabahaging storage."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"magbasa ng mga image file mula sa nakabahaging storage"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Nagbibigay-daan sa app na magbasa ng mga image file mula sa iyong nakabahaging storage."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"baguhin o i-delete ang content ng nakabahagi mong storage"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Pinapayagan ang app na mag-write sa content ng nakabahagi mong storage."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"magsagawa/tumanggap ng mga tawag sa SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Pindutin ang Menu upang i-unlock o magsagawa ng pang-emergency na tawag."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Pindutin ang Menu upang i-unlock."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Iguhit ang pattern upang i-unlock"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Emergency na tawag"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Emergency"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Bumalik sa tawag"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Tama!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Subukang muli"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Hindi Kailanman"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Wala kang pahintulot na buksan ang pahinang ito."</string>
<string name="text_copied" msgid="2531420577879738860">"Nakopya ang teksto sa clipboard."</string>
- <string name="copied" msgid="4675902854553014676">"Nakopya"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Na-paste ang <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> mula sa <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Na-paste ang <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> mula sa iyong clipboard"</string>
<string name="pasted_text" msgid="4298871641549173733">"Nag-paste ang <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> ng text na nakopya mo"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Pinapayagang humingi ng pahintulot ang isang app na balewalain ang mga pag-optimize ng baterya para sa app na iyon."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"i-query ang lahat ng package"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Nagbibigay-daan sa isang app na makita ang lahat ng naka-install na package."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"access sa SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Nagbibigay-daan sa isang application na i-access ang SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"i-access ang AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Nagbibigay-daan sa isang application na i-access ang AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"i-access ang mga AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Nagbibigay-daan sa isang application na i-access ang mga AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"i-access ang AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Nagbibigay-daan sa isang application na i-access ang AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Tapikin ng dalawang beses para sa pagkontrol ng zoom"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Hindi maidagdag ang widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Pumunta"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Lumilipat kay <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Nila-log out si <xliff:g id="NAME">%1$s</xliff:g>..."</string>
<string name="owner_name" msgid="8713560351570795743">"May-ari"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Bisita"</string>
<string name="error_message_title" msgid="4082495589294631966">"Error"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Hindi pinapayagan ng iyong admin ang pagbabagong ito"</string>
<string name="app_not_found" msgid="3429506115332341800">"Walang nakitang application na mangangasiwa sa pagkilos na ito"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"I-UNINSTALL"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"BUKSAN PA RIN"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"May na-detect na mapaminsalang app"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Kahilingan sa access sa log ng system"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Payagan ang <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> na i-access ang lahat ng log ng device?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Ngayon lang"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Huwag payagan"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"Humihiling ang <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ng mga log ng system para sa functional na pag-debug. Posibleng maglaman ang mga log na ito ng impormasyong isinulat ng mga app at serbisyo sa iyong device."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Nire-record ng mga log ng device kung ano ang nangyayari sa iyong device. Magagamit ng mga app ang mga log na ito para maghanap at mag-ayos ng mga isyu.\n\nPosibleng maglaman ang ilang log ng sensitibong impormasyon, kaya ang mga app lang na pinagkakatiwalaan mo ang payagang maka-access sa lahat ng log ng device. \n\nKung hindi mo papayagan ang app na ito na i-access ang lahat ng log ng device, maa-access pa rin nito ang mga sarili nitong log, at posible pa ring ma-access ng manufacturer ng iyong device ang ilang log o impormasyon sa device mo. Matuto pa"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Huwag ipakita ulit"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"Gustong ipakita ng <xliff:g id="APP_0">%1$s</xliff:g> ang mga slice ng <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"I-edit"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Napakatagal nang gumagana ang <xliff:g id="APP">%1$s</xliff:g> sa background. I-tap para suriin."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tingnan ang mga aktibong app"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Hindi ma-access ang camera mula sa device na ito"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index d1a568d..1e0cff5 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"<xliff:g id="SIMNUMBER">%d</xliff:g> numaralı SIM kart için operatörünüz tarafından geçici olarak kapatıldı"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobil ağa erişilemiyor"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tercih edilen ağı değiştirmeyi deneyin. Değiştirmek için dokunun."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Acil durum çağrısı kullanılamaz"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Kablosuz ağ üzerinden acil durum çağrıları yapılamaz"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Acil durum aramaları kullanılamayabilir"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g>, kablosuz bağlantı üzerinden acil durum aramalarını desteklemiyor. Ayrıntılar için dokunun."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Uyarılar"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Çağrı yönlendirme"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Acil geri arama modu"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Uygulamaya tabletinizin çağrı günlüğünde (gelen ve giden çağrılarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak çağrı günlüğünüzü silebilir veya değiştirebilir."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Uygulamaya, Android TV cihazınızın arama günlüğünde (gelen ve giden aramalarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak arama günlüğünüzü silebilir veya değiştirebilir."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Uygulamaya telefonunuzun arama günlüğünde (gelen ve giden aramalarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak arama günlüğünüzü silebilir veya değiştirebilir."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"vücut sensörlerine erişme (nabız takip cihazları gibi)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Nabız, vücut ısısı, kandaki oksijen yüzdesi gibi vücut sensörlerinden gelen verilere erişim."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"arka plandayken vücut sensörlerine erişim (nabız takip cihazları gibi)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Arka plandayken nabız, vücut ısısı, kandaki oksijen yüzdesi gibi vücut sensörlerinden gelen verilere erişim."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Kullanımdayken nabız gibi vücut sensörü verilerine erişme"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Kullanımdaki uygulamanın nabız, vücut ısısı, kandaki oksijen yüzdesi gibi vücut sensörü verilerine erişmesine izin verir."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Arka plandayken nabız gibi vücut sensörü verilerine erişme"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Arka plandaki uygulamanın nabız, vücut ısısı, kandaki oksijen yüzdesi gibi vücut sensörü verilerine erişmesine izin verir."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Takvim etkinlikleri ve ayrıntılarını okuma"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Bu uygulama, tabletinizde kayıtlı tüm takvim etkinliklerini okuyabilir ve takvim verilerinizi paylaşabilir ya da kaydedebilir."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Bu uygulama, Android TV cihazınızda kayıtlı tüm takvim etkinliklerini okuyabilir ve takvim verilerinizi paylaşabilir ya da kaydedebilir."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Uygulamaya, paylaşılan depolama alanınızdaki ses dosyalarını okuma izni verir."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"paylaşılan depolama alanınızdaki video dosyalarını okuma"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Uygulamaya, paylaşılan depolama alanınızdaki video dosyalarını okuma izni verir."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"paylaşılan depolama alanınızdaki resim dosyalarını okuma"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Uygulamaya, paylaşılan depolama alanınızdaki resim dosyalarını okuma izni verir."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"paylaşılan depolama alanınızdaki resim dosyalarını okuma"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Uygulamaya, paylaşılan depolama alanınızdaki resim dosyalarını okuma izni verir."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"paylaşılan depolama alanımın içeriğini değiştir veya sil"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Uygulamanın paylaşılan depolama alanınıza içerik yazmasına izin verir."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP aramaları yapma/alma"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Kilidi açmak veya acil çağrı yapmak için Menü\'ye basın."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Kilidi açmak için Menü\'ye basın."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Kilit açmak için deseni çizin"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Acil durum araması"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Acil durum çağrısı"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Çağrıya dön"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Doğru!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Tekrar deneyin"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Hiçbir zaman"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Bu sayfayı açma izniniz yok."</string>
<string name="text_copied" msgid="2531420577879738860">"Metin panoya kopyalandı."</string>
- <string name="copied" msgid="4675902854553014676">"Kopyalandı"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> uygulaması <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> kaynağından yapıştırdı"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>, panonuzdakini yapıştırdı"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>, kopyaladığınız metni yapıştırdı"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Bir uygulamanın, kendisi için pil optimizasyonlarını göz ardı etme izni istemesine olanak sağlar."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"tüm paketleri sorgulama"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Uygulamaya tüm yüklü paketleri görme izni verir."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis\'e erişim"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Bir uygulamanın SupplementalApis\'e erişimine izin verir."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API\'sine eriş"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Uygulamanın AdServices Topics API\'sine erişmesine izin verir."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API\'lerine eriş"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Uygulamanın AdServices Attribution API\'lerine erişmesine izin verir."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API\'sine eriş"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Uygulamanın AdServices Custom Audiences API\'sine erişmesine izin verir."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Zum denetimi için iki kez dokun"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Widget eklenemedi."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Git"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adlı kullanıcıya geçiliyor…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> hesabından çıkış yapılıyor…"</string>
<string name="owner_name" msgid="8713560351570795743">"Sahip"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Misafir"</string>
<string name="error_message_title" msgid="4082495589294631966">"Hata"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Yöneticiniz bu değişikliğe izin vermiyor"</string>
<string name="app_not_found" msgid="3429506115332341800">"Bu eylemi gerçekleştirecek bir uygulama bulunamadı"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"YÜKLEMEYİ KALDIR"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"YİNE DE AÇ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Zararlı uygulama tespit edildi"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Sistem günlük kayıtlarına erişim isteği"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> uygulamasının tüm cihaz günlüklerine erişmesine izin verilsin mi?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Yalnız bu sefer"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"İzin verme"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> uygulaması işlevsel hata ayıklama için sistem günlük kayıtlarını istiyor. Bu günlükler, cihazınızdaki uygulama ve hizmetler tarafından yazılan bilgileri içerebilir."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Cihaz günlükleri, cihazınızda olanları kaydeder. Uygulamalar, sorunları bulup düzeltmek için bu günlükleri kullanabilir.\n\nBazı günlükler hassas bilgiler içerebileceği için yalnızca güvendiğiniz uygulamaların tüm cihaz günlüklerine erişmesine izin verin. \n\nBu uygulamanın tüm cihaz günlüklerine erişmesine izin vermeseniz de kendi günlüklerine erişmeye devam edebilir. Ayrıca, cihaz üreticiniz de cihazınızdaki bazı günlüklere veya bilgilere erişmeye devam edebilir. Daha fazla bilgi"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Bir daha gösterme"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> uygulaması, <xliff:g id="APP_2">%2$s</xliff:g> dilimlerini göstermek istiyor"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Düzenle"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> uzun süredir arka planda çalışıyor. İncelemek için dokunun."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Etkin uygulamaları kontrol edin"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Bu cihazdan kameraya erişilemiyor"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 955651a..997bf47 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -87,8 +87,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Оператор тимчасово вимкнув службу для SIM-карти <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Не вдається під’єднатися до мобільної мережі"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Спробуйте змінити вибрану мережу. Торкніться, щоб це зробити."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Екстрені виклики недоступні"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Не можна здійснювати екстрені виклики через Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Екстрені виклики можуть бути недоступні"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> не підтримує екстрені виклики через Wi-Fi. Натисніть, щоб дізнатися більше."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Сповіщення"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Переадресація виклику"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим екстреного зворотного виклику"</string>
@@ -427,10 +427,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Дозволяє програмі змінювати журнал викликів вашого планшетного ПК, включно з даними про вхідні та вихідні дзвінки. Шкідливі програми можуть використовувати це для стирання або зміни вашого журналу викликів."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Дозволяє додатку змінювати журнал викликів пристрою, зокрема дані про вхідні та вихідні дзвінки. Шкідливі додатки можуть стирати або змінювати журнал викликів."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Дозволяє програмі змінювати журнал викликів вашого телефону, включно з даними про вхідні та вихідні дзвінки. Шкідливі програми можуть використовувати це для стирання або зміни вашого журналу викликів."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"отримувати дані з датчиків на тілі (наприклад, з пульсометра)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Доступ до даних із датчиків на тілі, наприклад про пульс, температуру, вміст кисню в крові тощо."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"отримувати дані з датчиків на тілі (наприклад, з пульсометра) у фоновому режимі"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Доступ до даних із датчиків на тілі, наприклад про пульс, температуру, вміст кисню в крові тощо (у фоновому режимі)."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Доступ до показників датчиків на тілі, наприклад пульсу, під час використання"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Під час використання додатка він матиме доступ до даних датчиків на тілі, наприклад пульсу, температури та відсотка кисню в крові."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Доступ до показників датчиків на тілі, наприклад пульсу, у фоновому режимі"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Коли додаток працюватиме у фоновому режимі, він матиме доступ до показників датчиків на тілі, наприклад пульсу, температури та відсотка кисню в крові."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Переглядати події календаря й додаткову інформацію"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Цей додаток може переглядати всі події календаря, збережені на вашому планшеті, а також надсилати та зберігати дані календаря."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Додаток може переглядати всі події календаря, збережені на вашому пристрої Android TV, а також надсилати та зберігати дані календаря."</string>
@@ -691,8 +691,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Дозволяє додатку зчитувати аудіофайли з вашого спільного сховища."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"зчитувати відеофайли зі спільного сховища"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Дозволяє додатку зчитувати відеофайли з вашого спільного сховища."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"зчитувати файли зображень зі спільного сховища"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Дозволяє додатку зчитувати файли зображень із вашого спільного сховища."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"зчитувати файли зображень зі спільного сховища"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Дозволяє додатку зчитувати файли зображень із вашого спільного сховища."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"змінювати чи видаляти вміст у спільній пам’яті"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Додаток може писати вміст у спільній пам’яті."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"здійснювати й отримувати дзвінки через протокол SIP"</string>
@@ -914,7 +914,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Натис. меню, щоб розбл. чи зробити авар. виклик."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Натисн. меню, щоб розбл."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Намал. ключ, щоб розбл."</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Екстрений виклик"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Екстрений виклик"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Поверн. до дзвін."</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Правильно!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Повторіть спробу"</string>
@@ -1053,7 +1053,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Ніколи"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"У вас немає дозволу на відкривання цієї сторінки."</string>
<string name="text_copied" msgid="2531420577879738860">"Текст скопійов. в буф. обм."</string>
- <string name="copied" msgid="4675902854553014676">"Скопійовано"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"Дані з додатка <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> вставлено в <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"Дані з буфера обміну вставлено в додатку <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
<string name="pasted_text" msgid="4298871641549173733">"Скопійований текст вставлено в додатку <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
@@ -1454,8 +1453,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Додаток зможе запитувати дозвіл ігнорувати оптимізацію використання заряду акумулятора."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"подавати запити на всі пакети"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Дозволяє додатку переглядати всі встановлені пакети."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"Доступ до SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Надає додатку доступ до SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"надавати доступ до AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Надає додатку доступ до AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"надавати доступ до інтерфейсів API AdServices Attribution"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Надає додатку доступ до інтерфейсів API AdServices Attribution."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"надавати доступ до AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Надає додатку доступ до AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Двічі натис. для кер. масшт."</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Не вдалося додати віджет."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Йти"</string>
@@ -1718,6 +1721,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Перехід у режим \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Вихід з облікового запису користувача <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Власник"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Гість"</string>
<string name="error_message_title" msgid="4082495589294631966">"Помилка"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Ця дія заборонена адміністратором"</string>
<string name="app_not_found" msgid="3429506115332341800">"Не знайдено програму для обробки цієї дії"</string>
@@ -2029,10 +2033,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"ВИДАЛИТИ"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"УСЕ ОДНО ВІДКРИТИ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Виявлено шкідливий додаток"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Запит на доступ до системних журналів"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Надати додатку <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> доступ до всіх журналів пристрою?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Лише цього разу"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Не дозволяти"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"Для функціонального налагодження додатку <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> потрібен доступ до системних журналів. Вони можуть містити інформацію, записану додатками й сервісами на вашому пристрої."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"У журналах пристрою реєструється все, що відбувається на ньому. За допомогою цих журналів додатки можуть виявляти й усувати проблеми.\n\nДеякі журнали можуть містити конфіденційні дані, тому надавати доступ до всіх журналів пристрою слід лише надійним додаткам. \n\nЯкщо додаток не має доступу до всіх журналів пристрою, він усе одно може використовувати власні журнали, а виробник вашого пристрою – деякі журнали чи інформацію на ньому. Докладніше"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Більше не показувати"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> хоче показати фрагменти додатка <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Редагувати"</string>
@@ -2267,4 +2271,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Додаток <xliff:g id="APP">%1$s</xliff:g> довго працює у фоновому режимі. Натисніть, щоб переглянути."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Перевірте активні додатки"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Не вдається отримати доступ до камери через цей пристрій"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 90e20b3..2770f89 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> کے لئے آپ کے کیریئر نے عارضی طور پر آف کر دیا ہے"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"موبائل نیٹ ورک تک رسائی نہیں ہو سکتی"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ترجیحی نیٹ ورک تبدیل کر کے دیکھیں۔ تبدیل کرنے کے لیے تھپتھپائیں۔"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ہنگامی کالنگ دستیاب نہیں ہے"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi‑Fi کے ذریعے ہنگامی کالز نہیں کر سکتے"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"ہو سکتا ہے کہ ہنگامی کالز دستیاب نہ ہوں"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi پر ہنگامی کالز کو سپورٹ نہیں کرتا ہے۔ تفصیلات کے ليے تھپتھپائيں۔"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"الرٹس"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"کال فارورڈنگ"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"ہنگامی کال بیک وضع"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ایپ کو آپ کے ٹیبلٹ کی کال لاگ، بشمول آنے والی اور باہر جانے والی کالوں کے بارے میں ڈیٹا میں ترمیم کرنے کی اجازت دیتا ہے۔ نقصان دہ ایپس آپ کی کال لاگ مٹانے یا اس میں ترمیم کرنے کیلئے اسے استعمال کرسکتی ہیں۔"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"آنے والی اور باہر جانے والی کالز کے بارے میں ڈیٹا سمیت، ایپ کو آپ کے Android TV آلہ کے کال لاگ میں ترمیم کرنے کی اجازت دیتا ہے۔ نقصان دہ ایپس آپ کی کال لاگ مٹانے یا اس میں ترمیم کرنے کیلئے اسے استعمال کر سکتی ہیں۔"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ایپ کو آپ کے فون کی کال لاگ، بشمول آنے والی اور باہر جانے والی کالوں کے بارے میں ڈیٹا میں ترمیم کرنے کی اجازت دیتا ہے۔ نقصان دہ ایپس آپ کی کال لاگ مٹانے یا اس میں ترمیم کرنے کیلئے اسے استعمال کرسکتی ہیں۔"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"باڈی سینسرز تک رسائی حاصل کریں (جیسے حرکت قلب شرح مانیٹرز)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"باڈی سینسرز سے ڈیٹا تک رسائی حاصل کریں جیسے حرکت قلب کی شرح، درجہ حرارت، خون میں آکسیجن فیصد وغیرہ۔"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"پس منظر میں رہتے ہوئے باڈی سینسرز تک رسائی حاصل کریں (جیسے حرکت قلب کی شرح کے مانیٹرز)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"پس منظر میں رہتے ہوئے باڈی سینسرز سے ڈیٹا تک رسائی حاصل کریں جیسے حرکت قلب کی شرح، درجہ حرارت، خون میں آکسیجن کا فیصد وغیرہ۔"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"استعمال کے دوران حرکت قلب کی شرح جیسے باڈی سینسر ڈیٹا تک رسائی پائیں"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ایپ کے استعمال میں ہونے کے دوران ایپ کو حرکت قلب کی شرح، درجہ حرارت اور خون میں آکسیجن کا فیصد جیسے باڈی سینسر ڈیٹا تک رسائی کی اجازت دیتا ہے۔"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"پس منظر میں ہونے کے دوران حرکت قلب کی شرح جیسے باڈی سینسر ڈیٹا تک رسائی پائیں"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ایپ کے پس منظر میں ہونے کے دوران ایپ کو حرکت قلب کی شرح، درجہ حرارت اور خون میں آکسیجن کا فیصد جیسے باڈی سینسر ڈیٹا تک رسائی کی اجازت دیتا ہے۔"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"کیلنڈر ایونٹس اور تفاصیل پڑھیں"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"یہ ایپ آپ کے ٹیبلیٹ پر اسٹور کردہ سبھی کیلنڈر ایونٹس کو پڑھ سکتی ہے اور آپ کے کیلنڈر ڈیٹا کا اشتراک یا اسے محفوظ کر سکتی ہے۔"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"یہ ایپ آپ کے Android TV آلہ پر اسٹور کردہ سبھی کیلنڈر ایونٹس کو پڑھ سکتی ہے اور آپ کے کیلنڈر ڈیٹا کا اشتراک یا اسے محفوظ کر سکتی ہے۔"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"ایپ کو آپ کی اشتراک کردہ اسٹوریج سے آڈیو فائلز کو پڑھنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"اشتراک کردہ اسٹوریج سے ویڈیو فائلز کو پڑھیں"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"ایپ کو آپ کی اشتراک کردہ اسٹوریج سے ویڈیو فائلز کو پڑھنے کی اجازت دیتا ہے۔"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"اشتراک کردہ اسٹوریج سے تصویری فائلز کو پڑھیں"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"ایپ کو آپ کی اشتراک کردہ اسٹوریج سے تصویری فائلز کو پڑھنے کی اجازت دیتا ہے۔"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"اشتراک کردہ اسٹوریج سے تصویری فائلز کو پڑھیں"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"ایپ کو آپ کی اشتراک کردہ اسٹوریج سے تصویری فائلز کو پڑھنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"اپنے اشتراک کردہ اسٹوریج کے مواد میں ترمیم کریں یا اسے حذف کریں"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"ایپ کو آپ کے اشتراک کردہ اسٹوریج کے مواد کو لکھنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP کالز کریں/موصول کریں"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"غیر مقفل کرنے کیلئے مینو دبائیں یا ہنگامی کال کریں۔"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"غیر مقفل کرنے کیلئے مینو دبائیں۔"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"غیر مقفل کرنے کیلئے پیٹرن کو ڈرا کریں"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"ہنگامی کال"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ہنگامی"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"کال پر واپس جائیں"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"صحیح!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"دوبارہ کوشش کریں"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"کبھی نہیں"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"آپ کے پاس یہ صفحہ کھولنے کی اجازت نہیں ہے۔"</string>
<string name="text_copied" msgid="2531420577879738860">"متن کو کلپ بورڈ پر کاپی کیا گیا۔"</string>
- <string name="copied" msgid="4675902854553014676">"کاپی ہو گیا"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> سے <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> میں پیسٹ کیا گیا"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> نے آپ کے کلپ بورڈ سے پپیسٹ کر دیا"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> نے آپ کا کاپی کردہ ٹیکسٹ پیسٹ کر دیا"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"اس ایپ کیلئے ایک ایپ کو بیٹری کی کارکردگی بہتر بنانے کو نظر انداز کرنے کی اجازت دیں۔"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"سبھی پیکیجز سے متعلق استفسار کریں"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"ایپ کو سبھی انسٹال کردہ پیکیجز دیکھنے کی اجازت دیتا ہے۔"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis تک رسائی حاصل کریں"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"ایپلیکیشن کو SupplementalApis تک رسائی حاصل کرنے کی اجازت دیتا ہے۔"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API تک رسائی حاصل کریں"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"کسی ایپلیکیشن کو AdServices Topics API تک رسائی کی اجازت دیتا ہے۔"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution APIs تک رسائی حاصل کریں"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"کسی ایپلیکیشن کو AdServices Attribution APIs تک رسائی کی اجازت دیتا ہے۔"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API تک رسائی حاصل کریں"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"کسی ایپلیکیشن کو AdServices Custom Audiences API تک رسائی کی اجازت دیتا ہے۔"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"زوم کنٹرول کیلئے دوبار تھپتھپائیں"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"ویجٹس کو شامل نہیں کرسکا۔"</string>
<string name="ime_action_go" msgid="5536744546326495436">"جائیں"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> پر سوئچ کیا جا رہا ہے…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> لاگ آؤٹ ہو رہا ہے…"</string>
<string name="owner_name" msgid="8713560351570795743">"مالک"</string>
+ <string name="guest_name" msgid="8502103277839834324">"مہمان"</string>
<string name="error_message_title" msgid="4082495589294631966">"خرابی"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"آپ کے منتظم کی جانب سے اس تبدیلی کی اجازت نہیں ہے"</string>
<string name="app_not_found" msgid="3429506115332341800">"اس عمل کو ہینڈل کرنے کیلئے کوئی ایپلیکیشن نہیں ملا"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"اَن انسٹال کریں"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"بہر صورت کھولیں"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"ضرر رساں ایپ کا پتہ چلا"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"سسٹم لاگ تک رسائی کی درخواست"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> کو آلے کے تمام لاگز تک رسائی کی اجازت دیں؟"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"صرف اس وقت"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"اجازت نہ دیں"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"فنکشنل ڈیبگنگ کے لیے <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> سسٹم لاگز کی درخواست کر رہی ہے۔ ان لاگز میں آپ کے آلے پر موجود ایپس اور سروسز کی معلومات شامل ہو سکتی ہیں۔"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"آپ کے آلے پر جو ہوتا ہے آلے کے لاگز اسے ریکارڈ کر لیتے ہیں۔ ایپس ان لاگز کا استعمال مسائل کو تلاش کرنے اور ان کو حل کرنے کے لیے کر سکتی ہیں۔\n\nکچھ لاگز میں حساس معلومات شامل ہو سکتی ہیں، اس لیے صرف اپنے بھروسے مند ایپس کو ہی آلے کے تمام لاگز تک رسائی کی اجازت دیں۔ \n\nاگر آپ اس ایپ کو آلے کے تمام لاگز تک رسائی کی اجازت نہیں دیتے ہیں، پھر بھی اسے اپنی خود کی لاگز تک رسائی حاصل ہو سکتی ہے اور آپ کے آلے کا مینوفیکچرر اب بھی آپ کے آلے پر موجود کچھ لاگز یا معلومات تک رسائی حاصل کر سکتا ہے۔ مزید جانیں"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"دوبارہ نہ دکھائیں"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> <xliff:g id="APP_2">%2$s</xliff:g> کے سلائسز دکھانا چاہتی ہے"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"ترمیم کریں"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> کافی وقت سے پس منظر میں چل رہی ہے۔ جائزے کے لیے تھپتھپائیں۔"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"فعال ایپس چیک کریں"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"اس آلہ سے کیمرا تک رسائی حاصل نہیں کر سکتے"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 31c6ec4..f823fc6 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"<xliff:g id="SIMNUMBER">%d</xliff:g>-SIM karta uchun aloqa operatoringiz tomonidan vaqtinchalik faolsizlantirilgan"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobil tarmoqqa ulanib bo‘lmadi"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tarmoq turini almashtiring. Almashtirish uchun bosing."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Favqulodda chaqiruv ishlamayapti"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi‑Fi orqali favqulodda chaqiruvlar amalga oshirilmadi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Favqulodda chaqiruvlar ishlamasligi mumkin"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi orqali favqulodda chaqiruvlar bilan ishlamaydi. Batafsil."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Ogohlantirishlar"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Chaqiruvlarni uzatish"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Favqulodda qaytarib chaqirish rejimi"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Ilovaga planshetingizdagi qo‘ng‘iroq jurnallari, kiruvchi va chiquvchi qo‘ng‘rioqlar haqidagi ma’lumotlarni o‘zgartirishga ruxsat beradi. Zararli ilovalar bundan qo‘ng‘iroqlar jurnalini o‘zgartirish yoki o‘chirish uchun foydalanishi mumkin."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Ilovaga Android TV qurilmangizdagi chaqiruvlar jurnali, kirish va chiqish chaqiruvlari haqidagi axborotni oʻzgartirish huquqini beradi. Zararli ilovalar undan chaqiruvlar jurnalini oʻzgartirish yoki oʻchirish uchun foydalanishi mumkin."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Ilovaga telefoningizdagi qo‘ng‘iroq jurnallari, kiruvchi va chiquvchi qo‘ng‘rioqlar haqidagi ma’lumotlarni o‘zgartirishga ruxsat beradi. Zararli ilovalar bundan qo‘ng‘iroqlar jurnalini o‘zgartirish yoki o‘chirish uchun foydalanishi mumkin."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"tana sezgichlari (m-n, yurak urishi sensori) ma’lumotlaridan foydalanishga ruxsat"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Yurak urishi, harorat, qondagi kislorod foizi kabi tana sezgilaridan olingan maʼlumotlarga kirish."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"orqa fonda tana sezgilari (m-n, yurak urishi sensori) maʼlumotlariga kirish"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Yurak urishi, harorat, qondagi kislorod foizi kabi tana sezgilaridan olingan maʼlumotlarga orqa fonda kirish."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Foydalanish vaqtida yurak urishi kabi tanadagi sensor maʼlumotlariga ruxsat"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ilovaga yurak urishi, harorat, qondagi kislorod foizi kabi tanadagi sensor maʼlumotlaridan foydalanishga ruxsat beradi."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Fonda ishlaganda yurak urishi kabi tanadagi sensor maʼlumotlariga ruxsat"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ilovaga yurak urishi, harorat, qondagi kislorod foizi kabi tanadagi sensor maʼlumotlaridan ilova fonda ishlaganda foydalanishga ruxsat beradi."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Taqvim tadbirlari va tafsilotlarini o‘qish"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Bu ilova planshetdagi barcha taqvim tadbirlarini o‘qiy olishi hamda taqvim ma’lumotlarini ulashishi yoki saqlashi mumkin."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Bu ilova Android TV qurilmangizda barcha taqvim tadbirlarini oʻqiy olishi hamda taqvim maʼlumotlarini ulashishi yoki saqlashi mumkin."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Ilovaga audio fayllarni umumiy xotiradan oʻqish imkonini beradi."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"umumiy xotiradan video fayllarni oʻqish"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Ilovaga video fayllarni umumiy xotiradan oʻqish imkonini beradi."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"umumiy xotiradan rasmli fayllarni oʻqish"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Ilovaga rasm fayllarini umumiy xotiradan oʻqish imkonini beradi."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"umumiy xotiradan rasmli fayllarni oʻqish"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Ilovaga rasm fayllarini umumiy xotiradan oʻqish imkonini beradi."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"umumiy xotiradagi kontentlarni tahrirlash yoki oʻchirib tashlash"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Ilovaga umumiy xotiradagi kontentlarga yozish imkonini beradi."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"SIP qo‘ng‘iroqlarini amalga oshirish/qabul qilish"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Qulfdan chiqarish yoki favqulodda qo‘ng‘iroqni amalga oshirish uchun \"Menyu\"ni bosing."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Qulfni ochish uchun \"Menyu\"ga bosing."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Qulfni ochish uchun grafik kalitni chizing"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Favqulodda chaqiruv"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Favqulodda chaqiruv"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Chaqiruvga qaytish"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"To‘g‘ri!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Qaytadan urining"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Hech qachon"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Sizda ushbu sahifani ochish uchun vakolat yo‘q."</string>
<string name="text_copied" msgid="2531420577879738860">"Matn klipboardga nusxa olindi."</string>
- <string name="copied" msgid="4675902854553014676">"Nusxalandi"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> ilovasidan <xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> joylandi"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> vaqtinchalik xotiradan joyladi"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> siz nusxa olgan matnni joyladi"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Ilovaga batareya quvvatidan xohlagancha foydalanish uchun ruxsat so‘rashga imkon beradi."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"barcha paketlarni chiqarish"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Ilova oʻrnatilgan barcha paketlarni koʻrishiga ruxsat beradi"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"SupplementalApis omboriga ruxsat"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Ilovaga SupplementalApis omboriga ruxsat beradi."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"AdServices Topics API taʼminotiga ruxsat"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Ilovaga AdServices Topics API taʼminotiga kirishga ruxsat beradi."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"AdServices Attribution API taʼminotiga ruxsat"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Ilovaga AdServices Attribution API taʼminotlariga kirishga ruxsat beradi."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"AdServices Custom Audiences API taʼminotiga ruxsat"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Ilovaga AdServices Custom Audiences API taʼminotiga kirishga ruxsat beradi."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Ko‘lamini o‘zgartirish uchun ikki marta bosing"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Vidjet qo‘shilmadi."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Tanlash"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Bunga almashilmoqda: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> hisobidan chiqilmoqda…"</string>
<string name="owner_name" msgid="8713560351570795743">"Egasi"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Mehmon"</string>
<string name="error_message_title" msgid="4082495589294631966">"Xato"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Ushbu o‘zgarishni amalga oshirish uchun administrator ruxsat bermagan"</string>
<string name="app_not_found" msgid="3429506115332341800">"Ushbu amalni bajaradigan dastur topilmadi"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"O‘CHIRIB TASHLASH"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"BARIBIR OCHILSIN"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Zararli ilova aniqlandi"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Tizim jurnaliga kirish soʻrovi"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ilovasiga qurilmadagi barcha jurnal qaydlariga ruxsat berilsinmi?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Faqat shu safar"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Rad etish"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> funksional nosozliklarni tuzatish uchun tizim jurnallarini soʻramoqda. Bu jurnallarda qurilmangizdagi ilovalar va xizmatlar yozilgan maʼlumotlar boʻlishi mumkin."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Qurilma jurnaliga qurilma bilan yuz bergan hodisalar qaydlari yoziladi. Ilovalar bu jurnal qaydlari yordamida muammolarni topishi va bartaraf qilishi mumkin.\n\nAyrim jurnal qaydlarida maxfiy axborotlar yozilishi mumkin, shu sababli qurilmadagi barcha jurnal qaydlariga ruxsatni faqat ishonchli ilovalarga bering. \n\nBu ilovaga qurilmadagi barcha jurnal qaydlariga ruxsat berilmasa ham, u oʻzining jurnalini, shuningdek, qurilma ishlab chiqaruvchisi ham ayrim jurnallar yoki qurilma haqidagi axborotlarni ochishi mumkin. Batafsil"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Boshqa chiqmasin"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ilovasi <xliff:g id="APP_2">%2$s</xliff:g> ilovasidan fragmentlar ko‘rsatish uchun ruxsat so‘ramoqda"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Tahrirlash"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> uzoq vaqt orqa fonda ishlamoqda. Tekshirish uchun bosing."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Faol ilovalarni tekshiring"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Kamera bu qurilma orqali ochilmadi"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index e53546f..772a224 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Nhà mạng đã tạm thời tắt dịch vụ này đối với SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Không thể kết nối với mạng di động"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Hãy thử thay đổi mạng ưu tiên. Nhấn để thay đổi."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Không có dịch vụ gọi khẩn cấp"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Không thể thực hiện cuộc gọi khẩn cấp qua Wi‑Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Cuộc gọi khẩn cấp có thể không hoạt động"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g> không hỗ trợ cuộc gọi khẩn cấp qua Wi-Fi. Hãy nhấn để xem thông tin chi tiết."</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Thông báo"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Chuyển tiếp cuộc gọi"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Chế độ gọi lại khẩn cấp"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Cho phép ứng dụng sửa đổi nhật ký cuộc gọi trên máy tính bảng của bạn, bao gồm dữ liệu về các cuộc gọi đến và gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi nhật ký cuộc gọi của bạn."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Cho phép ứng dụng sửa đổi nhật ký cuộc gọi trên thiết bị Android TV, bao gồm cả dữ liệu về cuộc gọi đến và cuộc gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi nhật ký cuộc gọi của bạn."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Cho phép ứng dụng sửa đổi nhật ký cuộc gọi trên điện thoại của bạn, bao gồm dữ liệu về các cuộc gọi đến và gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi nhật ký cuộc gọi của bạn."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"truy cập cảm biến cơ thể (như máy đo nhịp tim)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Quyền truy cập vào dữ liệu từ các cảm biến cơ thể, chẳng hạn như dữ liệu về nhịp tim, nhiệt độ, tỷ lệ phần trăm oxy trong máu và các dữ liệu khác."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"truy cập vào các cảm biến cơ thể (như máy đo nhịp tim) khi ở trong nền"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Quyền truy cập vào dữ liệu từ các cảm biến cơ thể, chẳng hạn như dữ liệu về nhịp tim, nhiệt độ, tỷ lệ phần trăm oxy trong máu và các dữ liệu khác khi ở trong nền."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Truy cập vào dữ liệu cảm biến cơ thể khi đang dùng, chẳng hạn như nhịp tim"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Cho phép ứng dụng truy cập vào dữ liệu cảm biến cơ thể khi đang dùng, chẳng hạn như nhịp tim, thân nhiệt và tỷ lệ phần trăm oxy trong máu."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Truy cập vào dữ liệu cảm biến cơ thể khi ở chế độ nền, chẳng hạn như nhịp tim"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Cho phép ứng dụng truy cập vào dữ liệu cảm biến cơ thể khi ở chế độ nền, chẳng hạn như nhịp tim, thân nhiệt và tỷ lệ phần trăm oxy trong máu."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Đọc chi tiết và sự kiện lịch"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ứng dụng này có thể đọc tất cả các sự kiện lịch được lưu trữ trên máy tính bảng của bạn và chia sẻ hoặc lưu dữ liệu lịch của bạn."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ứng dụng này có thể đọc tất cả sự kiện trên lịch mà bạn lưu vào thiết bị Android TV cũng như chia sẻ hoặc lưu dữ liệu lịch của bạn."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Cho phép ứng dụng đọc tệp âm thanh trong bộ nhớ dùng chung."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"đọc tệp video trong bộ nhớ dùng chung"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Cho phép ứng dụng đọc tệp video trong bộ nhớ dùng chung."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"đọc tệp hình ảnh trong bộ nhớ dùng chung"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Cho phép ứng dụng đọc tệp hình ảnh trong bộ nhớ dùng chung."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"đọc tệp hình ảnh trong bộ nhớ dùng chung"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Cho phép ứng dụng đọc tệp hình ảnh trong bộ nhớ dùng chung."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"sửa đổi hoặc xóa nội dung của bộ nhớ dùng chung"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Cho phép ứng dụng ghi nội dung của bộ nhớ dùng chung."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"thực hiện/nhận các cuộc gọi qua SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Nhấn vào Menu để mở khóa hoặc thực hiện cuộc gọi khẩn cấp."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Nhấn vào Menu để mở khóa."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Vẽ hình để mở khóa"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Cuộc gọi khẩn cấp"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Khẩn cấp"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Quay lại cuộc gọi"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Chính xác!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Thử lại"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Chưa bao giờ"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Bạn không được phép mở trang này."</string>
<string name="text_copied" msgid="2531420577879738860">"Đã sao chép văn bản vào bảng nhớ tạm thời."</string>
- <string name="copied" msgid="4675902854553014676">"Đã sao chép"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> đã dán dữ liệu từ <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> đã dán dữ liệu từ bảng nhớ tạm của bạn"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> đã dán văn bản mà bạn sao chép"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Cho phép ứng dụng hỏi quyền để bỏ qua tối ưu hóa pin cho ứng dụng đó."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"truy vấn tất cả các gói"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Cho phép một ứng dụng xem tất cả các gói đã cài đặt."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"quyền truy cập vào SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Cho phép ứng dụng truy cập vào SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"truy cập vào AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Cho phép ứng dụng truy cập vào AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"truy cập vào các AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Cho phép ứng dụng truy cập vào các AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"truy cập vào AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Cho phép ứng dụng truy cập vào AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Nhấn hai lần để kiểm soát thu phóng"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Không thể thêm tiện ích."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Đến"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Đang chuyển sang <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Đang đăng xuất <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Chủ sở hữu"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Khách"</string>
<string name="error_message_title" msgid="4082495589294631966">"Lỗi"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Quản trị viên của bạn không cho phép thực hiện thay đổi này"</string>
<string name="app_not_found" msgid="3429506115332341800">"Không tìm thấy ứng dụng nào để xử lý tác vụ này"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"GỠ CÀI ĐẶT"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"VẪN MỞ"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Đã phát hiện ứng dụng độc hại"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Yêu cầu truy cập vào nhật ký hệ thống"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Cho phép <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> truy cập vào tất cả các nhật ký thiết bị?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Chỉ lần này"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Không cho phép"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> cần truy cập vào nhật ký hệ thống để gỡ lỗi về chức năng. Những nhật ký này có thể chứa thông tin mà ứng dụng và dịch vụ trên thiết bị của bạn đã ghi lại."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Nhật ký thiết bị ghi lại những hoạt động diễn ra trên thiết bị. Các ứng dụng có thể dùng nhật ký này để tìm và khắc phục sự cố.\n\nMột số nhật ký có thể chứa thông tin nhạy cảm, vì vậy, bạn chỉ nên cấp quyền truy cập vào tất cả các nhật ký thiết bị cho những ứng dụng mà mình tin cậy. \n\nNếu bạn không cho phép ứng dụng này truy cập vào tất cả các nhật ký thiết bị, ứng dụng vẫn có thể truy cập vào nhật ký của chính nó. Ngoài ra, nhà sản xuất thiết bị cũng có thể truy cập vào một số nhật ký hoặc thông tin trên thiết bị của bạn. Tìm hiểu thêm"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Không hiện lại"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> muốn hiển thị các lát của <xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Chỉnh sửa"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> đang chạy trong nền trong thời gian dài. Nhấn để xem lại."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Xem các ứng dụng đang hoạt động"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Không sử dụng được máy ảnh trên thiết bị này"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 5986cb7..b88a05d 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM 卡 <xliff:g id="SIMNUMBER">%d</xliff:g> 已由运营商暂时关闭"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"无法连接到移动网络"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"请尝试更改首选网络。点按即可更改。"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"无法使用紧急呼救服务"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"无法通过 WLAN 拨打紧急呼救电话"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"紧急呼叫服务可能无法使用"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g>并不支持通过 WLAN 进行紧急呼叫。点按可了解详情。"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"提醒"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"来电转接"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"紧急回拨模式"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"允许该应用修改平板电脑的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此清除或修改您的通话记录。"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"允许应用修改您的 Android TV 设备的通话记录,包括关于来电和去电的数据。恶意应用可能会借此清空或修改您的通话记录。"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"允许该应用修改手机的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此清除或修改您的通话记录。"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"访问身体传感器(如心率监测器)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"访问身体传感器获得的数据,例如心率、体温、血氧百分比等。"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"在后台时访问身体传感器(如心率监测器)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"在后台时访问身体传感器获得的数据,例如心率、体温、血氧百分比等。"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"允许应用在使用中时访问身体传感器数据,如心率"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"允许应用在使用中时访问身体传感器数据,如心率、体温和血氧浓度。"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"允许应用在后台运行时访问身体传感器数据,如心率"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"允许应用在后台运行时访问身体传感器数据,如心率、体温和血氧浓度。"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"读取日历活动和详情"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"此应用可读取您平板电脑上存储的所有日历活动,并分享或保存您的日历数据。"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"此应用可读取您的 Android TV 设备上存储的所有日历活动,以及分享或保存您的日历数据。"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"允许应用读取您共享存储空间中的音频文件。"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"从共享存储空间读取视频文件"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"允许应用读取您共享存储空间中的视频文件。"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"从共享存储空间读取图片文件"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"允许应用读取您共享存储空间中的图片文件。"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"读取共享存储空间中的图片文件"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"允许应用读取您共享存储空间中的图片文件。"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"修改或删除您共享存储空间中的内容"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"允许该应用写入您共享存储空间中的内容。"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"拨打/接听SIP电话"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"按 Menu 解锁或进行紧急呼救。"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"按 MENU 解锁。"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"绘制解锁图案"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"紧急呼叫"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"紧急呼救"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"返回通话"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"正确!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"重试"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"永不"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"您无权打开此网页。"</string>
<string name="text_copied" msgid="2531420577879738860">"文本已复制到剪贴板。"</string>
- <string name="copied" msgid="4675902854553014676">"已复制"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>已粘贴从<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>复制的内容"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"已将剪贴板中的内容粘贴到<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>"</string>
<string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>已粘贴您复制的文字"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"允许应用请求相应的权限,以便忽略针对该应用的电池优化。"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"查询所有软件包"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"允许应用查看所有已安装的软件包。"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"访问 SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"允许应用访问 SupplementalApis。"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"访问 AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"允许应用访问 AdServices Topics API。"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"访问 AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"允许应用访问 AdServices Attribution API。"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"访问 AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"允许应用访问 AdServices Custom Audiences API。"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"双击可以进行缩放控制"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"无法添加微件。"</string>
<string name="ime_action_go" msgid="5536744546326495436">"开始"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"正在切换为<xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"正在将<xliff:g id="NAME">%1$s</xliff:g>退出帐号…"</string>
<string name="owner_name" msgid="8713560351570795743">"机主"</string>
+ <string name="guest_name" msgid="8502103277839834324">"访客"</string>
<string name="error_message_title" msgid="4082495589294631966">"错误"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"您的管理员不允许进行这项更改"</string>
<string name="app_not_found" msgid="3429506115332341800">"找不到可处理此操作的应用"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"卸载"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"仍然打开"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"检测到有害应用"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"系统日志访问请求"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"允许“<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>”访问所有设备日志吗?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"仅限这一次"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"不允许"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>请求访问系统日志,以进行功能调试。这些日志可能包含设备上的应用和服务写入的信息。"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"设备日志会记录设备上发生的活动。应用可以使用这些日志查找和修复问题。\n\n部分日志可能包含敏感信息,因此请仅允许您信任的应用访问所有设备日志。\n\n如果您不授予此应用访问所有设备日志的权限,那么它仍然可以访问自己的日志,并且您的设备制造商可能仍然能够访问您设备上的部分日志或信息。了解详情"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"不再显示"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"“<xliff:g id="APP_0">%1$s</xliff:g>”想要显示“<xliff:g id="APP_2">%2$s</xliff:g>”图块"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"编辑"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"“<xliff:g id="APP">%1$s</xliff:g>”已在后台运行较长时间。点按即可查看。"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"查看使用中的应用"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"无法使用此设备的摄像头"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 59572ee..786d5f6 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM 卡 <xliff:g id="SIMNUMBER">%d</xliff:g> 暫時被流動網絡供應商停用"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"無法連線至流動網絡"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"請嘗試變更偏好的網絡。輕按即可變更。"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"無法撥打緊急電話"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"無法經 Wi‑Fi 撥打緊急電話"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"可能無法撥打緊急電話"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"<xliff:g id="SPN">%s</xliff:g>不支援透過 Wi-Fi 撥打緊急電話。輕按即可瞭解詳情。"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"通知"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"來電轉駁"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"緊急回撥模式"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"允許應用程式修改平板電腦的通話記錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此刪除或修改您的通話記錄。"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"允許應用程式修改 Android TV 裝置的通話記錄,包括來電和撥出電話的相關資料。惡意應用程式可能會藉此清除或修改您的通話記錄。"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"允許應用程式修改手機的通話記錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此刪除或修改您的通話記錄。"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"存取人體感應器 (例如心跳監測器)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"存取人體感應器的資料,例如心率、體溫、血氧百分比等。"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"在背景中存取人體感應器 (例如心率感應器)"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"在背景中存取人體感應器的資料,例如心率、體溫、血氧百分比等。"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"在使用時存取人體感應器資料,例如心率"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"允許應用程式在使用時存取人體感應器資料,例如心率、體溫、血氧百分比等。"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"在背景執行時存取人體感應器資料,例如心率"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"允許應用程式在背景執行時存取人體感應器資料,例如心率、體溫、血氧百分比等。"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"讀取日曆活動和詳情"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"此應用程式可以讀取所有儲存在您的平板電腦的日曆活動,並分享或儲存您的日曆資料。"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"此應用程式可以讀取所有儲存在 Android TV 裝置上的日曆活動,並分享或儲存您的日曆資料。"</string>
@@ -542,12 +542,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"允許應用程式探索並配對附近的藍牙裝置"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"連接附近的藍牙裝置"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"允許應用程式連接已配對的藍牙裝置"</string>
- <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"向附近的藍牙裝置宣傳"</string>
- <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"允許應用程式向附近的藍牙裝置宣傳"</string>
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"向附近的藍牙裝置顯示此裝置"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"允許應用程式向附近的藍牙裝置顯示此裝置"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"判斷附近超寬頻裝置之間的相對位置"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允許應用程式判斷附近超寬頻裝置之間的相對位置"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"與附近的 Wi‑Fi 裝置互動"</string>
- <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允許應用程式顯示附近 Wi-Fi 裝置的資料、與其連接並判斷其相對位置"</string>
+ <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允許應用程式向附近的 Wi-Fi 裝置顯示此裝置、連接這些裝置並判斷其相對位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"由用戶允許授權的 NFC 付款服務資訊"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得由用戶允許授權的 NFC 付款服務資訊 (如已註冊的付款輔助功能和最終付款對象)。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"允許應用程式讀取共用儲存空間中的音訊檔案。"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"讀取共用儲存空間中的影片檔案"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"允許應用程式讀取共用儲存空間中的影片檔案。"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"讀取共用儲存空間中的圖片檔案"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"允許應用程式讀取共用儲存空間中的圖片檔案。"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"讀取共用儲存空間中的圖片檔案"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"允許應用程式讀取共用儲存空間中的圖片檔案。"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"修改或刪除您共用儲存空間的內容"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"允許應用程式寫入您共用儲存空間的內容。"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"撥打/接聽 SIP 電話"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"按選單鍵解鎖或撥打緊急電話。"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"按選單鍵解鎖。"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"畫出解鎖圖形以解除鎖定螢幕"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"緊急電話"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"緊急電話"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"返回通話"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"正確!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"再試一次"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"永遠不要"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"您沒有開啟這個頁面的權限。"</string>
<string name="text_copied" msgid="2531420577879738860">"文字已複製到剪貼簿。"</string>
- <string name="copied" msgid="4675902854553014676">"已複製"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> 已貼上從 <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> 複製的資料"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」已貼上剪貼簿內容"</string>
<string name="pasted_text" msgid="4298871641549173733">"您複製的文字已貼到「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"允許應用程式要求就該應用程式忽略電池優化。"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"查詢所有套件"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"允許應用程式查看所有已安裝的套件。"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"存取 SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"允許應用程式存取 SupplementalApis。"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"存取 AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"允許應用程式存取 AdServices Topics API。"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"存取 AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"允許應用程式存取 AdServices Attribution API。"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"存取 AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"允許應用程式存取 AdServices Custom Audiences API。"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"輕觸兩下控制縮放"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"無法新增小工具。"</string>
<string name="ime_action_go" msgid="5536744546326495436">"開始"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"正在登出 <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"擁有者"</string>
+ <string name="guest_name" msgid="8502103277839834324">"訪客"</string>
<string name="error_message_title" msgid="4082495589294631966">"錯誤"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"您的管理員不允許這項變更"</string>
<string name="app_not_found" msgid="3429506115332341800">"找不到處理這項操作的應用程式"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"解除安裝"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"仍要開啟"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"偵測到有害的應用程式"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"系統記錄存取要求"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"要允許「<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>」存取所有裝置記錄嗎?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"僅限這次"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"不允許"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"「<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>」需要系統記錄才能進行功能偵錯。這些記錄可能包含裝置上應用程式和服務寫入的資料。"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"裝置記錄會記下裝置上的活動。應用程式可透過這些記錄找出並修正問題。\n\n部分記錄可能包含敏感資料,因此請只允許信任的應用程式存取所有裝置記錄。\n\n如果不允許這個應用程式存取所有裝置記錄,此應用程式仍能存取自己的記錄,且裝置製造商可能仍可存取裝置上的部分記錄或資料。瞭解詳情"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"不要再顯示"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"「<xliff:g id="APP_0">%1$s</xliff:g>」想顯示「<xliff:g id="APP_2">%2$s</xliff:g>」的快訊"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"編輯"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> 已長時間在背景執行。輕按即可查看。"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"查看使用中的應用程式"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"無法存取此裝置的相機"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index e0e03dc..afd0f92 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"SIM 卡 <xliff:g id="SIMNUMBER">%d</xliff:g> 暫時遭電信業者停用"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"無法連上行動網路"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"請嘗試變更偏好的網路。輕觸即可變更。"</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"無法撥打緊急電話"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"無法透過 Wi‑Fi 撥打緊急電話"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"可能無法撥打緊急電話"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"「<xliff:g id="SPN">%s</xliff:g>」不支援透過 Wi-Fi 撥打緊急電話。輕觸即可瞭解詳情。"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"快訊"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"來電轉接"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"緊急回撥模式"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"允許應用程式修改平板電腦的通話記錄,包括來電和已撥電話相關資料。請注意,惡意應用程式可能濫用此功能刪除或修改你的通話記錄。"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"允許應用程式修改 Android TV 裝置的通話記錄,包括來電和撥出電話相關資料。惡意應用程式可能會藉此清除或修改你的通話記錄。"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"允許應用程式修改手機的通話記錄,包括來電和已撥電話相關資料。請注意,惡意應用程式可能濫用此功能刪除或修改你的通話記錄。"</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"存取人體感應器 (例如心跳速率監測器)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"存取人體感應器的資料,例如心跳速率、體溫、血氧比例等等。"</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"在背景存取人體感應器 (例如心跳速率監測器) 的資料"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"在背景存取人體感應器的資料,例如心跳速率、體溫、血氧比例等等。"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"在使用期間可存取人體感應器資料,例如心跳速率"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"允許應用程式在使用期間存取人體感應器資料,例如心跳速率、體溫和血氧比例。"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"在背景執行時可存取人體感應器資料,例如心跳速率"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"允許應用程式在背景執行時存取人體感應器資料,例如心跳速率、體溫和血氧比例。"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"讀取日曆活動和詳細資訊"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"這個應用程式可讀取所有儲存在平板電腦上的日曆活動資訊,以及共用或儲存日曆資料。"</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"這個應用程式可讀取所有儲存在 Android TV 裝置上的日曆活動,以及共用或儲存日曆資料。"</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"允許應用程式讀取共用儲存空間中的音訊檔案。"</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"讀取共用儲存空間中的影片檔案"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"允許應用程式讀取共用儲存空間中的影片檔案。"</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"讀取共用儲存空間中的圖片檔案"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"允許應用程式讀取共用儲存空間中的圖片檔案。"</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"讀取共用儲存空間中的圖片檔案"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"允許應用程式讀取共用儲存空間中的圖片檔案。"</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"修改或刪除共用儲存空間中的內容"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"允許這個應用程式寫入共用儲存空間中的內容。"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"撥打/接聽 SIP 通話"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"按下 [Menu] 解鎖或撥打緊急電話。"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"按下 Menu 鍵解鎖。"</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"畫出解鎖圖案"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"緊急電話"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"緊急撥號"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"返回通話"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"正確!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"再試一次"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"永不"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"你沒有開啟這個頁面的權限。"</string>
<string name="text_copied" msgid="2531420577879738860">"文字已複製到剪貼簿。"</string>
- <string name="copied" msgid="4675902854553014676">"已複製"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」已貼上從「<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>」複製的資料"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"已將剪貼簿內容貼到「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」"</string>
<string name="pasted_text" msgid="4298871641549173733">"你複製的文字已貼到「<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g>」"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"允許應用程式要求權限,以便忽略針對該應用程式的電池效能最佳化設定。"</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"查詢所有套件"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"允許應用程式查看所有已安裝的套件。"</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"存取 SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"允許應用程式存取 SupplementalApis。"</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"存取 AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"允許應用程式存取 AdServices Topics API。"</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"存取 AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"允許應用程式存取 AdServices Attribution API。"</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"存取 AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"允許應用程式存取 AdServices Custom Audiences API。"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"點兩下以進行縮放控制"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"無法新增小工具。"</string>
<string name="ime_action_go" msgid="5536744546326495436">"開始"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"正在將<xliff:g id="NAME">%1$s</xliff:g>登出帳戶…"</string>
<string name="owner_name" msgid="8713560351570795743">"擁有者"</string>
+ <string name="guest_name" msgid="8502103277839834324">"訪客"</string>
<string name="error_message_title" msgid="4082495589294631966">"錯誤"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"你的管理員不允許這項變更"</string>
<string name="app_not_found" msgid="3429506115332341800">"找不到支援此操作的應用程式"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"解除安裝"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"仍要開啟"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"偵測到有害應用程式"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"系統記錄存取要求"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"要允許「<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>」存取所有裝置記錄嗎?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"僅允許這一次"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"不允許"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"「<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>」要求存取系統記錄以進行功能偵錯。這些記錄可能包含應用程式和服務在你裝置上寫入的資訊。"</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"系統會透過裝置記錄記下裝置上的活動。應用程式可以根據這些記錄找出問題並進行修正。\n\n某些記錄可能含有機密資訊,因此請勿讓不信任的應用程式存取所有裝置記錄。\n\n即使你不允許這個應用程式存取所有裝置記錄,這個應用程式仍能存取自己的記錄,而且裝置製造商或許仍可存取裝置的某些記錄或資訊。瞭解詳情"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"不要再顯示"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"「<xliff:g id="APP_0">%1$s</xliff:g>」想要顯示「<xliff:g id="APP_2">%2$s</xliff:g>」的區塊"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"編輯"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"「<xliff:g id="APP">%1$s</xliff:g>」已長時間在背景運作。輕觸即可查看。"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"查看使用中的應用程式"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"無法存取這部裝置的相機"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 336e78e..f094f12 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -85,8 +85,8 @@
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Kuvalwe okwesikhashana inkampani yakho yenethiwekhi ku-SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Ayikwazi ukufinyelela kunethiwekhi yeselula"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Zama ukushintsha inethiwekhi encanyelwayo. Thepha ukuze ushintshe."</string>
- <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Ukushaya okuphuthumayo akutholakali"</string>
- <string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Ayikwazi ukwenza amakholi aphuthumayo nge-Wi-Fi"</string>
+ <string name="EmergencyCallWarningTitle" msgid="9164532362414787774">"Amakholi aphuthumayo angase angatholakali"</string>
+ <string name="EmergencyCallWarningSummary" msgid="3365701131304664899">"I-<xliff:g id="SPN">%s</xliff:g> ayisekeli amakholi aphuthumayo nge-Wi-Fi. Thepha ukuze uthole imininingwane"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Izexwayiso"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Ukudlulisa ikholi"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Imodi yokushayela yesimo esiphuthumayo"</string>
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Ivumela uhlelo lokusebenza ukushintsha ilogi yekholi yethebulethi yakho, kufaka phakathi idatha mayelana namakholi angenayo naphumayo. Izinhlelo zikusebenza ezingalungile zingasebenzisa lokhu ukusula noma ukushintsha irekhodi lwamakholi wakho."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Ivumela uhlelo lokusebenza ukuthi liguqule ilogi yekholi yedivayisi yakho ye-Android TV, okufaka idatha emayelana namakholi angenayo naphumayo. Izinhlelo zokusebenza ezinobungozi zingasebenzisa lokhu ukususa noma ukuguqula ilogi yakho yekholi."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Ivumela uhlelo lokusebenza ukushintsha irekhodi lamakholi efoni yakho, kufaka phakathi idatha emayelana namakholi angenayo naphumayo. Izinhlelo zikusebenza ezingalungile zingasebenzisa lokhu ukusula noma ukushintsha irekhodi lwamakholi wakho."</string>
- <string name="permlab_bodySensors" msgid="3411035315357380862">"finyelela kuzinzwa zomzimba (ezifana neziqaphi zokulinganisela inhliziyo)"</string>
- <string name="permdesc_bodySensors" product="default" msgid="3208940894182188063">"Ukufinyelela kudatha kusuka kuzinzwa zomzimba ezifana nokushaya kwenhliziyo, izinga lokushisa, amaphesenti womoyampilo wegazi, njll."</string>
- <string name="permlab_bodySensors_background" msgid="4352831883331744370">"finyelela izinzwa zomzimba (njengeziqapha ukushaya kwenhliziyo) kuyilapho ingemuva"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8512392249166660872">"Ukufinyelela kudatha evela kuzinzwa zomzimba ezinjengokushaya kwenhliziyo, izinga lokushisa, amaphesenti omoyampilo wegazi, njll. kuyilapho ingemuva."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Finyelela kudatha yenzwa yomzimba, njengokushaya kwenhliziyo, ngenkathi isetshenziswa"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ivumela i-app ukuthi ifinyelele idatha yenzwa yomzimba, efana nokushaya kwenhliziyo, izinga lokushisa, namaphesenti komoyampilo wegazi, kuyilapho i-app isetshenziswa."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Finyelela kudatha yenzwa yomzimba, njengokushaya kwenhliziyo, ngenkathi ungemuva"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ivumela i-app ukuthi ifinyelele idatha yenzwa yomzimba, efana nokushaya kwenhliziyo, izinga lokushisa, namaphesenti komoyampilo wegazi, kuyilapho i-app ingemuva."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Funda imicimbi yekhalenda nemininingwane"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Lolu hlelo lokusebenza lungafunda yonke imicimbi yekhalenda elondolozwe kuthebhulethi yakho nokwabelana noma ukulondoloza idatha yakho yekhalenda."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Lolu hlelo lokusebenza lungafunda yonke imicimbi yekhalenda elondolozwe kudivayisi yakho ye-Android TV nokwabelana noma ukulondoloza idatha yakho yekhalenda."</string>
@@ -689,8 +689,8 @@
<string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Ivumela i-app ukuthi ifunde amafayela okulalelwayo kwisitoreji sakho owabelane ngaso."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"funda amafayela amavidiyo esitoreji okwabelenwe ngaso"</string>
<string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Ivumela i-app ukuthi ifunde amafayela amavidiyo kwisitoreji sakho owabelane ngaso."</string>
- <string name="permlab_readMediaImage" msgid="1507059005825769856">"funda amafayela ezithombe esitoreji okwabelenwe ngaso"</string>
- <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Ivumela i-app ukuthi ifunde amafayela ezithombe kwisitoreji sakho owabelane ngaso."</string>
+ <string name="permlab_readMediaImages" msgid="4057590631020986789">"funda amafayela womfanekiso wesitoreji okwabelenwe ngaso"</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Ivumela i-app ukuthi ifunde amafayela ezithombe kwisitoreji sakho owabelane ngaso."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"guqula noma susa okuqukethwe kwesitoreji sakho esabiwe"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Ivumela uhlelo lokusebenza ukuthi lubhale okuqukethwe kwesitoreji sakho esabiwe."</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"yenza/thola amakholi we-SIP"</string>
@@ -912,7 +912,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Chofoza Menyu ukuvula noma ukwenza ikholi ephuthumayo."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Chofoza Menyu ukuvula."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Dweba iphathini ukuvula"</string>
- <string name="lockscreen_emergency_call" msgid="7549683825868928636">"Ikholi ephuthumayo"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Isimo esiphuthumayo"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Buyela ekholini"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Lungile!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Zama futhi"</string>
@@ -1051,7 +1051,6 @@
<string name="save_password_never" msgid="6776808375903410659">"Akusoze"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Awunayo imvume yokuvula leli khasi."</string>
<string name="text_copied" msgid="2531420577879738860">"Umbhalo ukopishwe ebhodini lokunamathisela."</string>
- <string name="copied" msgid="4675902854553014676">"Kukopishiwe"</string>
<string name="pasted_from_app" msgid="5627698450808256545">"I-<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> inamathiselwe kusuka ku-<xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g>"</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"I-<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> inamathiselwe ebhodini lakho lokunamathisela"</string>
<string name="pasted_text" msgid="4298871641549173733">"U-<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> unamathisele umbhalo owukopishile"</string>
@@ -1452,8 +1451,12 @@
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Ivumela uhlelo lokusebenza ukuthi licele imvume yokuziba ukulungiselela ibhethri yalolo hlelo lokusebenza."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"buza wonke amaphakheji"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Ivumela i-app ibone wonke amaphakheji afakiwe."</string>
- <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"finyelela i-SupplementalApis"</string>
- <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"Ivumela i-application ukuba ifinyelele i-SupplementalApis."</string>
+ <string name="permlab_accessAdServicesTopics" msgid="6687112022940098945">"finyelela i-AdServices Topics API"</string>
+ <string name="permdesc_accessAdServicesTopics" msgid="6011532458156465929">"Ivumela i-app ukufinyelela i-AdServices Topics API."</string>
+ <string name="permlab_accessAdServicesAttribution" msgid="3268942271128309354">"finyelela ama-AdServices Attribution API"</string>
+ <string name="permdesc_accessAdServicesAttribution" msgid="577482544832578288">"Ivumela i-app ukufinyelela kuma-AdServices Attribution API."</string>
+ <string name="permlab_accessAdServicesCustomAudiences" msgid="7249286630514600684">"finyelela i-AdServices Custom Audiences API"</string>
+ <string name="permdesc_accessAdServicesCustomAudiences" msgid="645526926477180315">"Ivumela i-app ukufinyelela i-AdServices Custom Audiences API."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Thepha kabili ukuthola ukulawula ukusondeza"</string>
<string name="gadget_host_error_inflating" msgid="2449961590495198720">"Yehlulekile ukwengeza i-widget."</string>
<string name="ime_action_go" msgid="5536744546326495436">"Iya"</string>
@@ -1716,6 +1719,7 @@
<string name="user_switching_message" msgid="1912993630661332336">"Ishintshela ku-<xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"Iyaphuma <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="8713560351570795743">"Umnikazi"</string>
+ <string name="guest_name" msgid="8502103277839834324">"Isivakashi"</string>
<string name="error_message_title" msgid="4082495589294631966">"Iphutha"</string>
<string name="error_message_change_not_allowed" msgid="843159705042381454">"Lolu shintsho aluvunyelwe umlawuli wakho"</string>
<string name="app_not_found" msgid="3429506115332341800">"Alukho uhlelo lokusebenza olutholakele lokuphatha lesi senzo"</string>
@@ -2027,10 +2031,10 @@
<string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"KHIPHA"</string>
<string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"VULA NOMA KUNJALO"</string>
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Uhlelo lokusebenza oluyingozi lutholakele"</string>
- <string name="log_access_confirmation_title" msgid="3143035474800851565">"Isicelo sokufinyelela ilogu yesistimu"</string>
+ <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vumela i-<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ukuba ifinyelele wonke amalogu edivayisi?"</string>
<string name="log_access_confirmation_allow" msgid="143157286283302512">"Kulokhu kuphela"</string>
<string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ungavumeli"</string>
- <string name="log_access_confirmation_body" msgid="7599059550906238538">"I-<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> icela amalogu wesistimu ukuze alungise iphutha. Lawa malogu angase aqukathe ulwazi olubhalwe ama-app namasevisi kudivayisi yakho."</string>
+ <string name="log_access_confirmation_body" msgid="4483075525611652922">"Amalogu edivayisi arekhoda okwenzekayo kudivayisi yakho. Ama-app angasebenzisa lawa malogu ukuze athole futhi alungise izinkinga.\n\nAmanye amalogu angase aqukathe ulwazi olubucayi, ngakho vumela ama-app owathembayo kuphela ukuthi afinyelele wonke amalogu edivayisi. \n\nUma ungayivumeli le-app ukuthi ifinyelele wonke amalogu edivayisi, isengakwazi ukufinyelela amalogu ayo futhi umkhiqizi wedivayisi yakho usengakwazi ukufinyelela amanye amalogu noma ulwazi kudivayisi yakho. Funda kabanzi"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ungabonisi futhi"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"I-<xliff:g id="APP_0">%1$s</xliff:g> ifuna ukubonisa izingcezu ze-<xliff:g id="APP_2">%2$s</xliff:g>"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"Hlela"</string>
@@ -2265,4 +2269,6 @@
<string name="notification_content_long_running_fgs" msgid="8878031652441570178">"I-<xliff:g id="APP">%1$s</xliff:g> isebenza ngemuva isikhathi eside. Thepha ukuze ubuyekeze."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Hlola ama-app asebenzayo"</string>
<string name="vdm_camera_access_denied" msgid="6345652513729130490">"Ayikwazi ukufinyelela ikhamera kule divayisi"</string>
+ <!-- no translation found for system_locale_title (3978041860457277638) -->
+ <skip />
</resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 44c5512..323c726 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -673,6 +673,9 @@
<item type="dimen" format="float" name="lock_pattern_dot_hit_factor">0.6</item>
<!-- Width of a gradient applied to a lock pattern line while its disappearing animation. -->
<dimen name="lock_pattern_fade_away_gradient_width">8dp</dimen>
+ <!-- Parameters applied to line disappearing animation in LockPatternView in milliseconds. -->
+ <integer name="lock_pattern_line_fade_out_duration">500</integer>
+ <integer name="lock_pattern_line_fade_out_delay">150</integer>
<dimen name="text_handle_min_size">40dp</dimen>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index ffcadd0..aaf6a41 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -128,6 +128,7 @@
<public name="localeConfig" />
<public name="showBackground" />
<public name="useTargetActivityForQuickAccess"/>
+ <public name="removed_inheritKeyStoreKeys" />
<public name="preferKeepClear" />
<public name="autoHandwritingEnabled" />
<public name="fromExtendLeft" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4a2c911..34c706d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4091,21 +4091,6 @@
<!-- Description of an application permission that lets it query all other packages. [CHAR LIMIT=NONE] -->
<string name="permdesc_queryAllPackages">Allows an app to see all installed packages.</string>
- <!-- Title of an application permission that lets it access AdServices Topics API. [CHAR LIMIT=NONE] -->
- <string name="permlab_accessAdServicesTopics">access AdServices Topics API</string>
- <!-- Description of an application permission that lets it access AdServices Topics API. [CHAR LIMIT=NONE]-->
- <string name="permdesc_accessAdServicesTopics">Allows an application to access AdServices Topics API.</string>
-
- <!-- Title of an application permission that lets it access AdServices Attribution APIs. [CHAR LIMIT=NONE] -->
- <string name="permlab_accessAdServicesAttribution">access AdServices Attribution APIs</string>
- <!-- Description of an application permission that lets it access AdServices Attribution APIs. [CHAR LIMIT=NONE]-->
- <string name="permdesc_accessAdServicesAttribution">Allows an application to access AdServices Attribution APIs.</string>
-
- <!-- Title of an application permission that lets it access AdServices Custom Audiences API. [CHAR LIMIT=NONE] -->
- <string name="permlab_accessAdServicesCustomAudiences">access AdServices Custom Audiences API</string>
- <!-- Description of an application permission that lets it access AdServices Custom Audiences API. [CHAR LIMIT=NONE]-->
- <string name="permdesc_accessAdServicesCustomAudiences">Allows an application to access AdServices Custom Audiences API.</string>
-
<!-- Shown in the tutorial for tap twice for zoom control. -->
<string name="tutorial_double_tap_to_zoom_message_short">Tap twice for zoom control</string>
@@ -5479,6 +5464,8 @@
<!-- Title of the dialog shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_title"><xliff:g id="activity" example="Permission dialog">%1$s</xliff:g> unavailable</string>
+ <!-- Title of the dialog shown when the permissioncontroller is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
+ <string name="app_streaming_blocked_title_for_permission_dialog">Permission needed</string>
<!-- Message shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_message" product="tv">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your Android TV device instead.</string>
<!-- Message shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
@@ -5736,7 +5723,7 @@
<!-- Content for the log access confirmation dialog. [CHAR LIMIT=NONE]-->
<string name="log_access_confirmation_body">Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps you trust to access all device logs.
- \n\nIf you don’t allow this app to access all device logs, it can still access its own logs and your device manufacturer may still be able to access some logs or info on your device. Learn more
+ \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device. Learn more
</string>
<!-- Privacy notice do not show [CHAR LIMIT=20] -->
@@ -6292,7 +6279,9 @@
<!-- Strings for VirtualDeviceManager -->
<!-- Error message indicating the camera cannot be accessed when running on a virtual device. [CHAR LIMIT=NONE] -->
- <string name="vdm_camera_access_denied">Cannot access camera from this device</string>
+ <string name="vdm_camera_access_denied" product="default">Can’t access the phone’s camera from your <xliff:g id="device" example="Chromebook">%1$s</xliff:g></string>
+ <!-- Error message indicating the camera cannot be accessed when running on a virtual device. [CHAR LIMIT=NONE] -->
+ <string name="vdm_camera_access_denied" product="tablet">Can’t access the tablet’s camera from your <xliff:g id="device" example="Chromebook">%1$s</xliff:g></string>
<!-- Title for preference of the system default locale. [CHAR LIMIT=50]-->
<string name="system_locale_title">System language</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 845de8a..bb9142a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -550,7 +550,6 @@
<java-symbol type="string" name="activity_resolver_work_profiles_support" />
<java-symbol type="string" name="app_running_notification_title" />
<java-symbol type="string" name="app_running_notification_text" />
- <java-symbol type="string" name="copied" />
<java-symbol type="string" name="delete" />
<java-symbol type="string" name="deleteText" />
<java-symbol type="string" name="grant_permissions_header_text" />
@@ -1327,6 +1326,8 @@
<java-symbol type="dimen" name="lock_pattern_dot_size_activated" />
<java-symbol type="dimen" name="lock_pattern_dot_hit_factor" />
<java-symbol type="dimen" name="lock_pattern_fade_away_gradient_width" />
+ <java-symbol type="integer" name="lock_pattern_line_fade_out_duration" />
+ <java-symbol type="integer" name="lock_pattern_line_fade_out_delay" />
<java-symbol type="drawable" name="clock_dial" />
<java-symbol type="drawable" name="clock_hand_hour" />
<java-symbol type="drawable" name="clock_hand_minute" />
@@ -1713,6 +1714,10 @@
<java-symbol type="anim" name="activity_open_exit" />
<java-symbol type="anim" name="activity_close_enter" />
<java-symbol type="anim" name="activity_close_exit" />
+ <java-symbol type="anim" name="activity_open_enter_legacy" />
+ <java-symbol type="anim" name="activity_open_exit_legacy" />
+ <java-symbol type="anim" name="activity_close_enter_legacy" />
+ <java-symbol type="anim" name="activity_close_exit_legacy" />
<java-symbol type="anim" name="task_fragment_close_enter" />
<java-symbol type="anim" name="task_fragment_close_exit" />
<java-symbol type="anim" name="task_fragment_open_enter" />
@@ -3294,6 +3299,7 @@
<java-symbol type="string" name="app_blocked_message" />
<java-symbol type="string" name="app_streaming_blocked_title" />
+ <java-symbol type="string" name="app_streaming_blocked_title_for_permission_dialog" />
<java-symbol type="string" name="app_streaming_blocked_message" />
<!-- Used internally for assistant to launch activity transitions -->
diff --git a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
index 1f6b57e..a663095 100644
--- a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
@@ -44,7 +44,6 @@
import android.metrics.LogMaker;
import android.net.Uri;
import android.os.Bundle;
-import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
@@ -649,7 +648,7 @@
@Override
public void startActivityAsCaller(Intent intent, @Nullable Bundle options,
- IBinder permissionToken, boolean ignoreTargetSecurity, int userId) {
+ boolean ignoreTargetSecurity, int userId) {
mStartActivityIntent = intent;
mUserIdActivityLaunchedIn = userId;
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index 7ccb9d9..87c45dc 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -26,16 +26,21 @@
import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU;
import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.mock;
import android.app.ActivityManager;
import android.app.usage.NetworkStatsManager;
+import android.hardware.radio.V1_5.AccessNetwork;
import android.os.BatteryStats;
import android.os.BatteryStats.HistoryItem;
import android.os.BatteryStats.Uid.Sensor;
import android.os.Process;
import android.os.UserHandle;
import android.os.WorkSource;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.ActivityStatsTechSpecificInfo;
import android.telephony.Annotation;
import android.telephony.CellSignalStrength;
import android.telephony.DataConnectionRealTimeInfo;
@@ -56,8 +61,10 @@
import org.mockito.Mock;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.function.IntConsumer;
@@ -228,6 +235,116 @@
assertEquals(120_000, bgTime);
}
+ /**
+ * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid.
+ */
+ @SmallTest
+ public void testNoteLongPartialWakelockStart_isolatedUid() throws Exception {
+ final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
+ MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+
+
+ bi.setRecordAllHistoryLocked(true);
+ bi.forceRecordAllHistory();
+
+ int pid = 10;
+ String name = "name";
+ String historyName = "historyName";
+
+ WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain();
+ isolatedWorkChain.addNode(ISOLATED_UID, name);
+
+ // Map ISOLATED_UID to UID.
+ bi.addIsolatedUidLocked(ISOLATED_UID, UID);
+
+ bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
+ bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID);
+
+ clocks.realtime = clocks.uptime = 100;
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+
+ clocks.realtime = clocks.uptime = 220;
+ bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID);
+
+ final BatteryStatsHistoryIterator iterator =
+ bi.createBatteryStatsHistoryIterator();
+
+ BatteryStats.HistoryItem item = new BatteryStats.HistoryItem();
+
+ while (iterator.next(item)) {
+ if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break;
+ }
+ assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START);
+ assertThat(item.eventTag).isNotNull();
+ assertThat(item.eventTag.string).isEqualTo(historyName);
+ assertThat(item.eventTag.uid).isEqualTo(UID);
+
+ while (iterator.next(item)) {
+ if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break;
+ }
+ assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH);
+ assertThat(item.eventTag).isNotNull();
+ assertThat(item.eventTag.string).isEqualTo(historyName);
+ assertThat(item.eventTag.uid).isEqualTo(UID);
+ }
+
+ /**
+ * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid.
+ */
+ @SmallTest
+ public void testNoteLongPartialWakelockStart_isolatedUidRace() throws Exception {
+ final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
+ MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+
+
+ bi.setRecordAllHistoryLocked(true);
+ bi.forceRecordAllHistory();
+
+ int pid = 10;
+ String name = "name";
+ String historyName = "historyName";
+
+ WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain();
+ isolatedWorkChain.addNode(ISOLATED_UID, name);
+
+ // Map ISOLATED_UID to UID.
+ bi.addIsolatedUidLocked(ISOLATED_UID, UID);
+
+ bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
+ bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID);
+
+ clocks.realtime = clocks.uptime = 100;
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+
+ clocks.realtime = clocks.uptime = 150;
+ bi.maybeRemoveIsolatedUidLocked(ISOLATED_UID, clocks.realtime, clocks.uptime);
+
+ clocks.realtime = clocks.uptime = 220;
+ bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID);
+
+ final BatteryStatsHistoryIterator iterator =
+ bi.createBatteryStatsHistoryIterator();
+
+ BatteryStats.HistoryItem item = new BatteryStats.HistoryItem();
+
+ while (iterator.next(item)) {
+ if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break;
+ }
+ assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START);
+ assertThat(item.eventTag).isNotNull();
+ assertThat(item.eventTag.string).isEqualTo(historyName);
+ assertThat(item.eventTag.uid).isEqualTo(UID);
+
+ while (iterator.next(item)) {
+ if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break;
+ }
+ assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH);
+ assertThat(item.eventTag).isNotNull();
+ assertThat(item.eventTag.string).isEqualTo(historyName);
+ assertThat(item.eventTag.uid).isEqualTo(UID);
+ }
/**
* Test BatteryStatsImpl.noteUidProcessStateLocked.
@@ -1210,7 +1327,7 @@
}
}
- final ModemAndBatteryState state = new ModemAndBatteryState(bi, null);
+ final ModemAndBatteryState state = new ModemAndBatteryState(bi, null, null);
IntConsumer incrementTime = inc -> {
state.currentTimeMs += inc;
@@ -1357,32 +1474,16 @@
final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
for (int rat = 0; rat < ratCount; rat++) {
for (int freq = 0; freq < frequencyCount; freq++) {
- if (rat != RADIO_ACCESS_TECHNOLOGY_NR
- && freq != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
- // Only the NR RAT should have per frequency data.
- expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
- } else {
- expectedRxDurationsMs[rat][freq] = 0;
- }
expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
- expectedDurationsMs[rat][freq][txLvl] = 0;
-
- if (rat != RADIO_ACCESS_TECHNOLOGY_NR
- && freq != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
- // Only the NR RAT should have per frequency data.
- expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
- } else {
- expectedTxDurationsMs[rat][freq][txLvl] = 0;
- }
expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
}
}
}
final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, new int[txLevelCount], 0L);
- final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai);
+ final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai, null);
IntConsumer incrementTime = inc -> {
state.currentTimeMs += inc;
@@ -1599,6 +1700,288 @@
expectedTxDurationsMs, bi, state.currentTimeMs);
}
+ @SmallTest
+ public void testGetPerStateActiveRadioDurationMs_withSpecificInfoModemActivity() {
+ final MockClock clock = new MockClock(); // holds realtime and uptime in ms
+ final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
+ bi.setPowerProfile(mock(PowerProfile.class));
+ final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT;
+ final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1;
+ final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
+
+ List<ActivityStatsTechSpecificInfo> specificInfoList = new ArrayList();
+
+ final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
+ final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount];
+ final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
+ for (int rat = 0; rat < ratCount; rat++) {
+ for (int freq = 0; freq < frequencyCount; freq++) {
+ if (rat == RADIO_ACCESS_TECHNOLOGY_NR
+ || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Initialize available specific Modem info
+ specificInfoList.add(
+ new ActivityStatsTechSpecificInfo(rat, freq, new int[txLevelCount], 0));
+ }
+ expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
+
+ for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
+ expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
+ }
+ }
+ }
+
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.UNKNOWN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.GERAN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.UTRAN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.EUTRAN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.CDMA2000,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.IWLAN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
+ ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
+ ServiceState.FREQUENCY_RANGE_LOW, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
+ ServiceState.FREQUENCY_RANGE_MID, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
+ ServiceState.FREQUENCY_RANGE_HIGH, new int[txLevelCount], 0));
+ specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
+ ServiceState.FREQUENCY_RANGE_MMWAVE, new int[txLevelCount], 0));
+
+ final ActivityStatsTechSpecificInfo[] specificInfos = specificInfoList.toArray(
+ new ActivityStatsTechSpecificInfo[specificInfoList.size()]);
+ final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, specificInfos);
+ final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai, specificInfos);
+
+ IntConsumer incrementTime = inc -> {
+ state.currentTimeMs += inc;
+ clock.realtime = clock.uptime = state.currentTimeMs;
+
+ // If the device is not on battery, no timers should increment.
+ if (!state.onBattery) return;
+ // If the modem is not active, no timers should increment.
+ if (!state.modemActive) return;
+
+ final int currRat = state.currentRat;
+ final int currRant = state.currentRadioAccessNetworkType;
+ final int currFreqRange =
+ currRat == RADIO_ACCESS_TECHNOLOGY_NR ? state.currentFrequencyRange : 0;
+ int currSignalStrength = state.currentSignalStrengths.get(currRat);
+
+ expectedDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
+
+ // Evaluate the HAL provided time in states.
+ final ActivityStatsTechSpecificInfo info = state.getSpecificInfo(currRant,
+ currFreqRange);
+ switch (state.modemState) {
+ case SLEEP:
+ long sleepMs = state.modemActivityInfo.getSleepTimeMillis();
+ state.modemActivityInfo.setSleepTimeMillis(sleepMs + inc);
+ break;
+ case IDLE:
+ long idleMs = state.modemActivityInfo.getIdleTimeMillis();
+ state.modemActivityInfo.setIdleTimeMillis(idleMs + inc);
+ break;
+ case RECEIVING:
+ long rxMs = info.getReceiveTimeMillis();
+ info.setReceiveTimeMillis(rxMs + inc);
+ expectedRxDurationsMs[currRat][currFreqRange] += inc;
+ break;
+ case TRANSMITTING:
+ int[] txMs = info.getTransmitTimeMillis().clone();
+ txMs[currSignalStrength] += inc;
+ info.setTransmitTimeMillis(txMs);
+ expectedTxDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
+ break;
+ }
+ };
+
+ state.setOnBattery(false);
+ state.setModemActive(false);
+ state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN,
+ BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+ AccessNetworkConstants.AccessNetworkType.UNKNOWN);
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN);
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+ CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // While not on battery, the timers should not increase.
+ state.setModemActive(true);
+ incrementTime.accept(100);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
+ AccessNetworkConstants.AccessNetworkType.NGRAN);
+ incrementTime.accept(200);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
+ CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+ incrementTime.accept(500);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE);
+ incrementTime.accept(300);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setRatType(TelephonyManager.NETWORK_TYPE_LTE,
+ BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ AccessNetworkConstants.AccessNetworkType.EUTRAN);
+ incrementTime.accept(400);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
+ incrementTime.accept(500);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Data will now be available.
+ for (int rat = 0; rat < ratCount; rat++) {
+ for (int freq = 0; freq < frequencyCount; freq++) {
+ if (rat == RADIO_ACCESS_TECHNOLOGY_NR
+ || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Only the NR RAT should have per frequency data.
+ expectedRxDurationsMs[rat][freq] = 0;
+ }
+ for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
+ if (rat == RADIO_ACCESS_TECHNOLOGY_NR
+ || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Only the NR RAT should have per frequency data.
+ expectedTxDurationsMs[rat][freq][txLvl] = 0;
+ }
+ }
+ }
+ }
+
+ // When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should
+ // start counting up.
+ state.setOnBattery(true);
+ state.noteModemControllerActivity();
+ incrementTime.accept(300);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(500);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(600);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+ // Changing LTE signal strength should be tracked.
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_POOR);
+ incrementTime.accept(300);
+ state.setModemState(ModemState.SLEEP);
+ incrementTime.accept(1000);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(700);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
+ incrementTime.accept(800);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(222);
+ state.setModemState(ModemState.IDLE);
+ incrementTime.accept(111);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(7777);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+ incrementTime.accept(88);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(900);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_GREAT);
+ incrementTime.accept(123);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(333);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(1000);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(555);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Change in the signal strength of nonactive RAT should not affect anything.
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+ CellSignalStrength.SIGNAL_STRENGTH_POOR);
+ incrementTime.accept(631);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(321);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(99);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Changing to OTHER Rat should start tracking the poor signal strength.
+ state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA,
+ BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+ AccessNetworkConstants.AccessNetworkType.CDMA2000);
+ incrementTime.accept(1200);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Noting frequency change should not affect non NR Rat.
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH);
+ incrementTime.accept(444);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(1300);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Now the NR Rat, HIGH frequency range, good signal strength should start counting.
+ state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
+ AccessNetworkConstants.AccessNetworkType.NGRAN);
+ incrementTime.accept(1400);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Frequency changed to low.
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW);
+ incrementTime.accept(852);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(157);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(1500);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Modem no longer active, should not be tracking any more.
+ state.setModemActive(false);
+ incrementTime.accept(1500);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+ }
+
private void setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi) {
// Note that noteUidProcessStateLocked uses ActivityManager process states.
if (fgOn) {
@@ -1729,17 +2112,22 @@
public int currentNetworkDataType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
@BatteryStats.RadioAccessTechnology
public int currentRat = BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER;
+ @AccessNetworkConstants.RadioAccessNetworkType
+ public int currentRadioAccessNetworkType = AccessNetworkConstants.AccessNetworkType.UNKNOWN;
@ServiceState.FrequencyRange
public int currentFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
public SparseIntArray currentSignalStrengths = new SparseIntArray();
public ModemState modemState = ModemState.SLEEP;
public ModemActivityInfo modemActivityInfo;
+ public ActivityStatsTechSpecificInfo[] specificInfo;
private final MockBatteryStatsImpl mBsi;
- ModemAndBatteryState(MockBatteryStatsImpl bsi, ModemActivityInfo mai) {
+ ModemAndBatteryState(MockBatteryStatsImpl bsi, ModemActivityInfo mai,
+ ActivityStatsTechSpecificInfo[] astsi) {
mBsi = bsi;
modemActivityInfo = mai;
+ specificInfo = astsi;
}
void setOnBattery(boolean onBattery) {
@@ -1759,6 +2147,13 @@
}
void setRatType(@Annotation.NetworkType int dataType,
+ @BatteryStats.RadioAccessTechnology int rat,
+ @AccessNetworkConstants.RadioAccessNetworkType int halDataType) {
+ currentRadioAccessNetworkType = halDataType;
+ setRatType(dataType, rat);
+ }
+
+ void setRatType(@Annotation.NetworkType int dataType,
@BatteryStats.RadioAccessTechnology int rat) {
currentNetworkDataType = dataType;
currentRat = rat;
@@ -1783,13 +2178,45 @@
modemState = state;
}
+ ActivityStatsTechSpecificInfo getSpecificInfo(@BatteryStats.RadioAccessTechnology int rat,
+ @ServiceState.FrequencyRange int frequency) {
+ if (specificInfo == null) return null;
+ for (ActivityStatsTechSpecificInfo info : specificInfo) {
+ if (info.getRat() == rat && info.getFrequencyRange() == frequency) {
+ return info;
+ }
+ }
+ return null;
+ }
+
void noteModemControllerActivity() {
if (modemActivityInfo == null) return;
modemActivityInfo.setTimestamp(currentTimeMs);
- ModemActivityInfo copy = new ModemActivityInfo(modemActivityInfo.getTimestampMillis(),
- modemActivityInfo.getSleepTimeMillis(), modemActivityInfo.getIdleTimeMillis(),
- modemActivityInfo.getTransmitTimeMillis().clone(),
- modemActivityInfo.getReceiveTimeMillis());
+ final ModemActivityInfo copy;
+ if (specificInfo == null) {
+ copy = new ModemActivityInfo(
+ modemActivityInfo.getTimestampMillis(),
+ modemActivityInfo.getSleepTimeMillis(),
+ modemActivityInfo.getIdleTimeMillis(),
+ modemActivityInfo.getTransmitTimeMillis().clone(),
+ modemActivityInfo.getReceiveTimeMillis());
+ } else {
+ // Deep copy specificInfo
+ final ActivityStatsTechSpecificInfo[] infoCopies =
+ new ActivityStatsTechSpecificInfo[specificInfo.length];
+ for (int i = 0; i < specificInfo.length; i++) {
+ final ActivityStatsTechSpecificInfo info = specificInfo[i];
+ infoCopies[i] = new ActivityStatsTechSpecificInfo(info.getRat(),
+ info.getFrequencyRange(), info.getTransmitTimeMillis().clone(),
+ (int) info.getReceiveTimeMillis());
+ }
+
+ copy = new ModemActivityInfo(
+ modemActivityInfo.getTimestampMillis(),
+ modemActivityInfo.getSleepTimeMillis(),
+ modemActivityInfo.getIdleTimeMillis(),
+ infoCopies);
+ }
mBsi.noteModemControllerActivity(copy, POWER_DATA_UNAVAILABLE,
currentTimeMs, currentTimeMs, mNetworkStatsManager);
}
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index bde18f3..6b66fad 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -613,12 +613,6 @@
"group": "WM_DEBUG_CONFIGURATION",
"at": "com\/android\/server\/wm\/ActivityStarter.java"
},
- "-1488852351": {
- "message": "Task=%d contains embedded TaskFragment in untrusted mode. Disabled all input during TaskFragment remote animation.",
- "level": "DEBUG",
- "group": "WM_DEBUG_APP_TRANSITIONS",
- "at": "com\/android\/server\/wm\/AppTransitionController.java"
- },
"-1483435730": {
"message": "InsetsSource setWin %s for type %s",
"level": "DEBUG",
@@ -3439,12 +3433,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "1333520287": {
- "message": "Creating PendingTransition: %s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_WINDOW_TRANSITIONS",
- "at": "com\/android\/server\/wm\/TransitionController.java"
- },
"1335791109": {
"message": "createSurface %s: mDrawState=DRAW_PENDING",
"level": "INFO",
@@ -3739,6 +3727,12 @@
"group": "WM_DEBUG_IME",
"at": "com\/android\/server\/wm\/InsetsStateController.java"
},
+ "1667162379": {
+ "message": "Creating Pending Transition: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/WindowOrganizerController.java"
+ },
"1670933628": {
"message": " Setting allReady override",
"level": "VERBOSE",
@@ -3793,6 +3787,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "1730300180": {
+ "message": "PendingStartTransaction found",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_SYNC_ENGINE",
+ "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
+ },
"1739298851": {
"message": "removeWindowToken: Attempted to remove token: %s for non-exiting displayId=%d",
"level": "WARN",
@@ -4105,12 +4105,6 @@
"group": "WM_DEBUG_BOOT",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "2034988903": {
- "message": "PendingStartTransaction found",
- "level": "VERBOSE",
- "group": "WM_DEBUG_WINDOW_TRANSITIONS",
- "at": "com\/android\/server\/wm\/WindowOrganizerController.java"
- },
"2039056415": {
"message": "Found matching affinity candidate!",
"level": "DEBUG",
@@ -4165,6 +4159,12 @@
"group": "WM_DEBUG_KEEP_SCREEN_ON",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "2100457473": {
+ "message": "Task=%d contains embedded TaskFragment. Disabled all input during TaskFragment remote animation.",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
"2114149926": {
"message": "Not removing %s because app died while it's visible",
"level": "VERBOSE",
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index bd0e56a..c81473d 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -416,6 +416,8 @@
key usage 0x0c006F BRIGHTNESS_UP
key usage 0x0c0070 BRIGHTNESS_DOWN
key usage 0x0c0173 MEDIA_AUDIO_TRACK
+key usage 0x0c019C PROFILE_SWITCH
+key usage 0x0c01A2 ALL_APPS
# Joystick and game controller axes.
# Axes that are not mapped will be assigned generic axis numbers by the input subsystem.
diff --git a/data/keyboards/Vendor_0957_Product_0001.kl b/data/keyboards/Vendor_0957_Product_0001.kl
index 672abef..13b4096 100644
--- a/data/keyboards/Vendor_0957_Product_0001.kl
+++ b/data/keyboards/Vendor_0957_Product_0001.kl
@@ -44,6 +44,8 @@
key 11 0
# custom keys
+key usage 0x000c019C PROFILE_SWITCH
+key usage 0x000c01A2 ALL_APPS
key usage 0x000c01BB TV_INPUT
key usage 0x000c022A BOOKMARK
key usage 0x000c0096 SETTINGS
@@ -53,6 +55,7 @@
key usage 0x000c009C CHANNEL_UP
key usage 0x000c009D CHANNEL_DOWN
key usage 0x000c00CD MEDIA_PLAY_PAUSE
+key usage 0x000c00B2 MEDIA_RECORD
key usage 0x000c00B4 MEDIA_SKIP_BACKWARD
key usage 0x000c00B3 MEDIA_SKIP_FORWARD
key usage 0x000c0226 MEDIA_STOP
@@ -62,6 +65,7 @@
key usage 0x000c0079 BUTTON_6 WAKE #Disney+
key usage 0x000c007A BUTTON_7 WAKE #HBOmax
+key usage 0x00070037 PERIOD
key usage 0x000c01BD INFO
key usage 0x000c0061 CAPTIONS
key usage 0x000c0185 TV_TELETEXT
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index fd4bed1..7cc22d7 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -849,6 +849,14 @@
nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
}
+ /**
+ * Force the new frame to draw, ensuring the UI draw request will attempt a draw this vsync.
+ * @hide
+ */
+ public void forceDrawNextFrame() {
+ nForceDrawNextFrame(mNativeProxy);
+ }
+
/** @hide */
public void setPictureCaptureCallback(@Nullable PictureCapturedCallback callback) {
nSetPictureCaptureCallback(mNativeProxy, callback);
@@ -976,12 +984,12 @@
}
/**
- * b/68769804: For low FPS experiments.
+ * b/68769804, b/66945974: For low FPS experiments.
*
* @hide
*/
public static void setFPSDivisor(int divisor) {
- nHackySetRTAnimationsEnabled(divisor <= 1);
+ nSetRtAnimationsEnabled(divisor <= 1);
}
/**
@@ -1145,6 +1153,16 @@
nSetDrawingEnabled(drawingEnabled);
}
+ /**
+ * Disable RenderThread animations that schedule draws directly from RenderThread. This is used
+ * when we don't want to de-schedule draw requests that come from the UI thread.
+ *
+ * @hide
+ */
+ public static void setRtAnimationsEnabled(boolean enabled) {
+ nSetRtAnimationsEnabled(enabled);
+ }
+
private static final class DestroyContextRunnable implements Runnable {
private final long mNativeInstance;
@@ -1423,6 +1441,8 @@
private static native void nSetContentDrawBounds(long nativeProxy, int left,
int top, int right, int bottom);
+ private static native void nForceDrawNextFrame(long nativeProxy);
+
private static native void nSetPictureCaptureCallback(long nativeProxy,
PictureCapturedCallback callback);
@@ -1451,9 +1471,6 @@
private static native void nSetHighContrastText(boolean enabled);
- // For temporary experimentation b/66945974
- private static native void nHackySetRTAnimationsEnabled(boolean enabled);
-
private static native void nSetDebuggingEnabled(boolean enabled);
private static native void nSetIsolatedProcess(boolean enabled);
@@ -1472,4 +1489,6 @@
private static native void nSetDrawingEnabled(boolean drawingEnabled);
private static native boolean nIsDrawingEnabled();
+
+ private static native void nSetRtAnimationsEnabled(boolean rtAnimationsEnabled);
}
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index 05fb4c3..919a93b 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -20,7 +20,6 @@
import android.annotation.Nullable;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
-import android.security.keystore.KeyProperties;
import android.security.maintenance.IKeystoreMaintenance;
import android.system.keystore2.Domain;
import android.system.keystore2.KeyDescriptor;
@@ -158,11 +157,6 @@
* Migrates a key given by the source descriptor to the location designated by the destination
* descriptor.
*
- * If Domain::APP is selected in either source or destination, nspace must be set to
- * {@link KeyProperties#NAMESPACE_APPLICATION}, implying the caller's UID.
- * If the caller has the MIGRATE_ANY_KEY permission, Domain::APP may be used with
- * other nspace values which then indicates the UID of a different application.
- *
* @param source - The key to migrate may be specified by Domain.APP, Domain.SELINUX, or
* Domain.KEY_ID. The caller needs the permissions use, delete, and grant for the
* source namespace.
@@ -189,20 +183,4 @@
return SYSTEM_ERROR;
}
}
-
- /**
- * @see IKeystoreMaintenance#listEntries(int, long)
- */
- @Nullable
- public static KeyDescriptor[] listEntries(int domain, long nspace) {
- try {
- return getService().listEntries(domain, nspace);
- } catch (ServiceSpecificException e) {
- Log.e(TAG, "listEntries failed", e);
- return null;
- } catch (Exception e) {
- Log.e(TAG, "Can not connect to keystore", e);
- return null;
- }
- }
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
index 1c49881..921552b 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
@@ -236,7 +236,8 @@
}
private static void assertValidState(@Nullable Integer state) {
- if (state != null && state != COMMON_STATE_FLAT && state != COMMON_STATE_HALF_OPENED) {
+ if (state != null && state != COMMON_STATE_FLAT
+ && state != COMMON_STATE_HALF_OPENED && state != COMMON_STATE_UNKNOWN) {
throw new IllegalArgumentException("Invalid state: " + state
+ "must be either COMMON_STATE_FLAT or COMMON_STATE_HALF_OPENED");
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
index e9d213e..0e696eb 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java
@@ -16,6 +16,8 @@
package androidx.window.common;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT;
+import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN;
import static androidx.window.common.CommonFoldingFeature.parseListFromString;
@@ -42,7 +44,10 @@
public final class SettingsDisplayFeatureProducer
extends BaseDataProducer<List<CommonFoldingFeature>> {
private static final String DISPLAY_FEATURES = "display_features";
+ private static final String DEVICE_POSTURE = "device_posture";
+ private final Uri mDevicePostureUri =
+ Settings.Global.getUriFor(DEVICE_POSTURE);
private final Uri mDisplayFeaturesUri =
Settings.Global.getUriFor(DISPLAY_FEATURES);
@@ -55,6 +60,15 @@
mObserver = new SettingsObserver();
}
+ private int getPosture() {
+ int posture = Settings.Global.getInt(mResolver, DEVICE_POSTURE, COMMON_STATE_UNKNOWN);
+ if (posture == COMMON_STATE_HALF_OPENED || posture == COMMON_STATE_FLAT) {
+ return posture;
+ } else {
+ return COMMON_STATE_UNKNOWN;
+ }
+ }
+
@Override
@NonNull
public Optional<List<CommonFoldingFeature>> getData() {
@@ -66,7 +80,7 @@
if (TextUtils.isEmpty(displayFeaturesString)) {
return Optional.of(Collections.emptyList());
}
- return Optional.of(parseListFromString(displayFeaturesString, COMMON_STATE_UNKNOWN));
+ return Optional.of(parseListFromString(displayFeaturesString, getPosture()));
}
/**
@@ -80,6 +94,7 @@
mRegisteredObservers = true;
mResolver.registerContentObserver(mDisplayFeaturesUri, false /* notifyForDescendants */,
mObserver /* ContentObserver */);
+ mResolver.registerContentObserver(mDevicePostureUri, false, mObserver);
}
/**
@@ -101,7 +116,7 @@
@Override
public void onChange(boolean selfChange, Uri uri) {
- if (mDisplayFeaturesUri.equals(uri)) {
+ if (mDisplayFeaturesUri.equals(uri) || mDevicePostureUri.equals(uri)) {
notifyDataChanged();
}
}
diff --git a/libs/WindowManager/Jetpack/tests/OWNERS b/libs/WindowManager/Jetpack/tests/OWNERS
new file mode 100644
index 0000000..f2c3388
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 909476
+# includes OWNERS from parent directories
+charlesccchen@google.com
+diegovela@google.com
diff --git a/libs/WindowManager/Jetpack/tests/unittest/Android.bp b/libs/WindowManager/Jetpack/tests/unittest/Android.bp
new file mode 100644
index 0000000..62e8128
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/Android.bp
@@ -0,0 +1,52 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+ name: "WMJetpackUnitTests",
+
+ srcs: [
+ "**/*.java",
+ ],
+
+ static_libs: [
+ "androidx.window.extensions",
+ "junit",
+ "androidx.test.runner",
+ "androidx.test.rules",
+ "androidx.test.ext.junit",
+ "mockito-target-extended-minus-junit4",
+ "truth-prebuilt",
+ "testables",
+ "platform-test-annotations",
+ ],
+
+ libs: [
+ "android.test.mock",
+ "android.test.base",
+ "android.test.runner",
+ ],
+
+ optimize: {
+ enabled: false,
+ },
+}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/AndroidManifest.xml b/libs/WindowManager/Jetpack/tests/unittest/AndroidManifest.xml
new file mode 100644
index 0000000..b12b6f6
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="androidx.window.tests">
+
+ <application android:debuggable="true" android:largeHeap="true">
+ <uses-library android:name="android.test.mock" />
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:label="Tests for WindowManager Jetpack library"
+ android:targetPackage="androidx.window.tests">
+ </instrumentation>
+</manifest>
diff --git a/libs/WindowManager/Jetpack/tests/unittest/AndroidTest.xml b/libs/WindowManager/Jetpack/tests/unittest/AndroidTest.xml
new file mode 100644
index 0000000..56d8c33
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs Tests for WindowManager Jetpack library">
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="install-arg" value="-t" />
+ <option name="test-file-name" value="WMJetpackUnitTests.apk" />
+ </target_preparer>
+
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="framework-base-presubmit" />
+ <option name="test-tag" value="WMJetpackUnitTests" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="androidx.window.tests" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration>
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
new file mode 100644
index 0000000..b6df876
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window.extensions;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WindowExtensionsTest {
+ private WindowExtensions mExtensions;
+
+ @Before
+ public void setUp() {
+ mExtensions = WindowExtensionsProvider.getWindowExtensions();
+ }
+
+ @Test
+ public void testGetWindowLayoutComponent() {
+ assertThat(mExtensions.getWindowLayoutComponent()).isNotNull();
+ }
+
+ @Test
+ public void testGetActivityEmbeddingComponent() {
+ assertThat(mExtensions.getActivityEmbeddingComponent()).isNotNull();
+ }
+}
diff --git a/libs/WindowManager/Shell/res/layout/bubble_stack_user_education.xml b/libs/WindowManager/Shell/res/layout/bubble_stack_user_education.xml
index 87deb8b..5c8c84c 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_stack_user_education.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_stack_user_education.xml
@@ -21,8 +21,8 @@
android:layout_width="wrap_content"
android:paddingTop="48dp"
android:paddingBottom="48dp"
- android:paddingEnd="16dp"
- android:layout_marginEnd="24dp"
+ android:paddingEnd="@dimen/bubble_user_education_padding_end"
+ android:layout_marginEnd="@dimen/bubble_user_education_margin_end"
android:orientation="vertical"
android:background="@drawable/bubble_stack_user_education_bg"
>
diff --git a/libs/WindowManager/Shell/res/layout/bubbles_manage_button_education.xml b/libs/WindowManager/Shell/res/layout/bubbles_manage_button_education.xml
index fafe40e..b28f58f 100644
--- a/libs/WindowManager/Shell/res/layout/bubbles_manage_button_education.xml
+++ b/libs/WindowManager/Shell/res/layout/bubbles_manage_button_education.xml
@@ -23,8 +23,8 @@
android:clickable="true"
android:paddingTop="28dp"
android:paddingBottom="16dp"
- android:paddingEnd="48dp"
- android:layout_marginEnd="24dp"
+ android:paddingEnd="@dimen/bubble_user_education_padding_end"
+ android:layout_marginEnd="@dimen/bubble_user_education_margin_end"
android:orientation="vertical"
android:background="@drawable/bubble_stack_user_education_bg"
>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index ad38975..59d03c7 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -205,8 +205,15 @@
<dimen name="bubble_dismiss_target_padding_x">40dp</dimen>
<dimen name="bubble_dismiss_target_padding_y">20dp</dimen>
<dimen name="bubble_manage_menu_elevation">4dp</dimen>
- <!-- Size of user education views on large screens (phone is just match parent). -->
- <dimen name="bubbles_user_education_width_large_screen">400dp</dimen>
+ <!-- Size of manage user education views on large screens or in landscape. -->
+ <dimen name="bubbles_user_education_width">480dp</dimen>
+ <!-- Margin applied to the end of the user education views (really only matters for phone
+ since the width is match parent). -->
+ <dimen name="bubble_user_education_margin_end">24dp</dimen>
+ <!-- Padding applied to the end of the user education view. -->
+ <dimen name="bubble_user_education_padding_end">58dp</dimen>
+ <!-- Padding between the bubble and the user education text. -->
+ <dimen name="bubble_user_education_stack_padding">16dp</dimen>
<!-- Bottom and end margin for compat buttons. -->
<dimen name="compat_button_margin">16dp</dimen>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
index ca4ef07..d28a68a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
@@ -88,7 +88,7 @@
private boolean mIsInitialized;
private Listener mListener;
private Executor mListenerExecutor;
- private Rect mObscuredTouchRect;
+ private Region mObscuredTouchRegion;
private final Rect mTmpRect = new Rect();
private final Rect mTmpRootRect = new Rect();
@@ -202,7 +202,16 @@
* @param obscuredRect the obscured region of the view.
*/
public void setObscuredTouchRect(Rect obscuredRect) {
- mObscuredTouchRect = obscuredRect;
+ mObscuredTouchRegion = obscuredRect != null ? new Region(obscuredRect) : null;
+ }
+
+ /**
+ * Indicates a region of the view that is not touchable.
+ *
+ * @param obscuredRegion the obscured region of the view.
+ */
+ public void setObscuredTouchRegion(Region obscuredRegion) {
+ mObscuredTouchRegion = obscuredRegion;
}
private void onLocationChanged(WindowContainerTransaction wct) {
@@ -468,8 +477,8 @@
mTmpLocation[0] + getWidth(), mTmpLocation[1] + getHeight());
inoutInfo.touchableRegion.op(mTmpRect, Region.Op.DIFFERENCE);
- if (mObscuredTouchRect != null) {
- inoutInfo.touchableRegion.union(mObscuredTouchRect);
+ if (mObscuredTouchRegion != null) {
+ inoutInfo.touchableRegion.op(mObscuredTouchRegion, Region.Op.UNION);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index da8308e..10ff2fb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -692,6 +692,7 @@
* @param bubblePosition the x position of the bubble if showing on top, the y position of
* the bubble if showing vertically.
* @param onLeft whether the stack was on the left side of the screen when expanded.
+ * @param animate whether the pointer should animate to this position.
*/
public void setPointerPosition(float bubblePosition, boolean onLeft, boolean animate) {
// Pointer gets drawn in the padding
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 8a120b9..97e5ee3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -579,11 +579,10 @@
// Showing vertically: might need to translate the bubbles above the IME.
// Subtract spacing here to provide a margin between top of IME and bottom of bubble row.
- final float bottomInset = getImeHeight() + mInsets.bottom - (mSpacingBetweenBubbles * 2);
+ final float bottomHeight = getImeHeight() + mInsets.bottom - (mSpacingBetweenBubbles * 2);
+ final float bottomInset = mScreenRect.bottom - bottomHeight;
final float expandedStackSize = getExpandedStackSize(numberOfBubbles);
- final float centerPosition = showBubblesVertically()
- ? mPositionRect.centerY()
- : mPositionRect.centerX();
+ final float centerPosition = mPositionRect.centerY();
final float rowBottom = centerPosition + (expandedStackSize / 2f);
final float rowTop = centerPosition - (expandedStackSize / 2f);
float rowTopForIme = rowTop;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 677c1c7..3319411 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -899,7 +899,7 @@
mStackAnimationController.updateResources();
mBubbleOverflow.updateResources();
- if (mRelativeStackPositionBeforeRotation != null) {
+ if (!isStackEduShowing() && mRelativeStackPositionBeforeRotation != null) {
mStackAnimationController.setStackPosition(
mRelativeStackPositionBeforeRotation);
mRelativeStackPositionBeforeRotation = null;
@@ -1139,6 +1139,7 @@
// The menu itself should respect locale direction so the icons are on the correct side.
mManageMenu.setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
addView(mManageMenu);
+ updateManageButtonListener();
}
/**
@@ -1200,6 +1201,8 @@
addView(mStackEduView);
}
mBubbleContainer.bringToFront();
+ // Ensure the stack is in the correct spot
+ mStackAnimationController.setStackPosition(mPositioner.getDefaultStartPosition());
return mStackEduView.show(mPositioner.getDefaultStartPosition());
}
@@ -1214,6 +1217,8 @@
mStackEduView = new StackEducationView(mContext, mPositioner, mBubbleController);
addView(mStackEduView);
mBubbleContainer.bringToFront(); // Stack appears on top of the stack education
+ // Ensure the stack is in the correct spot
+ mStackAnimationController.setStackPosition(mPositioner.getDefaultStartPosition());
mStackEduView.show(mPositioner.getDefaultStartPosition());
}
if (mManageEduView != null && mManageEduView.getVisibility() == VISIBLE) {
@@ -1311,7 +1316,6 @@
/** Respond to the display size change by recalculating view size and location. */
public void onDisplaySizeChanged() {
updateOverflow();
- setUpManageMenu();
setUpFlyout();
setUpDismissView();
updateUserEdu();
@@ -1331,13 +1335,16 @@
mStackAnimationController.updateResources();
mDismissView.updateResources();
mMagneticTarget.setMagneticFieldRadiusPx(mBubbleSize * 2);
- mStackAnimationController.setStackPosition(
- new RelativeStackPosition(
- mPositioner.getRestingPosition(),
- mStackAnimationController.getAllowableStackPositionRegion()));
+ if (!isStackEduShowing()) {
+ mStackAnimationController.setStackPosition(
+ new RelativeStackPosition(
+ mPositioner.getRestingPosition(),
+ mStackAnimationController.getAllowableStackPositionRegion()));
+ }
if (mIsExpanded) {
updateExpandedView();
}
+ setUpManageMenu();
}
@Override
@@ -2808,7 +2815,7 @@
// a race condition with adding the BubbleExpandedView view to the expanded view
// container. Due to the race condition the click handler sometimes is not set up
// correctly and is never called.
- bev.setManageClickListener((view) -> showManageMenu(true /* show */));
+ updateManageButtonListener();
}, 0);
if (!mIsExpansionAnimating) {
@@ -2819,6 +2826,16 @@
}
}
+ private void updateManageButtonListener() {
+ if (mIsExpanded && mExpandedBubble != null
+ && mExpandedBubble.getExpandedView() != null) {
+ BubbleExpandedView bev = mExpandedBubble.getExpandedView();
+ bev.setManageClickListener((view) -> {
+ showManageMenu(true /* show */);
+ });
+ }
+ }
+
/**
* Requests a snapshot from the currently expanded bubble's TaskView and displays it in a
* SurfaceView. This allows us to load a newly expanded bubble's Activity into the TaskView,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ManageEducationView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ManageEducationView.kt
index eb4737a..c09d1e0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ManageEducationView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ManageEducationView.kt
@@ -101,9 +101,8 @@
bubbleExpandedView = expandedView
expandedView.taskView?.setObscuredTouchRect(Rect(positioner.screenRect))
- layoutParams.width = if (positioner.isLargeScreen)
- context.resources.getDimensionPixelSize(
- R.dimen.bubbles_user_education_width_large_screen)
+ layoutParams.width = if (positioner.isLargeScreen || positioner.isLandscape)
+ context.resources.getDimensionPixelSize(R.dimen.bubbles_user_education_width)
else ViewGroup.LayoutParams.MATCH_PARENT
alpha = 0f
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
index 3846de7..1ff4be8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
@@ -122,28 +122,29 @@
* If necessary, shows the user education view for the bubble stack. This appears the first
* time a user taps on a bubble.
*
- * @return true if user education was shown, false otherwise.
+ * @return true if user education was shown and wasn't showing before, false otherwise.
*/
fun show(stackPosition: PointF): Boolean {
isHiding = false
if (visibility == VISIBLE) return false
controller.updateWindowFlagsForBackpress(true /* interceptBack */)
- layoutParams.width = if (positioner.isLargeScreen)
- context.resources.getDimensionPixelSize(
- R.dimen.bubbles_user_education_width_large_screen)
+ layoutParams.width = if (positioner.isLargeScreen || positioner.isLandscape)
+ context.resources.getDimensionPixelSize(R.dimen.bubbles_user_education_width)
else ViewGroup.LayoutParams.MATCH_PARENT
+ val stackPadding = context.resources.getDimensionPixelSize(
+ R.dimen.bubble_user_education_stack_padding)
setAlpha(0f)
setVisibility(View.VISIBLE)
post {
requestFocus()
with(view) {
if (resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR) {
- setPadding(positioner.bubbleSize + paddingRight, paddingTop, paddingRight,
+ setPadding(positioner.bubbleSize + stackPadding, paddingTop, paddingRight,
paddingBottom)
} else {
- setPadding(paddingLeft, paddingTop, positioner.bubbleSize + paddingLeft,
+ setPadding(paddingLeft, paddingTop, positioner.bubbleSize + stackPadding,
paddingBottom)
}
translationY = stackPosition.y + positioner.bubbleSize / 2 - getHeight() / 2
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
index 8d1afa4..d5875c0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
@@ -343,15 +343,13 @@
@Override
public void resized(ClientWindowFrames frames, boolean reportDraw,
- MergedConfiguration newMergedConfiguration, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId, int syncSeqId, int resizeMode) {}
-
- @Override
- public void insetsChanged(InsetsState insetsState, boolean willMove, boolean willResize) {}
+ MergedConfiguration newMergedConfiguration, InsetsState insetsState,
+ boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, int syncSeqId,
+ int resizeMode) {}
@Override
public void insetsControlChanged(InsetsState insetsState,
- InsetsSourceControl[] activeControls, boolean willMove, boolean willResize) {}
+ InsetsSourceControl[] activeControls) {}
@Override
public void showInsets(int types, boolean fromIme) {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
index a10ee6a..3ac7cbf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
@@ -124,6 +124,9 @@
/** Releases the surfaces for split decor. */
public void release(SurfaceControl.Transaction t) {
+ if (mFadeAnimator != null && mFadeAnimator.isRunning()) {
+ mFadeAnimator.cancel();
+ }
if (mViewHost != null) {
mViewHost.release();
mViewHost = null;
@@ -139,6 +142,8 @@
mHostLeash = null;
mIcon = null;
mResizingIconView = null;
+ mIsResizing = false;
+ mShown = false;
}
/** Showing resizing hint. */
@@ -181,13 +186,13 @@
if (mFadeAnimator != null && mFadeAnimator.isRunning()) {
mFadeAnimator.cancel();
}
- startFadeAnimation(show, false /* releaseLeash */);
+ startFadeAnimation(show, false /* isResized */);
mShown = show;
}
}
/** Stops showing resizing hint. */
- public void onResized(Rect newBounds, SurfaceControl.Transaction t) {
+ public void onResized(SurfaceControl.Transaction t) {
if (mResizingIconView == null) {
return;
}
@@ -200,7 +205,7 @@
mFadeAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- releaseLeash(finishT);
+ releaseDecor(finishT);
finishT.apply();
finishT.close();
}
@@ -212,22 +217,25 @@
mFadeAnimator.cancel();
}
if (mShown) {
- startFadeAnimation(false /* show */, true /* releaseLeash */);
- mShown = false;
+ startFadeAnimation(false /* show */, true /* isResized */);
} else {
- // Surface is hidden so release it directly.
- releaseLeash(t);
+ // Decor surface is hidden so release it directly.
+ releaseDecor(t);
}
}
- private void startFadeAnimation(boolean show, boolean releaseLeash) {
+ private void startFadeAnimation(boolean show, boolean isResized) {
final SurfaceControl.Transaction animT = new SurfaceControl.Transaction();
mFadeAnimator = ValueAnimator.ofFloat(0f, 1f);
mFadeAnimator.setDuration(FADE_DURATION);
mFadeAnimator.addUpdateListener(valueAnimator-> {
final float progress = (float) valueAnimator.getAnimatedValue();
- animT.setAlpha(mBackgroundLeash, show ? progress : 1 - progress);
- animT.setAlpha(mIconLeash, show ? progress : 1 - progress);
+ if (mBackgroundLeash != null) {
+ animT.setAlpha(mBackgroundLeash, show ? progress : 1 - progress);
+ }
+ if (mIconLeash != null) {
+ animT.setAlpha(mIconLeash, show ? progress : 1 - progress);
+ }
animT.apply();
});
mFadeAnimator.addListener(new AnimatorListenerAdapter() {
@@ -241,19 +249,25 @@
@Override
public void onAnimationEnd(@NonNull Animator animation) {
if (!show) {
- animT.hide(mBackgroundLeash).hide(mIconLeash).apply();
+ if (mBackgroundLeash != null) {
+ animT.hide(mBackgroundLeash);
+ }
+ if (mIconLeash != null) {
+ animT.hide(mIconLeash);
+ }
}
- if (releaseLeash) {
- releaseLeash(animT);
- animT.apply();
+ if (isResized) {
+ releaseDecor(animT);
}
+ animT.apply();
animT.close();
}
});
mFadeAnimator.start();
}
- private void releaseLeash(SurfaceControl.Transaction t) {
+ /** Release or hide decor hint. */
+ private void releaseDecor(SurfaceControl.Transaction t) {
if (mBackgroundLeash != null) {
t.remove(mBackgroundLeash);
mBackgroundLeash = null;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl
index b4c745f..ef62764 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPipAnimationListener.aidl
@@ -32,4 +32,9 @@
* @param cornerRadius the pixel value of the corner radius, zero means it's disabled.
*/
void onPipCornerRadiusChanged(int cornerRadius);
+
+ /**
+ * Notifies the listener that user leaves PiP by tapping on the expand button.
+ */
+ void onExpandPip();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 9b04764..ad5d85c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -96,7 +96,7 @@
* Manages the picture-in-picture (PIP) UI and states for Phones.
*/
public class PipController implements PipTransitionController.PipTransitionCallback,
- RemoteCallable<PipController>, DisplayController.OnDisplaysChangedListener {
+ RemoteCallable<PipController> {
private static final String TAG = "PipController";
private Context mContext;
@@ -137,6 +137,11 @@
* @param cornerRadius the pixel value of the corner radius, zero means it's disabled.
*/
void onPipCornerRadiusChanged(int cornerRadius);
+
+ /**
+ * Notifies the listener that user leaves PiP by tapping on the expand button.
+ */
+ void onExpandPip();
}
/**
@@ -229,6 +234,14 @@
onDisplayChanged(mDisplayController.getDisplayLayout(displayId),
true /* saveRestoreSnapFraction */);
}
+
+ @Override
+ public void onKeepClearAreasChanged(int displayId, Set<Rect> restricted,
+ Set<Rect> unrestricted) {
+ if (mPipBoundsState.getDisplayId() == displayId) {
+ mPipBoundsState.setKeepClearAreas(restricted, unrestricted);
+ }
+ }
};
/**
@@ -458,14 +471,6 @@
return mMainExecutor;
}
- @Override
- public void onKeepClearAreasChanged(int displayId, Set<Rect> restricted,
- Set<Rect> unrestricted) {
- if (mPipBoundsState.getDisplayId() == displayId) {
- mPipBoundsState.setKeepClearAreas(restricted, unrestricted);
- }
- }
-
private void onConfigurationChanged(Configuration newConfig) {
mPipBoundsAlgorithm.onConfigurationChanged(mContext);
mTouchHandler.onConfigurationChanged();
@@ -652,6 +657,9 @@
mTouchHandler.setTouchEnabled(false);
if (mPinnedStackAnimationRecentsCallback != null) {
mPinnedStackAnimationRecentsCallback.onPipAnimationStarted();
+ if (direction == TRANSITION_DIRECTION_LEAVE_PIP) {
+ mPinnedStackAnimationRecentsCallback.onExpandPip();
+ }
}
}
@@ -911,6 +919,11 @@
public void onPipCornerRadiusChanged(int cornerRadius) {
mListener.call(l -> l.onPipCornerRadiusChanged(cornerRadius));
}
+
+ @Override
+ public void onExpandPip() {
+ mListener.call(l -> l.onExpandPip());
+ }
};
IPipImpl(PipController controller) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
index d6dacd1..1aefd77 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
@@ -95,13 +95,14 @@
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: getEntryDestinationBounds()", TAG);
}
- if (mTvPipBoundsState.isTvExpandedPipSupported()
+ updateExpandedPipSize();
+ final boolean isPipExpanded = mTvPipBoundsState.isTvExpandedPipSupported()
&& mTvPipBoundsState.getDesiredTvExpandedAspectRatio() != 0
- && !mTvPipBoundsState.isTvPipManuallyCollapsed()) {
- updateExpandedPipSize();
+ && !mTvPipBoundsState.isTvPipManuallyCollapsed();
+ if (isPipExpanded) {
updateGravityOnExpandToggled(Gravity.NO_GRAVITY, true);
- mTvPipBoundsState.setTvPipExpanded(true);
}
+ mTvPipBoundsState.setTvPipExpanded(isPipExpanded);
return getTvPipBounds().getBounds();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
index ccd054a..9529d04 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
@@ -303,7 +303,7 @@
*/
private boolean actionsMatch(RemoteAction action1, RemoteAction action2) {
if (action1 == action2) return true;
- if (action1 == null) return false;
+ if (action1 == null || action2 == null) return false;
return Objects.equals(action1.getTitle(), action2.getTitle())
&& Objects.equals(action1.getContentDescription(), action2.getContentDescription())
&& Objects.equals(action1.getActionIntent(), action2.getActionIntent());
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index ec1ddf0..880693d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -1072,8 +1072,8 @@
mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> {
updateSurfaceBounds(layout, t);
- mMainStage.onResized(getMainStageBounds(), t);
- mSideStage.onResized(getSideStageBounds(), t);
+ mMainStage.onResized(t);
+ mSideStage.onResized(t);
});
mLogger.logResize(mSplitLayout.getDividerPositionAsFraction());
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 5f0cd01..fb0eebd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -319,9 +319,9 @@
}
}
- void onResized(Rect newBounds, SurfaceControl.Transaction t) {
+ void onResized(SurfaceControl.Transaction t) {
if (mSplitDecorManager != null) {
- mSplitDecorManager.onResized(newBounds, t);
+ mSplitDecorManager.onResized(t);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
index 0d46199..2debcf2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
@@ -534,8 +534,9 @@
@Override
public void resized(ClientWindowFrames frames, boolean reportDraw,
- MergedConfiguration mergedConfiguration, boolean forceLayout,
- boolean alwaysConsumeSystemBars, int displayId, int seqId, int resizeMode) {
+ MergedConfiguration mergedConfiguration, InsetsState insetsState,
+ boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, int seqId,
+ int resizeMode) {
if (mOuter != null) {
mOuter.mSplashScreenExecutor.execute(() -> {
if (mergedConfiguration != null
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
index f40aa66..bd98585 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
@@ -123,6 +123,7 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java
index 03df92f..32f1587 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TaskViewTest.java
@@ -39,11 +39,13 @@
import android.app.PendingIntent;
import android.content.Context;
import android.graphics.Rect;
+import android.graphics.Region;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.SurfaceControl;
import android.view.SurfaceHolder;
import android.view.SurfaceSession;
+import android.view.ViewTreeObserver;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -397,4 +399,45 @@
mTaskView.prepareCloseAnimation();
verify(mOrganizer).setInterceptBackPressedOnTaskRoot(eq(mTaskInfo.token), eq(false));
}
+
+ @Test
+ public void testSetObscuredTouchRect() {
+ mTaskView.setObscuredTouchRect(
+ new Rect(/* left= */ 0, /* top= */ 10, /* right= */ 100, /* bottom= */ 120));
+ ViewTreeObserver.InternalInsetsInfo insetsInfo = new ViewTreeObserver.InternalInsetsInfo();
+ mTaskView.onComputeInternalInsets(insetsInfo);
+
+ assertThat(insetsInfo.touchableRegion.contains(0, 10)).isTrue();
+ // Region doesn't contain the right/bottom edge.
+ assertThat(insetsInfo.touchableRegion.contains(100 - 1, 120 - 1)).isTrue();
+
+ mTaskView.setObscuredTouchRect(null);
+ insetsInfo.touchableRegion.setEmpty();
+ mTaskView.onComputeInternalInsets(insetsInfo);
+
+ assertThat(insetsInfo.touchableRegion.contains(0, 10)).isFalse();
+ assertThat(insetsInfo.touchableRegion.contains(100 - 1, 120 - 1)).isFalse();
+ }
+
+ @Test
+ public void testSetObscuredTouchRegion() {
+ Region obscuredRegion = new Region(10, 10, 19, 19);
+ obscuredRegion.union(new Rect(30, 30, 39, 39));
+
+ mTaskView.setObscuredTouchRegion(obscuredRegion);
+ ViewTreeObserver.InternalInsetsInfo insetsInfo = new ViewTreeObserver.InternalInsetsInfo();
+ mTaskView.onComputeInternalInsets(insetsInfo);
+
+ assertThat(insetsInfo.touchableRegion.contains(10, 10)).isTrue();
+ assertThat(insetsInfo.touchableRegion.contains(20, 20)).isFalse();
+ assertThat(insetsInfo.touchableRegion.contains(30, 30)).isTrue();
+
+ mTaskView.setObscuredTouchRegion(null);
+ insetsInfo.touchableRegion.setEmpty();
+ mTaskView.onComputeInternalInsets(insetsInfo);
+
+ assertThat(insetsInfo.touchableRegion.contains(10, 10)).isFalse();
+ assertThat(insetsInfo.touchableRegion.contains(20, 20)).isFalse();
+ assertThat(insetsInfo.touchableRegion.contains(30, 30)).isFalse();
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index af6e5d4..aef298e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -217,7 +217,8 @@
final Rect keepClearArea = new Rect(0, 0, 10, 10);
when(mMockPipBoundsState.getDisplayId()).thenReturn(displayId);
- mPipController.onKeepClearAreasChanged(displayId, Set.of(keepClearArea), Set.of());
+ mPipController.mDisplaysChangedListener.onKeepClearAreasChanged(
+ displayId, Set.of(keepClearArea), Set.of());
verify(mMockPipBoundsState).setKeepClearAreas(Set.of(keepClearArea), Set.of());
}
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 30ca7d15..86ae399 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -69,7 +69,6 @@
bool Properties::enableHighContrastText = false;
bool Properties::waitForGpuCompletion = false;
-bool Properties::forceDrawFrame = false;
bool Properties::filterOutTestOverhead = false;
bool Properties::disableVsync = false;
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index cc9094c..6b8f439 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -100,6 +100,8 @@
int stretchEffectCount = 0;
+ bool forceDrawFrame = false;
+
struct Out {
bool hasFunctors = false;
// This is only updated if evaluateAnimations is true
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 27865b3..c48448d 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -259,7 +259,8 @@
}
static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
- jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) {
+ jlong proxyPtr, jlongArray frameInfo,
+ jint frameInfoSize) {
LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
"Mismatched size expectations, given %d expected %zu", frameInfoSize,
UI_THREAD_FRAME_INFO_SIZE);
@@ -413,6 +414,12 @@
proxy->setContentDrawBounds(left, top, right, bottom);
}
+static void android_view_ThreadedRenderer_forceDrawNextFrame(JNIEnv* env, jobject clazz,
+ jlong proxyPtr) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ proxy->forceDrawNextFrame();
+}
+
class JGlobalRefHolder {
public:
JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {}
@@ -770,11 +777,6 @@
Properties::enableHighContrastText = enable;
}
-static void android_view_ThreadedRenderer_hackySetRTAnimationsEnabled(JNIEnv*, jclass,
- jboolean enable) {
- Properties::enableRTAnimations = enable;
-}
-
static void android_view_ThreadedRenderer_setDebuggingEnabled(JNIEnv*, jclass, jboolean enable) {
Properties::debuggingEnabled = enable;
}
@@ -804,6 +806,11 @@
RenderProxy::preload();
}
+static void android_view_ThreadedRenderer_setRtAnimationsEnabled(JNIEnv* env, jobject clazz,
+ jboolean enabled) {
+ RenderProxy::setRtAnimationsEnabled(enabled);
+}
+
// Plumbs the display density down to DeviceInfo.
static void android_view_ThreadedRenderer_setDisplayDensityDpi(JNIEnv*, jclass, jint densityDpi) {
// Convert from dpi to density-independent pixels.
@@ -935,6 +942,7 @@
{"nDrawRenderNode", "(JJ)V", (void*)android_view_ThreadedRendererd_drawRenderNode},
{"nSetContentDrawBounds", "(JIIII)V",
(void*)android_view_ThreadedRenderer_setContentDrawBounds},
+ {"nForceDrawNextFrame", "(J)V", (void*)android_view_ThreadedRenderer_forceDrawNextFrame},
{"nSetPictureCaptureCallback",
"(JLandroid/graphics/HardwareRenderer$PictureCapturedCallback;)V",
(void*)android_view_ThreadedRenderer_setPictureCapturedCallbackJNI},
@@ -959,8 +967,6 @@
(void*)android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode},
{"disableVsync", "()V", (void*)android_view_ThreadedRenderer_disableVsync},
{"nSetHighContrastText", "(Z)V", (void*)android_view_ThreadedRenderer_setHighContrastText},
- {"nHackySetRTAnimationsEnabled", "(Z)V",
- (void*)android_view_ThreadedRenderer_hackySetRTAnimationsEnabled},
{"nSetDebuggingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDebuggingEnabled},
{"nSetIsolatedProcess", "(Z)V", (void*)android_view_ThreadedRenderer_setIsolatedProcess},
{"nSetContextPriority", "(I)V", (void*)android_view_ThreadedRenderer_setContextPriority},
@@ -974,6 +980,8 @@
(void*)android_view_ThreadedRenderer_isWebViewOverlaysEnabled},
{"nSetDrawingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDrawingEnabled},
{"nIsDrawingEnabled", "()Z", (void*)android_view_ThreadedRenderer_isDrawingEnabled},
+ {"nSetRtAnimationsEnabled", "(Z)V",
+ (void*)android_view_ThreadedRenderer_setRtAnimationsEnabled},
};
static JavaVM* mJvm = nullptr;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index bdad772..122c77f 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -390,7 +390,7 @@
return;
}
- if (CC_LIKELY(mSwapHistory.size() && !Properties::forceDrawFrame)) {
+ if (CC_LIKELY(mSwapHistory.size() && !info.forceDrawFrame)) {
nsecs_t latestVsync = mRenderThread.timeLord().latestVsync();
SwapHistory& lastSwap = mSwapHistory.back();
nsecs_t vsyncDelta = std::abs(lastSwap.vsyncTime - latestVsync);
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 2357dfe..59c914f 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -148,6 +148,8 @@
bool canDrawThisFrame;
{
TreeInfo info(TreeInfo::MODE_FULL, *mContext);
+ info.forceDrawFrame = mForceDrawFrame;
+ mForceDrawFrame = false;
canUnblockUiThread = syncFrameState(info);
canDrawThisFrame = info.out.canDrawThisFrame;
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index 25ed935..d6fc292 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -88,6 +88,8 @@
mFrameCompleteCallback = std::move(callback);
}
+ void forceDrawNextFrame() { mForceDrawFrame = true; }
+
private:
class HintSessionWrapper {
public:
@@ -132,6 +134,8 @@
nsecs_t mLastDequeueBufferDuration = 0;
nsecs_t mLastTargetWorkDuration = 0;
std::optional<HintSessionWrapper> mHintSessionWrapper;
+
+ bool mForceDrawFrame = false;
};
} /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 026699c..a44b498 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -133,6 +133,10 @@
return mDrawFrameTask.frameInfo();
}
+void RenderProxy::forceDrawNextFrame() {
+ mDrawFrameTask.forceDrawNextFrame();
+}
+
int RenderProxy::syncAndDrawFrame() {
return mDrawFrameTask.drawFrame();
}
@@ -424,6 +428,15 @@
thread.queue().post([&thread]() { thread.preload(); });
}
+void RenderProxy::setRtAnimationsEnabled(bool enabled) {
+ if (RenderThread::hasInstance()) {
+ RenderThread::getInstance().queue().post(
+ [enabled]() { Properties::enableRTAnimations = enabled; });
+ } else {
+ Properties::enableRTAnimations = enabled;
+ }
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 491dbd7..ee9efd4 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -82,6 +82,7 @@
void setOpaque(bool opaque);
void setColorMode(ColorMode mode);
int64_t* frameInfo();
+ void forceDrawNextFrame();
int syncAndDrawFrame();
void destroy();
@@ -143,6 +144,8 @@
static void preload();
+ static void setRtAnimationsEnabled(bool enabled);
+
private:
RenderThread& mRenderThread;
CanvasContext* mContext;
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index de2c621..613a6ae 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -104,7 +104,6 @@
// If we're reporting GPU memory usage we need to first start with a clean slate
RenderProxy::purgeCaches();
}
- Properties::forceDrawFrame = true;
TestContext testContext;
testContext.setRenderOffscreen(opts.renderOffscreen);
@@ -144,6 +143,7 @@
.setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID,
UiFrameInfoBuilder::UNKNOWN_DEADLINE,
UiFrameInfoBuilder::UNKNOWN_FRAME_INTERVAL);
+ proxy->forceDrawNextFrame();
proxy->syncAndDrawFrame();
}
@@ -163,6 +163,7 @@
UiFrameInfoBuilder::UNKNOWN_DEADLINE,
UiFrameInfoBuilder::UNKNOWN_FRAME_INTERVAL);
scene->doFrame(i);
+ proxy->forceDrawNextFrame();
proxy->syncAndDrawFrame();
}
if (opts.reportFrametimeWeight) {
diff --git a/location/java/android/location/LastLocationRequest.java b/location/java/android/location/LastLocationRequest.java
index ec03a33..d90c2e6 100644
--- a/location/java/android/location/LastLocationRequest.java
+++ b/location/java/android/location/LastLocationRequest.java
@@ -20,8 +20,10 @@
import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.content.pm.PackageManager;
import android.os.Parcel;
import android.os.Parcelable;
@@ -224,6 +226,7 @@
*/
@SystemApi
@RequiresPermission(LOCATION_BYPASS)
+ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
public @NonNull LastLocationRequest.Builder setAdasGnssBypass(boolean adasGnssBypass) {
mAdasGnssBypass = adasGnssBypass;
return this;
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index a504cfe..371f5ed 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -681,6 +681,7 @@
*/
@SystemApi
@RequiresPermission(LOCATION_BYPASS)
+ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
public void setAdasGnssLocationEnabled(boolean enabled) {
try {
mService.setAdasGnssLocationEnabledForUser(enabled, mContext.getUser().getIdentifier());
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index 09474b5..80b55e2 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -27,10 +27,12 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
+import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -1136,6 +1138,7 @@
*/
@SystemApi
@RequiresPermission(LOCATION_BYPASS)
+ @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
public @NonNull Builder setAdasGnssBypass(boolean adasGnssBypass) {
mAdasGnssBypass = adasGnssBypass;
return this;
diff --git a/media/java/android/media/AudioDeviceVolumeManager.java b/media/java/android/media/AudioDeviceVolumeManager.java
index 7104241..11cacd0 100644
--- a/media/java/android/media/AudioDeviceVolumeManager.java
+++ b/media/java/android/media/AudioDeviceVolumeManager.java
@@ -17,6 +17,7 @@
package android.media;
import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -27,6 +28,8 @@
import com.android.internal.annotations.GuardedBy;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -40,6 +43,22 @@
// define when using Log.*
//private static final String TAG = "AudioDeviceVolumeManager";
+
+ /** Indicates no special treatment in the handling of the volume adjustment */
+ public static final int ADJUST_MODE_NORMAL = 0;
+ /** Indicates the start of a volume adjustment */
+ public static final int ADJUST_MODE_START = 1;
+ /** Indicates the end of a volume adjustment */
+ public static final int ADJUST_MODE_END = 2;
+
+ @IntDef(flag = false, prefix = "ADJUST_MODE", value = {
+ ADJUST_MODE_NORMAL,
+ ADJUST_MODE_START,
+ ADJUST_MODE_END}
+ )
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface VolumeAdjustmentMode {}
+
private static IAudioService sService;
private final String mPackageName;
@@ -65,18 +84,33 @@
void onAudioDeviceVolumeChanged(
@NonNull AudioDeviceAttributes device,
@NonNull VolumeInfo vol);
+
+ /**
+ * Called when the volume for the given audio device has been adjusted.
+ * @param device the audio device whose volume has been adjusted
+ * @param vol the volume info for the device
+ * @param direction the direction of the adjustment
+ * @param mode the volume adjustment mode
+ */
+ void onAudioDeviceVolumeAdjusted(
+ @NonNull AudioDeviceAttributes device,
+ @NonNull VolumeInfo vol,
+ @AudioManager.VolumeAdjustment int direction,
+ @VolumeAdjustmentMode int mode);
}
static class ListenerInfo {
final @NonNull OnAudioDeviceVolumeChangedListener mListener;
final @NonNull Executor mExecutor;
final @NonNull AudioDeviceAttributes mDevice;
+ final @NonNull boolean mHandlesVolumeAdjustment;
ListenerInfo(@NonNull OnAudioDeviceVolumeChangedListener listener, @NonNull Executor exe,
- @NonNull AudioDeviceAttributes device) {
+ @NonNull AudioDeviceAttributes device, boolean handlesVolumeAdjustment) {
mListener = listener;
mExecutor = exe;
mDevice = device;
+ mHandlesVolumeAdjustment = handlesVolumeAdjustment;
}
}
@@ -98,11 +132,12 @@
* @param device device for which volume is monitored
*/
public void register(boolean register, @NonNull AudioDeviceAttributes device,
- @NonNull List<VolumeInfo> volumes) {
+ @NonNull List<VolumeInfo> volumes, boolean handlesVolumeAdjustment) {
try {
getService().registerDeviceVolumeDispatcherForAbsoluteVolume(register,
this, mPackageName,
- Objects.requireNonNull(device), Objects.requireNonNull(volumes));
+ Objects.requireNonNull(device), Objects.requireNonNull(volumes),
+ handlesVolumeAdjustment);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
@@ -116,12 +151,29 @@
volumeListeners = (ArrayList<ListenerInfo>) mDeviceVolumeListeners.clone();
}
for (ListenerInfo listenerInfo : volumeListeners) {
- if (listenerInfo.mDevice.equals(device)) {
+ if (listenerInfo.mDevice.equalTypeAddress(device)) {
listenerInfo.mExecutor.execute(
() -> listenerInfo.mListener.onAudioDeviceVolumeChanged(device, vol));
}
}
}
+
+ @Override
+ public void dispatchDeviceVolumeAdjusted(
+ @NonNull AudioDeviceAttributes device, @NonNull VolumeInfo vol, int direction,
+ int mode) {
+ final ArrayList<ListenerInfo> volumeListeners;
+ synchronized (mDeviceVolumeListenerLock) {
+ volumeListeners = (ArrayList<ListenerInfo>) mDeviceVolumeListeners.clone();
+ }
+ for (ListenerInfo listenerInfo : volumeListeners) {
+ if (listenerInfo.mDevice.equalTypeAddress(device)) {
+ listenerInfo.mExecutor.execute(
+ () -> listenerInfo.mListener.onAudioDeviceVolumeAdjusted(device, vol,
+ direction, mode));
+ }
+ }
+ }
}
/**
@@ -139,10 +191,12 @@
@NonNull AudioDeviceAttributes device,
@NonNull VolumeInfo volume,
@NonNull @CallbackExecutor Executor executor,
- @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
+ @NonNull OnAudioDeviceVolumeChangedListener vclistener,
+ boolean handlesVolumeAdjustment) {
final ArrayList<VolumeInfo> volumes = new ArrayList<>(1);
volumes.add(volume);
- setDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener);
+ setDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener,
+ handlesVolumeAdjustment);
}
/**
@@ -153,6 +207,9 @@
* @param volumes the list of volumes the given device responds to
* @param executor the Executor used for receiving volume updates through the listener
* @param vclistener the callback for volume updates
+ * @param handlesVolumeAdjustment whether the controller handles volume adjustments separately
+ * from volume changes. If true, adjustments from {@link AudioManager#adjustStreamVolume}
+ * will be sent via {@link OnAudioDeviceVolumeChangedListener#onAudioDeviceVolumeAdjusted}.
*/
@RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING,
android.Manifest.permission.BLUETOOTH_PRIVILEGED })
@@ -160,14 +217,15 @@
@NonNull AudioDeviceAttributes device,
@NonNull List<VolumeInfo> volumes,
@NonNull @CallbackExecutor Executor executor,
- @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
+ @NonNull OnAudioDeviceVolumeChangedListener vclistener,
+ boolean handlesVolumeAdjustment) {
Objects.requireNonNull(device);
Objects.requireNonNull(volumes);
Objects.requireNonNull(executor);
Objects.requireNonNull(vclistener);
- // TODO verify not already registered
- //final ListenerInfo listenerInfo = new ListenerInfo(vclistener, executor, device);
+ final ListenerInfo listenerInfo = new ListenerInfo(
+ vclistener, executor, device, handlesVolumeAdjustment);
synchronized (mDeviceVolumeListenerLock) {
if (mDeviceVolumeListeners == null) {
mDeviceVolumeListeners = new ArrayList<>();
@@ -176,8 +234,17 @@
if (mDeviceVolumeDispatcherStub == null) {
mDeviceVolumeDispatcherStub = new DeviceVolumeDispatcherStub();
}
+ } else {
+ for (ListenerInfo info : mDeviceVolumeListeners) {
+ if (info.mListener == vclistener) {
+ throw new IllegalArgumentException(
+ "attempt to call setDeviceAbsoluteMultiVolumeBehavior() "
+ + "on a previously registered listener");
+ }
+ }
}
- mDeviceVolumeDispatcherStub.register(true, device, volumes);
+ mDeviceVolumeListeners.add(listenerInfo);
+ mDeviceVolumeDispatcherStub.register(true, device, volumes, handlesVolumeAdjustment);
}
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 1a56b15..491a5cd 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -604,6 +604,13 @@
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int FLAG_FROM_KEY = 1 << 12;
+ /**
+ * Indicates that an absolute volume controller is notifying AudioService of a change in the
+ * volume or mute status of an external audio system.
+ * @hide
+ */
+ public static final int FLAG_ABSOLUTE_VOLUME = 1 << 13;
+
/** @hide */
@IntDef(prefix = {"ENCODED_SURROUND_OUTPUT_"}, value = {
ENCODED_SURROUND_OUTPUT_UNKNOWN,
@@ -661,6 +668,7 @@
FLAG_SHOW_UI_WARNINGS,
FLAG_SHOW_VIBRATE_HINT,
FLAG_FROM_KEY,
+ FLAG_ABSOLUTE_VOLUME,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Flags {}
@@ -682,6 +690,7 @@
FLAG_NAMES.put(FLAG_SHOW_UI_WARNINGS, "FLAG_SHOW_UI_WARNINGS");
FLAG_NAMES.put(FLAG_SHOW_VIBRATE_HINT, "FLAG_SHOW_VIBRATE_HINT");
FLAG_NAMES.put(FLAG_FROM_KEY, "FLAG_FROM_KEY");
+ FLAG_NAMES.put(FLAG_ABSOLUTE_VOLUME, "FLAG_ABSOLUTE_VOLUME");
}
/** @hide */
@@ -8393,6 +8402,12 @@
* {@link #addAssistantServicesUids(int[])} and not yet removed with
* {@link #removeAssistantServicesUids(int[])}
*
+ * <p> Note that during native audioserver crash and after boot up the list of assistant
+ * UIDs will be reset to an empty list (i.e. no UID will be considered as assistant)
+ * Just after user switch, the list of assistant will also reset to empty.
+ * In both cases,The component's UID of the assistiant role or assistant setting will be
+ * automitically added to the list by the audio service.
+ *
* @return array of assistants UIDs
*
* @hide
diff --git a/media/java/android/media/IAudioDeviceVolumeDispatcher.aidl b/media/java/android/media/IAudioDeviceVolumeDispatcher.aidl
index 65633fe..70b4ab6 100644
--- a/media/java/android/media/IAudioDeviceVolumeDispatcher.aidl
+++ b/media/java/android/media/IAudioDeviceVolumeDispatcher.aidl
@@ -27,5 +27,7 @@
oneway interface IAudioDeviceVolumeDispatcher {
void dispatchDeviceVolumeChanged(in AudioDeviceAttributes device, in VolumeInfo vol);
+ void dispatchDeviceVolumeAdjusted(in AudioDeviceAttributes device, in VolumeInfo vol,
+ int direction, int mode);
}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index babafaf..e28178a 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -509,7 +509,8 @@
void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register,
in IAudioDeviceVolumeDispatcher cb,
in String packageName,
- in AudioDeviceAttributes device, in List<VolumeInfo> volumes);
+ in AudioDeviceAttributes device, in List<VolumeInfo> volumes,
+ boolean handlesvolumeAdjustment);
String getHalVersion();
}
diff --git a/media/java/android/media/metrics/BundleSession.java b/media/java/android/media/metrics/BundleSession.java
index 743d233..0f0fdfe 100644
--- a/media/java/android/media/metrics/BundleSession.java
+++ b/media/java/android/media/metrics/BundleSession.java
@@ -32,6 +32,15 @@
private final @NonNull MediaMetricsManager mManager;
private final @NonNull LogSessionId mLogSessionId;
+ /**
+ * A key describing the statsd atom into which to place this bundle's other contents.
+ * The associated value is an integer.
+ *
+ * @see #reportBundleMetrics
+ */
+
+ public static final String KEY_STATSD_ATOM = "bundlesession-statsd-atom";
+
/** @hide */
public BundleSession(@NonNull String id, @NonNull MediaMetricsManager manager) {
mId = id;
@@ -44,6 +53,10 @@
/**
* Reports metrics via bundle.
*
+ * The key {@link #KEY_STATSD_ATOM} references an integer value that
+ * indicates the statsd atom for the data in this bundle. Other keys
+ * and their types are defined on a per-atom basis.
+ *
*/
public void reportBundleMetrics(@NonNull PersistableBundle metrics) {
mManager.reportBundleMetrics(mId, metrics);
@@ -68,5 +81,6 @@
@Override
public void close() {
+ mManager.releaseSessionId(mLogSessionId.getStringId());
}
}
diff --git a/media/java/android/media/metrics/EditingSession.java b/media/java/android/media/metrics/EditingSession.java
index 2a48a72..2ddf623b 100644
--- a/media/java/android/media/metrics/EditingSession.java
+++ b/media/java/android/media/metrics/EditingSession.java
@@ -59,5 +59,6 @@
@Override
public void close() {
+ mManager.releaseSessionId(mLogSessionId.getStringId());
}
}
diff --git a/media/java/android/media/metrics/IMediaMetricsManager.aidl b/media/java/android/media/metrics/IMediaMetricsManager.aidl
index a774403..51b1cc2 100644
--- a/media/java/android/media/metrics/IMediaMetricsManager.aidl
+++ b/media/java/android/media/metrics/IMediaMetricsManager.aidl
@@ -41,4 +41,6 @@
String getEditingSessionId(int userId);
String getBundleSessionId(int userId);
void reportBundleMetrics(in String sessionId, in PersistableBundle metrics, int userId);
+
+ void releaseSessionId(in String sessionId, int userId);
}
diff --git a/media/java/android/media/metrics/MediaMetricsManager.java b/media/java/android/media/metrics/MediaMetricsManager.java
index 7229c47..0898874 100644
--- a/media/java/android/media/metrics/MediaMetricsManager.java
+++ b/media/java/android/media/metrics/MediaMetricsManager.java
@@ -171,6 +171,18 @@
}
/**
+ * Creates a generic bundle session.
+ */
+ @NonNull
+ public void releaseSessionId(@NonNull String sessionId) {
+ try {
+ mService.releaseSessionId(sessionId, mUserId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Reports error event.
* @hide
*/
diff --git a/media/java/android/media/metrics/PlaybackSession.java b/media/java/android/media/metrics/PlaybackSession.java
index aad510e..f8dd756 100644
--- a/media/java/android/media/metrics/PlaybackSession.java
+++ b/media/java/android/media/metrics/PlaybackSession.java
@@ -100,5 +100,6 @@
@Override
public void close() {
mClosed = true;
+ mManager.releaseSessionId(mLogSessionId.getStringId());
}
}
diff --git a/media/java/android/media/metrics/PlaybackStateEvent.java b/media/java/android/media/metrics/PlaybackStateEvent.java
index 8e74825..cfe0ff8 100644
--- a/media/java/android/media/metrics/PlaybackStateEvent.java
+++ b/media/java/android/media/metrics/PlaybackStateEvent.java
@@ -31,6 +31,11 @@
* Playback state event.
*/
public final class PlaybackStateEvent extends Event implements Parcelable {
+
+ // RBE -- we should be getting these values from the proto, not doing them
+ // hand-coded values here.
+ // frameorks/proto_logging/stats/message/mediametrics_message.pb.h
+ // package libstatslog?
/** Playback has not started (initial state) */
public static final int STATE_NOT_STARTED = 0;
/** Playback is buffering in the background for initial playback start */
diff --git a/media/java/android/media/metrics/RecordingSession.java b/media/java/android/media/metrics/RecordingSession.java
index d388351..87cc250 100644
--- a/media/java/android/media/metrics/RecordingSession.java
+++ b/media/java/android/media/metrics/RecordingSession.java
@@ -61,5 +61,6 @@
@Override
public void close() {
mClosed = true;
+ mManager.releaseSessionId(mLogSessionId.getStringId());
}
}
diff --git a/media/java/android/media/metrics/TranscodingSession.java b/media/java/android/media/metrics/TranscodingSession.java
index e6d359a..352138e 100644
--- a/media/java/android/media/metrics/TranscodingSession.java
+++ b/media/java/android/media/metrics/TranscodingSession.java
@@ -59,5 +59,6 @@
@Override
public void close() {
+ mManager.releaseSessionId(mLogSessionId.getStringId());
}
}
diff --git a/media/packages/BluetoothMidiService/AndroidManifest.xml b/media/packages/BluetoothMidiService/AndroidManifest.xml
index 858f85f..6928b94 100644
--- a/media/packages/BluetoothMidiService/AndroidManifest.xml
+++ b/media/packages/BluetoothMidiService/AndroidManifest.xml
@@ -20,8 +20,6 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.android.bluetoothmidiservice"
>
- <uses-sdk android:minSdkVersion="33" android:targetSdkVersion="33" />
-
<uses-feature android:name="android.hardware.bluetooth_le"
android:required="true"/>
<uses-feature android:name="android.software.midi"
diff --git a/media/packages/BluetoothMidiService/AndroidManifestBase.xml b/media/packages/BluetoothMidiService/AndroidManifestBase.xml
index 99dcaaa..468f6ee 100644
--- a/media/packages/BluetoothMidiService/AndroidManifestBase.xml
+++ b/media/packages/BluetoothMidiService/AndroidManifestBase.xml
@@ -19,7 +19,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.bluetoothmidiservice"
>
- <uses-sdk android:minSdkVersion="33" android:targetSdkVersion="33" />
<application
android:label="BluetoothMidi"
android:defaultToDeviceProtectedStorage="true"
diff --git a/mms/java/android/telephony/MmsManager.java b/mms/java/android/telephony/MmsManager.java
index d541da0..b893b45 100644
--- a/mms/java/android/telephony/MmsManager.java
+++ b/mms/java/android/telephony/MmsManager.java
@@ -70,7 +70,8 @@
}
iMms.sendMessage(subId, ActivityThread.currentPackageName(), contentUri,
- locationUrl, configOverrides, sentIntent, messageId);
+ locationUrl, configOverrides, sentIntent, messageId,
+ mContext.getAttributionTag());
} catch (RemoteException e) {
// Ignore it
}
@@ -102,7 +103,7 @@
}
iMms.downloadMessage(subId, ActivityThread.currentPackageName(),
locationUrl, contentUri, configOverrides, downloadedIntent,
- messageId);
+ messageId, mContext.getAttributionTag());
} catch (RemoteException e) {
// Ignore it
}
diff --git a/mms/java/com/android/internal/telephony/IMms.aidl b/mms/java/com/android/internal/telephony/IMms.aidl
index e0e0a4a..3cdde10 100644
--- a/mms/java/com/android/internal/telephony/IMms.aidl
+++ b/mms/java/com/android/internal/telephony/IMms.aidl
@@ -26,7 +26,7 @@
*/
interface IMms {
/**
- * Send an MMS message
+ * Send an MMS message with attribution tag.
*
* @param subId the SIM id
* @param callingPkg the package name of the calling app
@@ -38,10 +38,11 @@
* @param sentIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is successfully sent, or failed
* @param messageId An id that uniquely identifies the message requested to be sent.
+ * @param attributionTag a tag that attributes the call to a client App.
*/
void sendMessage(int subId, String callingPkg, in Uri contentUri,
String locationUrl, in Bundle configOverrides, in PendingIntent sentIntent,
- in long messageId);
+ in long messageId, String attributionTag);
/**
* Download an MMS message using known location and transaction id
@@ -57,10 +58,11 @@
* @param downloadedIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is downloaded, or the download is failed
* @param messageId An id that uniquely identifies the message requested to be downloaded.
+ * @param attributionTag a tag that attributes the call to a client App.
*/
void downloadMessage(int subId, String callingPkg, String locationUrl,
in Uri contentUri, in Bundle configOverrides,
- in PendingIntent downloadedIntent, in long messageId);
+ in PendingIntent downloadedIntent, in long messageId, String attributionTag);
/**
* Import a text message into system's SMS store
diff --git a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
index c37054e..c0e6c09 100644
--- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
@@ -12,120 +12,135 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/activity_confirmation"
- style="@style/ContainerLayout">
-
- <!-- A header for selfManaged devices only. -->
- <include layout="@layout/vendor_header" />
-
- <!-- Do NOT change the ID of the root LinearLayout above: it's referenced in CTS tests. -->
-
- <ImageView
- android:id="@+id/profile_icon"
+ android:id="@+id/activity_confirmation"
android:layout_width="match_parent"
- android:layout_height="32dp"
- android:gravity="center"
- android:layout_marginTop="18dp"
- android:tint="@android:color/system_accent1_600"/>
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:minWidth="340dp">
- <LinearLayout style="@style/Description">
- <TextView
- android:id="@+id/title"
- style="@style/DescriptionTitle" />
+ <LinearLayout android:id="@+id/association_confirmation"
+ style="@style/ContainerLayout">
- <TextView
- android:id="@+id/summary"
- style="@style/DescriptionSummary" />
+ <!-- A header for selfManaged devices only. -->
+ <include layout="@layout/vendor_header" />
+
+ <!-- Do NOT change the ID of the root LinearLayout above: it's referenced in CTS tests. -->
+
+ <ImageView
+ android:id="@+id/profile_icon"
+ android:layout_width="match_parent"
+ android:layout_height="32dp"
+ android:gravity="center"
+ android:layout_marginTop="18dp"
+ android:tint="@android:color/system_accent1_600"/>
+
+ <LinearLayout style="@style/Description">
+ <TextView
+ android:id="@+id/title"
+ style="@style/DescriptionTitle" />
+
+ <TextView
+ android:id="@+id/summary"
+ style="@style/DescriptionSummary" />
+
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <LinearLayout
+ android:id="@+id/multiple_device_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="12dp"
+ android:layout_marginBottom="12dp"
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <View
+ android:id="@+id/border_top"
+ style="@style/DeviceListBorder" />
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/device_list"
+ android:layout_width="match_parent"
+ android:scrollbars="vertical"
+ android:layout_marginBottom="12dp"
+ android:layout_height="200dp" />
+
+ <View
+ android:id="@+id/border_bottom"
+ style="@style/DeviceListBorder" />
+
+ </LinearLayout>
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/permission_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <ProgressBar
+ android:id="@+id/spinner_multiple_device"
+ android:visibility="gone"
+ style="@style/Spinner" />
+
+ </RelativeLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:layout_marginTop="16dp">
+
+ <!-- Do NOT change the IDs of the buttons: they are referenced in CTS tests. -->
+
+ <Button
+ android:id="@+id/btn_positive"
+ style="@style/PositiveButton"
+ android:text="@string/consent_yes" />
+
+ <Button
+ android:id="@+id/btn_negative"
+ android:layout_marginBottom="12dp"
+ style="@style/NegativeButton"
+ android:text="@string/consent_no" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="bottom|right"
+ android:orientation="vertical"
+ android:layout_marginRight="16dp"
+ android:layout_marginBottom="16dp">
+
+ <!-- Do NOT change the IDs of the buttons: they are referenced in CTS tests. -->
+
+ <Button
+ android:id="@+id/btn_negative_multiple_devices"
+ style="@style/NegativeButtonMultipleDevices"
+ android:textColor="?android:textColorPrimary"
+ android:visibility="gone"
+ android:text="@string/consent_no" />
+ </LinearLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
- android:layout_height="0dp"
+ android:layout_height="wrap_content"
android:layout_weight="1">
- <LinearLayout
- android:id="@+id/multiple_device_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="12dp"
- android:layout_marginBottom="12dp"
- android:orientation="vertical"
- android:visibility="gone">
-
- <View
- android:id="@+id/border_top"
- style="@style/DeviceListBorder" />
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/device_list"
- android:layout_width="match_parent"
- android:scrollbars="vertical"
- android:layout_marginBottom="12dp"
- android:layout_height="200dp" />
-
- <View
- android:id="@+id/border_bottom"
- style="@style/DeviceListBorder" />
-
- </LinearLayout>
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/permission_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
<ProgressBar
- android:id="@+id/spinner"
- android:layout_width="56dp"
- android:layout_height="56dp"
- android:layout_centerInParent="true"
- android:indeterminate="true"
- android:tint="@android:color/system_accent1_600"
+ android:id="@+id/spinner_single_device"
android:visibility="gone"
- style="?android:attr/progressBarStyleLarge" />
-
- </RelativeLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="vertical"
- android:layout_marginTop="16dp">
-
- <!-- Do NOT change the IDs of the buttons: they are referenced in CTS tests. -->
-
- <Button
- android:id="@+id/btn_positive"
- style="@style/PositiveButton"
- android:text="@string/consent_yes" />
-
- <Button
- android:id="@+id/btn_negative"
- android:layout_marginBottom="12dp"
- style="@style/NegativeButton"
- android:text="@string/consent_no" />
-
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="bottom|right"
- android:orientation="vertical"
- android:layout_marginRight="16dp"
- android:layout_marginBottom="16dp">
-
- <!-- Do NOT change the IDs of the buttons: they are referenced in CTS tests. -->
-
- <Button
- android:id="@+id/btn_negative_multiple_devices"
- style="@style/NegativeButtonMultipleDevices"
- android:textColor="?android:textColorPrimary"
- android:visibility="gone"
- android:text="@string/consent_no" />
- </LinearLayout>
+ style="@style/Spinner" />
+ </RelativeLayout>>
</LinearLayout>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index eec09d2..89205ef 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Programme"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Stroom jou foon se programme"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Gee <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang tot hierdie inligting op jou foon"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Gee <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> afstandtoegang tot programme wat op <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> geïnstalleer is wanneer hierdie foon aan die internet gekoppel is."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Gee <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> afstandtoegang tot programme wat op <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> geïnstalleer is wanneer hierdie tablet aan die internet gekoppel is."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Gee <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> afstandtoegang tot programme wat op <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> geïnstalleer is wanneer hierdie toestel aan die internet gekoppel is."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Oorkruistoestel-dienste"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Hierdie diens word gebruik om programme tussen jou toestelle te stroom"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Gee <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang tot hierdie inligting op jou foon"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Kennisgewings"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Kan alle kennisgewings lees, insluitend inligting soos kontakte, boodskappe en foto\'s"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Kan alle kennisgewings lees, insluitend inligting soos kontakte, boodskappe en foto\'s"</string>
<string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Dienste"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Hierdie diens deel foto\'s, media en kennisgewings van jou foon af na ander dienste"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Hierdie diens deel foto\'s, media en kennisgewings van jou foon af na ander dienste"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Laat toe"</string>
<string name="consent_no" msgid="2640796915611404382">"Moenie toelaat nie"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Dra programtoestemmings na jou horlosie toe oor"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Om dit makliker te maak om jou horlosie op te stel, sal programme wat gedurende opstelling op jou horlosie geïnstalleer word, dieselfde toestemmings as jou foon gebruik.\n\n Hierdie toestemmings kan toegang tot jou horlosie se mikrofoon en ligging insluit."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index 0411f3a..7b699db 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"መተግበሪያዎች"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"የስልክዎን መተግበሪያዎች በዥረት ይልቀቁ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ይህን መረጃ ከስልክዎ እንዲደርስበት ይፍቀዱለት"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ሲገናኙ በዚህ ስልክ ላይ የተጫኑ መተግበሪያዎችን እንዲደርስ ለ<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> የርቀት መዳረሻ እንዲያቀርብ ይፍቀዱለት።"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ሲገናኙ በዚህ ጡባዊ ላይ የተጫኑ መተግበሪያዎችን እንዲደርስ ለ<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> የርቀት መዳረሻ እንዲያቀርብ ይፍቀዱለት።"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ሲገናኙ በዚህ መሳሪያ ላይ የተጫኑ መተግበሪያዎችን እንዲደርስ ለ<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> የርቀት መዳረሻ እንዲያቀርብ ይፍቀዱለት።"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"መሣሪያ ተሻጋሪ አገልግሎቶች"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"ይህ አገልግሎት በእርስዎ መሣሪያዎች መካከል መተግበሪያዎችን ለመልቀቅ ስራ ላይ ይውላል"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ይህን መረጃ ከስልክዎ ላይ እንዲደርስ ይፍቀዱለት"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"ማሳወቂያዎች"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"እንደ ውሎች፣ መልዕክቶች እና ፎቶዎች ያሉ መረጃዎችን ጨምሮ ሁሉንም ማሳወቂያዎች ማንበብ ይችላል"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"እንደ እውቂያዎች፣ መልዕክቶች እና ፎቶዎች ያሉ መረጃዎችን ጨምሮ ሁሉንም ማሳወቂያዎች ማንበብ ይችላል"</string>
<string name="permission_storage" msgid="6831099350839392343">"ፎቶዎች እና ሚዲያ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"የGoogle Play አገልግሎቶች"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"ይህ አገልግሎት ፎቶዎችን፣ ሚዲያዎችን እና ማሳወቂያዎችን ከስልክዎ ለሌሎች መሣሪያዎች ያጋራል"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"ይህ አገልግሎት ፎቶዎችን፣ ሚዲያዎችን እና ማሳወቂያዎችን ከስልክዎ ለሌሎች መሣሪያዎች ያጋራል"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ፍቀድ"</string>
<string name="consent_no" msgid="2640796915611404382">"አትፍቀድ"</string>
- <string name="consent_ok" msgid="3662376764371001106">"እሺ"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"የመተግበሪያ ፈቃዶችን ወደ የእጅ ሰዓትዎ ያስተላልፉ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"የእጅ ሰዓትዎን ማቀናበርን ለማቅለል በማዋቀር ጊዜ በእጅ ሰዓትዎ ላይ የተጫኑ መተግበሪያዎች እንደ ስልክዎ ተመሳሳይ ፈቃዶችን ይጠቀማሉ።\n\n እነዚህ ፈቃዶች የእጅ ሰዓትዎ ማይክሮፎን እና አካባቢ መዳረሻን ሊያካትቱ ይችላሉ።"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index 5c00999..573ff64 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"التطبيقات"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"بث تطبيقات هاتفك"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى هذه المعلومات من هاتفك"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بمنح الإذن بالوصول عن بُعد إلى التطبيقات المثبَّتة <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> الإذن بالوصول عن بُعد إلى التطبيقات المثبَّتة على هذا الهاتف عندما يكون متصلاً بالإنترنت."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بمنح <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> الإذن بالوصول عن بُعد إلى التطبيقات المثبَّتة على هذا الجهاز اللوحي عندما يكون متصلاً بالإنترنت."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بمنح <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> الإذن بالوصول عن بُعد إلى التطبيقات المثبَّتة على هذا الجهاز عندما يكون متصلاً بالإنترنت."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"الخدمات التي تعمل بين الأجهزة"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"تُستخدَم هذه الخدمة لبث التطبيقات بين الأجهزة."</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى هذه المعلومات من هاتفك"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"الإشعارات"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"يمكن لهذا الملف الشخصي قراءة جميع الإشعارات، بما في ذلك المعلومات، مثل جهات الاتصال والرسائل والصور."</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"يمكن لهذا الملف الشخصي قراءة جميع الإشعارات، بما في ذلك المعلومات، مثل جهات الاتصال والرسائل والصور."</string>
<string name="permission_storage" msgid="6831099350839392343">"الصور والوسائط"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"خدمات Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"تشارك هذه الخدمة الصور والوسائط والإشعارات من هاتفك إلى أجهزة أخرى."</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"تشارك هذه الخدمة الصور والوسائط والإشعارات من هاتفك إلى أجهزة أخرى."</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"السماح"</string>
<string name="consent_no" msgid="2640796915611404382">"عدم السماح"</string>
- <string name="consent_ok" msgid="3662376764371001106">"حسنًا"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"نقل أذونات التطبيقات إلى ساعتك"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"لتسهيل إعداد ساعتك، فإن التطبيقات التي يتم تثبيتها على ساعتك أثناء الإعداد ستستخدم الأذونات نفسها التي يستخدمها هاتفك.\n\n قد تشتمل هذه الأذونات على الوصول إلى ميكروفون ساعتك وبيانات موقعها الجغرافي."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index dbb5c3b..9a07302 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"এপ্"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"আপোনাৰ ফ’নৰ এপ্ ষ্ট্ৰীম কৰক"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"সংযোগ কৰিলে <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক এই ফ’নটোত ইনষ্টল কৰি থোৱা এপ্লিকেশ্বনসমূহ এক্সেছ কৰিবলৈ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ক ৰিম’ট এক্সেছ দিবলৈ দিয়ক।"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"সংযোগ কৰিলে <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক এই টেবলেটটোত ইনষ্টল কৰি থোৱা এপ্লিকেশ্বনসমূহ এক্সেছ কৰিবলৈ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ক ৰিম’ট এক্সেছ দিবলৈ দিয়ক।"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"সংযোগ কৰিলে <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক এই ডিভাইচটোত ইনষ্টল কৰি থোৱা এপ্লিকেশ্বনসমূহ এক্সেছ কৰিবলৈ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ক ৰিম’ট এক্সেছ দিবলৈ দিয়ক।"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্ৰছ-ডিভাইচ সেৱাসমূহ"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"এই সেৱাটো আপোনাৰ ডিভাইচবোৰৰ মাজত এপ্ ষ্ট্ৰীম কৰিবলৈ ব্যৱহাৰ কৰা হয়"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"জাননী"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"চুক্তি, বাৰ্তা আৰু ফট’ৰ দৰে তথ্যকে ধৰি আটাইবোৰ জাননী পঢ়িব পাৰে"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"সম্পৰ্কসূচী, বাৰ্তা আৰু ফট’ৰ দৰে তথ্যকে ধৰি আটাইবোৰ জাননী পঢ়িব পাৰে"</string>
<string name="permission_storage" msgid="6831099350839392343">"ফট’ আৰু মিডিয়া"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play সেৱা"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"এই সেৱাটোৱে আপোনাৰ ফ\'নৰ পৰা অন্য ডিভাইচলৈ ফট’, মিডিয়া আৰু জাননী শ্বেয়াৰ কৰে"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"এই সেৱাটোৱে আপোনাৰ ফ\'নৰ পৰা অন্য ডিভাইচলৈ ফট’, মিডিয়া আৰু জাননী শ্বেয়াৰ কৰে"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইচ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিয়ক"</string>
<string name="consent_no" msgid="2640796915611404382">"অনুমতি নিদিব"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ঠিক আছে"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"আপোনাৰ ঘড়ীলৈ এপৰ অনুমতিসমূহ স্থানান্তৰ কৰক"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"আপোনাৰ ঘড়ীটো ছেটআপ কৰাটো অধিক সহজ কৰি তুলিবলৈ, এয়া কৰাৰ সময়ত আপোনাৰ ঘড়ীটোত ইনষ্টল কৰি থোৱা এপ্সমূহে আপোনাৰ ফ’নৰ দৰে একেই অনুমতিসমূহ ব্যৱহাৰ কৰিব।\n\n এই অনুমতিসমূহত আপোনাৰ ঘড়ীৰ মাইক্ৰ’ফ’ন আৰু অৱস্থানৰ এক্সেছ অন্তৰ্ভুক্ত হ’ব পাৰে।"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index a0b5b8c..4592e88 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Tətbiqlər"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun tətbiqlərini yayımlayın"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazının qoşulduqda bu telefonda quraşdırılmış tətbiqlərə uzaqdan giriş icazəsi verməsinə imkan verin."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazının qoşulduqda bu planşetdə quraşdırılmış tətbiqlərə uzaqdan giriş icazəsi verməsinə imkan verin."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazının qoşulduqda bu cihazda quraşdırılmış tətbiqlərə uzaqdan giriş icazəsi verməsinə imkan verin."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlararası xidmətlər"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Bu xidmət cihazlarınız arasında tətbiqləri yayımlamaq üçün istifadə olunur"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Bildirişlər"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Bütün bildirişləri, o cümlədən müqavilələr, mesajlar və fotolar kimi məlumatları oxuya bilər"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Bütün bildirişləri, o cümlədən kontaktlar, mesajlar və fotolar kimi məlumatları oxuya bilər"</string>
<string name="permission_storage" msgid="6831099350839392343">"Foto və media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play xidmətləri"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Bu xidmət telefonunuzdakı foto, media və bildirişləri digər cihazlarla paylaşır"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Bu xidmət telefonunuzdakı foto, media və bildirişləri digər cihazlarla paylaşır"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"İcazə verin"</string>
<string name="consent_no" msgid="2640796915611404382">"İcazə verməyin"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Tətbiq icazələrini saatınıza köçürün"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Saatınızı ayarlamağı asanlaşdırmaq üçün ayarlama zamanı saatınızda quraşdırılmış tətbiqlər telefonunuzla eyni icazələrdən istifadə edəcək.\n\n Bu icazələrə saatınızın mikrofonuna və məkanına giriş daxil ola bilər."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index 78cac0a..3e9a5a3 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Strimujte aplikacije na telefonu"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama sa telefona"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Dozvolite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da daljinski pristupa aplikacijama instaliranim na telefonu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> kada je povezan."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Dozvolite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da daljinski pristupa aplikacijama instaliranim na tabletu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> kada je povezan."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Dozvolite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da daljinski pristupa aplikacijama instaliranim na uređaju <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> kada je povezan."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na više uređaja"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ova usluga se koristi za strimovanje aplikacija između uređaja"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama sa telefona"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Obaveštenja"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Može da čita sva obaveštenja, uključujući informacije poput ugovora, poruka i slika"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Može da čita sva obaveštenja, uključujući informacije poput kontakata, poruka i slika"</string>
<string name="permission_storage" msgid="6831099350839392343">"Slike i mediji"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Ova usluga deli slike, medijski sadržaj i obaveštenja sa telefona na druge uređaje"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Ova usluga deli slike, medijski sadržaj i obaveštenja sa telefona na druge uređaje"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne dozvoli"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Potvrdi"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prenesite dozvole za aplikacije na sat"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Da bismo pojednostavili podešavanje sata, aplikacije instalirane na satu tokom podešavanja će koristiti iste dozvole kao telefon.\n\n Te dozvole mogu da obuhvataju pristup mikrofonu i lokaciji sata."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index ed521b1..c89410777 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Праграмы"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Трансліруйце змесціва праграм з вашага тэлефона"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> атрымліваць аддалены доступ да праграм, усталяваных на тэлефоне <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> (калі тэлефон падключаны)."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> атрымліваць аддалены доступ да праграм, усталяваных на планшэце <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> (калі планшэт падключаны)."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> атрымліваць аддалены доступ да праграм, усталяваных на прыладзе <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> (калі прылада падключана)."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сэрвісы для некалькіх прылад"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Гэты сэрвіс выкарыстоўваецца для перадачы праграм плынню паміж прыладамі"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Апавяшчэнні"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Можа счытваць усе апавяшчэнні, уключаючы паведамленні, фота і інфармацыю пра кантакты"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Можа счытваць усе апавяшчэнні, уключаючы паведамленні, фота і інфармацыю пра кантакты"</string>
<string name="permission_storage" msgid="6831099350839392343">"Фота і медыяфайлы"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сэрвісы Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Гэты сэрвіс абагульвае з іншымі прыладамі фота, медыяфайлы і апавяшчэнні, якія захоўваюцца на вашым тэлефоне"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Гэты сэрвіс абагульвае з іншымі прыладамі фота, медыяфайлы і апавяшчэнні, якія захоўваюцца на вашым тэлефоне"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Дазволіць"</string>
<string name="consent_no" msgid="2640796915611404382">"Не дазваляць"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ОК"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Перанос дазволаў праграм на ваш гадзіннік"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Для праграм, усталяваных на гадзіннік падчас наладжвання, будуць дзейнічаць тыя самыя дазволы, што і на тэлефоне.\n\n Так гадзіннік можа атрымаць доступ да мікрафона і даных пра месцазнаходжанне."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index fe65bda4..110a221 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Приложения"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Поточно предаване на приложенията на телефона ви"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Разрешете на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да осъществява достъп до тази информация от телефона ви"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Разрешете на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да предоставя на <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> отдалечен достъп до приложенията, инсталирани на този телефон, когато има установена връзка."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Разрешете на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да предоставя на <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> отдалечен достъп до приложенията, инсталирани на този таблет, когато има установена връзка."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Разрешете на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да предоставя на <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> отдалечен достъп до приложенията, инсталирани на това устройство, когато има установена връзка."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуги за различни устройства"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Тази услуга служи за поточно предаване на приложения между устройствата ви"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Разрешете на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да осъществява достъп до тази информация от телефона ви"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Известия"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Може да чете всички известия, включително различна информация, като например договори, съобщения и снимки"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Може да чете всички известия, включително различна информация, като например контакти, съобщения и снимки"</string>
<string name="permission_storage" msgid="6831099350839392343">"Снимки и мултимедия"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Услуги за Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Тази услуга споделя с други устройства снимки, мултимедия и известия от телефона ви"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Тази услуга споделя с други устройства снимки, мултимедия и известия от телефона ви"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Разрешаване"</string>
<string name="consent_no" msgid="2640796915611404382">"Забраняване"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Прехвърляне на разрешенията за приложенията към часовника"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"За по-лесно конфигуриране на часовника ви приложенията, инсталирани на него по време на настройването, ще използват същите разрешения като предоставените на телефона ви.\n\nТе може да включват достъп до микрофона и местоположението на часовника ви."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 58c6c26..fb1ede0 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"অ্যাপ"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"আপনার ফোনের অ্যাপ স্ট্রিমিংয়ের মাধ্যমে কাস্ট করুন"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"আপনার ফোন থেকে <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> অ্যাপকে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> কে <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>এ দূরবর্তী অ্যাক্সেস প্রদান করতে দিন যাতে কানেক্ট থাকাকালীন এই ফোনে ইনস্টল করা অ্যাপ্লিকেশনগুলিতে অ্যাক্সেস করা যায়।"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> কে <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>এ দূরবর্তী অ্যাক্সেস প্রদান করতে দিন যাতে কানেক্ট থাকাকালীন এই ট্যাবলেটে ইনস্টল করা অ্যাপ্লিকেশনগুলিতে অ্যাক্সেস করা যায়।"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> কে <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>এ দূরবর্তী অ্যাক্সেস প্রদান করতে দিন যাতে কানেক্ট থাকাকালীন এই ডিভাইসে ইনস্টল করা অ্যাপ্লিকেশনগুলিতে অ্যাক্সেস করা যায়।"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্রস-ডিভাইস পরিষেবা"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"আপনার ডিভাইসের মধ্যে অ্যাপ স্ট্রিম করার জন্য এই পরিষেবা ব্যবহার করা হয়"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"আপনার ফোন থেকে <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-কে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"বিজ্ঞপ্তি"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"চুক্তি, মেসেজ ও ফটোর সহ সব বিজ্ঞপ্তি পড়তে পারে"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"সব বিজ্ঞপ্তি পড়তে পারবে, যার মধ্যে পরিচিতি, মেসেজ ও ফটোর মতো তথ্য অন্তর্ভুক্ত"</string>
<string name="permission_storage" msgid="6831099350839392343">"ফটো ও মিডিয়া"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play পরিষেবা"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"এই পরিষেবা আপনার ফোন থেকে অন্যান্য ডিভাইসে ফটো, মিডিয়া ও বিজ্ঞপ্তি শেয়ার করে"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"এই পরিষেবা আপনার ফোন থেকে অন্যান্য ডিভাইসে ফটো, মিডিয়া ও বিজ্ঞপ্তি শেয়ার করে"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিন"</string>
<string name="consent_no" msgid="2640796915611404382">"অনুমতি দেবেন না"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ঠিক আছে"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"অ্যাপকে দেওয়া অনুমতি আপনার ঘড়িতে ট্রান্সফার করুন"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ঘড়ি আরও সহজে সেট আপ করতে, সেট আপ চলাকালীন আপনার ঘড়িতে ইনস্টল করা অ্যাপ ফোনের মতো একই অনুমতি ব্যবহার করবে।\n\n এইসব অনুমতির মধ্যে আপনার ঘড়ির মাইক্রোফোন ও লোকেশন সম্পর্কে তথ্যের অ্যাক্সেস অন্তর্ভুক্ত থাকতে পারে।"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index 1ce8944..eff7709 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Prenosite aplikacije s telefona"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da aplikacija <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama s telefona"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> omogući daljinski pristup uređaju <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> radi pristupanja aplikacijama instaliranim na ovom telefonu kada je povezan s mrežom."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> omogući daljinski pristup uređaju <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> radi pristupanja aplikacijama instaliranim na ovom tabletu kada je povezan s mrežom."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> omogući daljinski pristup uređaju <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> radi pristupanja aplikacijama instaliranim na njemu kada je povezan s mrežom."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluga na više uređaja"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ova usluga se koristi za prijenos aplikacija između vaših uređaja"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Dozvolite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa ovim informacijama s vašeg telefona"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Obavještenja"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Može čitati sva obavještenja, uključujući informacije kao što su kontakti, poruke i fotografije"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Može čitati sva obavještenja, uključujući informacije kao što su kontakti, poruke i fotografije"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Ova usluga dijeli fotografije, medijski sadržaj i obavještenja s vašeg telefona na druge uređaje"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Ova usluga dijeli fotografije, medijski sadržaj i obavještenja s vašeg telefona na druge uređaje"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
<string name="consent_no" msgid="2640796915611404382">"Nemoj dozvoliti"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Uredu"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prijenos odobrenja za aplikaciju na sat"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Radi lakšeg postavljanja sata, aplikacije instalirane na satu tokom postavljanja će koristiti ista odobrenja kao i na telefonu.\n\n Ta odobrenja mogu uključivati pristup mikrofonu i lokaciji sata."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 0b18476..cfa9ba2 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplicacions"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Reprodueix en continu aplicacions del telèfon"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> accedeixi a aquesta informació del telèfon"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> proporcioni accés remot a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> per accedir a les aplicacions instal·lades en aquest telèfon quan estigui connectat."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> proporcioni accés remot a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> per accedir a les aplicacions instal·lades en aquesta tauleta quan estigui connectada."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> proporcioni accés remot a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> per accedir a les aplicacions instal·lades en aquest dispositiu quan estigui connectat."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serveis multidispositiu"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Aquest servei s\'utilitza per reproduir en continu aplicacions entre dispositius"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> accedeixi a aquesta informació del telèfon"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notificacions"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Pot llegir totes les notificacions, inclosa informació com ara els contactes, els missatges i les fotos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Pot llegir totes les notificacions, inclosa informació com ara els contactes, els missatges i les fotos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotos i contingut multimèdia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Serveis de Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Aquest servei comparteix fotos, contingut multimèdia i notificacions amb altres dispositius des del teu telèfon"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Aquest servei comparteix fotos, contingut multimèdia i notificacions amb altres dispositius des del teu telèfon"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permet"</string>
<string name="consent_no" msgid="2640796915611404382">"No permetis"</string>
- <string name="consent_ok" msgid="3662376764371001106">"D\'acord"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfereix els permisos de les aplicacions al teu rellotge"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Per facilitar la configuració del rellotge, les aplicacions instal·lades al rellotge durant la configuració utilitzaran els mateixos permisos que al teu telèfon.\n\n Aquests permisos poden incloure l\'accés al micròfon i a la ubicació del rellotge."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index f89f17e..4781361 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplikace"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Streamujte aplikace v telefonu"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Povolte aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> přístup k těmto informacím z vašeho telefonu"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Povolit aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> poskytovat <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> vzdálený přístup k aplikacím nainstalovaným v tomto telefonu, když je připojen."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Povolit aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> poskytovat <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> vzdálený přístup k aplikacím nainstalovaným v tomto tabletu, když je připojen."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Povolit aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> poskytovat <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> vzdálený přístup k aplikacím nainstalovaným v tomto zařízení, když je připojeno."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pro více zařízení"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Tato služba slouží ke streamování aplikací mezi zařízeními"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Povolte aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> přístup k těmto informacím z vašeho telefonu"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Oznámení"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Může číst veškerá oznámení včetně informací, jako jsou kontakty, zprávy a fotky"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Může číst veškerá oznámení včetně informací, jako jsou kontakty, zprávy a fotky"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotky a média"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Tato služba sdílí fotky, média a oznámení z telefonu do ostatních zařízení"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Tato služba sdílí fotky, média a oznámení z telefonu do ostatních zařízení"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Povolit"</string>
<string name="consent_no" msgid="2640796915611404382">"Nepovolovat"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Přesunout oprávnění aplikací do hodinek"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Abychom vám usnadnili nastavení hodinek, aplikace nainstalované do hodinek během úvodního nastavení budou používat stejná oprávnění jako váš telefon.\n\n Tato oprávnění mohou zahrnovat přístup k mikrofonu a poloze hodinek."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index e366bb9..41bbca5 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Stream din telefons apps"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Giv <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> adgang til disse oplysninger fra din telefon"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Giver <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilladelse til at fjernstyre apps, som er installeret på <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>, når telefonen har forbindelse til internettet."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Giver <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilladelse til at fjernstyre apps, som er installeret på <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>, når tabletten har forbindelse til internettet."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Giver <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilladelse til at fjernstyre apps, som er installeret på <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>, når enheden har forbindelse til internettet."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester, som kan tilsluttes en anden enhed"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Denne tjeneste anvendes til at caste apps mellem dine enheder"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Tillad, at <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> får adgang til disse oplysninger fra din telefon"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notifikationer"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Kan læse alle notifikationer, herunder oplysninger som f.eks. kontakter, beskeder og billeder"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Kan læse alle notifikationer, herunder oplysninger som f.eks. kontakter, beskeder og billeder"</string>
<string name="permission_storage" msgid="6831099350839392343">"Billeder og medier"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Denne tjeneste deler billeder, medier og notifikationer fra din telefon til andre enheder"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Denne tjeneste deler billeder, medier og notifikationer fra din telefon til andre enheder"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Tillad"</string>
<string name="consent_no" msgid="2640796915611404382">"Tillad ikke"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Overfør apptilladelser til dit ur"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"For at gøre det nemmere at konfigurere dit ur vil de apps, der installeres under konfigurationen, anvende de samme tilladelser som din telefon.\n\n Disse tilladelser kan omfatte adgang til dit urs mikrofon og lokation."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index 440e06b..d8834a2 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Smartphone-Apps streamen"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Besteht eine Verbindung, darf <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> Remotezugriff auf die auf diesem Smartphone installierten Apps geben."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Besteht eine Verbindung, darf <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> Remotezugriff auf die auf diesem Tablet installierten Apps geben."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Besteht eine Verbindung, darf <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> Remotezugriff auf die auf diesem Gerät installierten Apps geben."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Geräteübergreifende Dienste"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Dieser Dienst wird dazu verwendet, Apps zwischen deinen Geräten zu streamen"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Benachrichtigungen"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Kann alle Benachrichtigungen lesen, einschließlich Informationen wie Verträgen, Nachrichten und Fotos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Kann alle Benachrichtigungen lesen, einschließlich Informationen wie Kontakten, Nachrichten und Fotos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotos und Medien"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-Dienste"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Dieser Dienst teilt Fotos, Medien und Benachrichtigungen von deinem Smartphone mit anderen Geräten"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Dieser Dienst teilt Fotos, Medien und Benachrichtigungen von deinem Smartphone mit anderen Geräten"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Zulassen"</string>
<string name="consent_no" msgid="2640796915611404382">"Nicht zulassen"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"App-Berechtigungen auf Smartwatch übertragen"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Damit sich deine Smartwatch leichter einrichten lässt, erhalten die Apps, die während der Einrichtung auf deiner Smartwatch installiert werden, automatisch die gleichen Berechtigungen wie deine Smartphone-Apps.\n\n Zu diesen Berechtigungen kann der Zugriff auf das Mikrofon und den Standort deiner Smartwatch gehören."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 326527c..56a9633 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Εφαρμογές"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Μεταδώστε σε ροή τις εφαρμογές του τηλεφώνου σας"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Να επιτρέπεται στην εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> η πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας."</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Επιτρέψτε στην εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> να παρέχει απομακρυσμένη πρόσβαση στη συσκευή <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> κατά τη σύνδεση, προκειμένου να έχει πρόσβαση σε εφαρμογές που έχουν εγκατασταθεί σε αυτό το τηλέφωνο."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Επιτρέψτε στην εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> να παρέχει απομακρυσμένη πρόσβαση στη συσκευή <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> κατά τη σύνδεση, προκειμένου να έχει πρόσβαση σε εφαρμογές που έχουν εγκατασταθεί σε αυτό το tablet."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Επιτρέψτε στην εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> να παρέχει απομακρυσμένη πρόσβαση στη συσκευή <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> κατά τη σύνδεση, προκειμένου να έχει πρόσβαση σε εφαρμογές που έχουν εγκατασταθεί σε αυτήν τη συσκευή."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Υπηρεσίες πολλών συσκευών"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Αυτή η υπηρεσία χρησιμοποιείται για τη ροή εφαρμογών μεταξύ των συσκευών σας"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Επιτρέψτε στην εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> να έχει πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Ειδοποιήσεις"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Μπορεί να διαβάσει όλες τις ειδοποιήσεις, συμπεριλαμβανομένων πληροφοριών όπως επαφές, μηνύματα και φωτογραφίες"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Μπορεί να διαβάσει όλες τις ειδοποιήσεις, συμπεριλαμβανομένων πληροφοριών όπως επαφές, μηνύματα και φωτογραφίες"</string>
<string name="permission_storage" msgid="6831099350839392343">"Φωτογραφίες και μέσα"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Υπηρεσίες Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Αυτή η υπηρεσία κοινοποιεί φωτογραφίες, πολυμέσα και ειδοποιήσεις από το τηλέφωνό σας σε άλλες συσκευές"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Αυτή η υπηρεσία κοινοποιεί φωτογραφίες, πολυμέσα και ειδοποιήσεις από το τηλέφωνό σας σε άλλες συσκευές"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Να επιτρέπεται"</string>
<string name="consent_no" msgid="2640796915611404382">"Να μην επιτρέπεται"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Μεταφορά αδειών εφαρμογών στο ρολόι σας"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Για να είναι πιο εύκολη η ρύθμιση του ρολογιού σας, οι εφαρμογές που εγκαθίστανται στο ρολόι σας κατά τη ρύθμιση, θα χρησιμοποιούν τις ίδιες άδειες με το τηλέφωνό σας.\n\n Στις άδειες ενδέχεται να περιλαμβάνεται άδεια πρόσβασης στο μικρόφωνο και την τοποθεσία του ρολογιού σας."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index 9b8f959..cf08be0 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this phone when connected."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this tablet when connected."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this device when connected."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"This service is used to stream apps between your devices"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Can read all notifications, including information such as contracts, messages and photos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"This service shares photos, media and notifications from your phone to other devices"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"This service shares photos, media and notifications from your phone to other devices"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
<string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer app permissions to your watch"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"To make it easier to set up your watch, apps installed on your watch during setup will use the same permissions as your phone.\n\n These permissions may include access to your watch’s microphone and location."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
index 9b8f959..cf08be0 100644
--- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this phone when connected."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this tablet when connected."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this device when connected."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"This service is used to stream apps between your devices"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Can read all notifications, including information such as contracts, messages and photos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"This service shares photos, media and notifications from your phone to other devices"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"This service shares photos, media and notifications from your phone to other devices"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
<string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer app permissions to your watch"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"To make it easier to set up your watch, apps installed on your watch during setup will use the same permissions as your phone.\n\n These permissions may include access to your watch’s microphone and location."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index 9b8f959..cf08be0 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this phone when connected."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this tablet when connected."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this device when connected."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"This service is used to stream apps between your devices"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Can read all notifications, including information such as contracts, messages and photos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"This service shares photos, media and notifications from your phone to other devices"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"This service shares photos, media and notifications from your phone to other devices"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
<string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer app permissions to your watch"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"To make it easier to set up your watch, apps installed on your watch during setup will use the same permissions as your phone.\n\n These permissions may include access to your watch’s microphone and location."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index 9b8f959..cf08be0 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this phone when connected."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this tablet when connected."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this device when connected."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"This service is used to stream apps between your devices"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Can read all notifications, including information such as contracts, messages and photos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"This service shares photos, media and notifications from your phone to other devices"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"This service shares photos, media and notifications from your phone to other devices"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
<string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer app permissions to your watch"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"To make it easier to set up your watch, apps installed on your watch during setup will use the same permissions as your phone.\n\n These permissions may include access to your watch’s microphone and location."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
index 8bd1c4a..a9a9631 100644
--- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
@@ -25,27 +25,23 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this phone when connected."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this tablet when connected."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Let <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to provide <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> remote access to access to applications installed on this device when connected."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"This service is used to stream apps between your devices"</string>
+ <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media, and notifications"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Can read all notifications, including information like contracts, messages, and photos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages, and photos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"This service shares photos, media, and notifications form your phone to other devices"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"This service shares photos, media, and notifications form your phone to other devices"</string>
+ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
<string name="consent_no" msgid="2640796915611404382">"Don’t allow"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <string name="consent_back" msgid="2560683030046918882">"Back"</string>
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer app permissions to your watch"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"To make it easier to set up your watch, apps installed on your watch during setup will use the same permissions as your phone.\n\n These permissions may include access to your watch’s microphone and location."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index e5b22a2..514c2cb 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Transmitir las apps de tu teléfono"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información de tu teléfono"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> proporcione a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acceso remoto a las aplicaciones instaladas en este teléfono cuando esté conectado."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> proporcione <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acceso remoto a las aplicaciones instaladas en esta tablet cuando esté conectada."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> proporcione a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acceso remoto a las aplicaciones instaladas en este dispositivo cuando esté conectado."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Este servicio se utiliza para transmitir apps entre tus dispositivos"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información de tu teléfono"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notificaciones"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Puede leer todas las notificaciones, incluso con información como contratos, mensajes y fotos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Puede leer todas las notificaciones, incluso con información como contactos, mensajes y fotos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotos y contenido multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Este servicio comparte fotos, contenido multimedia y notificaciones de tu teléfono a otros dispositivos"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Este servicio comparte fotos, contenido multimedia y notificaciones de tu teléfono a otros dispositivos"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Aceptar"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfiere los permisos de la app a tu reloj"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para que sea más fácil configurar tu reloj, las apps que se instalen en este durante la configuración usarán los mismos permisos que tu teléfono.\n\n Es posible que estos permisos incluyan el acceso al micrófono y a la ubicación del reloj."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index 1a988e9..79e554c 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplicaciones"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Emite las aplicaciones de tu teléfono"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información desde tu teléfono"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda de forma remota a las aplicaciones instaladas en este teléfono cuando <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> esté conectado a Internet."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda de forma remota a las aplicaciones instaladas en este tablet cuando <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> esté conectado a Internet."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda de forma remota a las aplicaciones instaladas en este dispositivo cuando <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> esté conectado a Internet."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Este servicio se usa para emitir aplicaciones en otros dispositivos tuyos"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información desde tu teléfono"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notificaciones"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Puede leer todas las notificaciones, incluida información como contactos, mensajes y fotos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Puede leer todas las notificaciones, incluida información como contactos, mensajes y fotos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotos y elementos multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Este servicio comparte fotos, archivos multimedia y notificaciones de tu teléfono con otros dispositivos"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Este servicio comparte fotos, archivos multimedia y notificaciones de tu teléfono con otros dispositivos"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Aceptar"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir permisos de aplicaciones a tu reloj"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para configurar fácilmente tu reloj, las aplicaciones que instales en él durante la configuración usarán los mismos permisos que tengan en tu teléfono.\n\n Estos permisos pueden incluir acceso al micrófono y a la ubicación del reloj."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index f3b8ea9..52b0d4d 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Rakendused"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Telefoni rakenduste voogesitamine"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pääseda teie telefonis juurde sellele teabele"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> lubatakse seadmele <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> pakkuda kaugjuurdepääsu, et ühendatuna pääseda juurde sellesse telefoni installitud rakendustele."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> lubatakse seadmele <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> pakkuda kaugjuurdepääsu, et ühendatuna pääseda juurde sellesse tahvelarvutisse installitud rakendustele."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> lubatakse seadmele <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> pakkuda kaugjuurdepääsu, et ühendatuna pääseda juurde sellesse seadmesse installitud rakendustele."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Seadmeülesed teenused"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Seda teenust kasutatakse rakenduste voogesitamiseks teie seadmete vahel"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pääseda teie telefonis juurde sellele teabele"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Märguanded"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Kõikide märguannete, sealhulgas teabe, nagu kontaktid, sõnumid ja fotod, lugemine"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Kõikide märguannete, sealhulgas teabe, nagu kontaktid, sõnumid ja fotod, lugemine"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotod ja meedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play teenused"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"See teenus jagab muude seadmetega teie telefonist pärit fotosid, meediat ja märguandeid"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"See teenus jagab muude seadmetega teie telefonist pärit fotosid, meediat ja märguandeid"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"seade"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Luba"</string>
<string name="consent_no" msgid="2640796915611404382">"Ära luba"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Rakenduste lubade kellale ülekandmine"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Selleks et muuta kella seadistamine lihtsamaks, kasutavad teie kellas seadistamise ajal installitud rakendused samasid lubasid, mis neile telefonis antud on.\n\n Need load võivad hõlmata juurdepääsuluba kella mikrofonile ja asukohale."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 0d4f073..fafbe23 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplikazioak"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Igorri zuzenean telefonoko aplikazioak"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Eman informazioa telefonotik hartzeko baimena <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Utzi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> urrunetik atzitzen, telefonoa konektatuta dagoenean bertan instalatuta dauden aplikazioetarako sarbidea izateko."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Utzi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> urrunetik atzitzen, tableta konektatuta dagoenean bertan instalatuta dauden aplikazioetarako sarbidea izateko."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Utzi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> urrunetik atzitzen, gailua konektatuta dagoenean bertan instalatuta dauden aplikazioetarako sarbidea izateko."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Gailu bat baino gehiagotarako zerbitzuak"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Gailuen artean aplikazioak igortzeko erabiltzen da zerbitzua"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Eman informazio hori telefonotik hartzeko baimena <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Jakinarazpenak"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Jakinarazpen guztiak irakur ditzake; besteak beste, kontaktuak, mezuak, argazkiak eta antzeko informazioa"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Jakinarazpen guztiak irakur ditzake; besteak beste, kontaktuak, mezuak, argazkiak eta antzeko informazioa"</string>
<string name="permission_storage" msgid="6831099350839392343">"Argazkiak eta multimedia-edukia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Zerbitzuak telefonoko argazkiak, multimedia-edukia eta jakinarazpenak partekatzen ditu beste gailuekin"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Zerbitzuak telefonoko argazkiak, multimedia-edukia eta jakinarazpenak partekatzen ditu beste gailuekin"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Eman baimena"</string>
<string name="consent_no" msgid="2640796915611404382">"Ez eman baimenik"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Ados"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferitu aplikazio-baimenak erlojura"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Erlojua errazago konfiguratzeko, konfigurazio-prozesua abian zen bitartean erlojuan instalatutako aplikazioek telefonoak darabiltzan baimen berak erabiliko dituzte.\n\n Baliteke baimen horien artean erlojuaren mikrofonoa eta kokapena atzitzeko baimenak egotea."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index cb14c27..b212b5f 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"برنامهها"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"جاریسازی برنامههای تلفن"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"اجازه دادن به <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> برای دسترسی به اطلاعات تلفن"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"به <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> اجازه میدهد برای <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> دسترسی ازراهدور ارائه دهد تا دستگاه موردنظر بتواند هنگام اتصال، به برنامههای نصبشده در این تلفن دسترسی داشته باشد."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"به <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> اجازه میدهد برای <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> دسترسی ازراهدور ارائه دهد تا دستگاه موردنظر بتواند هنگام اتصال، به برنامههای نصبشده در این رایانه لوحی دسترسی داشته باشد."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"به <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> اجازه میدهد برای <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> دسترسی ازراهدور ارائه دهد تا دستگاه موردنظر بتواند هنگام اتصال، به برنامههای نصبشده در این دستگاه دسترسی داشته باشد."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"سرویسهای بیندستگاهی"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"از این سرویس برای جاریسازی برنامهها میان دستگاههایتان استفاده میشود"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> مجاز میشود به این اطلاعات در دستگاهتان دسترسی پیدا کند"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"اعلانها"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"میتواند همه اعلانها، ازجمله اطلاعاتی مثل قراردادها، پیامها، و عکسها را بخواند"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"میتواند همه اعلانها، ازجمله اطلاعاتی مثل مخاطبین، پیامها، و عکسها را بخواند"</string>
<string name="permission_storage" msgid="6831099350839392343">"عکسها و رسانهها"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"خدمات Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"این سرویس عکسها، رسانه، و اعلانهای تلفن را با دستگاههای دیگر همرسانی میکند"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"این سرویس عکسها، رسانه، و اعلانهای تلفن را با دستگاههای دیگر همرسانی میکند"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"مجاز است"</string>
<string name="consent_no" msgid="2640796915611404382">"مجاز نبودن"</string>
- <string name="consent_ok" msgid="3662376764371001106">"تأیید"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"انتقال اجازههای برنامه به ساعت"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"برای آسانتر کردن راهاندازی ساعت، برنامههای نصبشده در ساعت درحین راهاندازی از همان اجازههای تلفن استفاده خواهند کرد.\n\n ممکن است این اجازهها شامل دسترسی به میکروفون و مکان ساعت باشد."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index a1c15f1..cde3864 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Sovellukset"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Striimaa puhelimen sovelluksia"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Salli, että <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> saa pääsyn näihin puhelimesi tietoihin"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Salli, että <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> voi saada sovellukselta (<strong><xliff:g id="APP_NAME">%1$s</xliff:g>) etäpääsyoikeuden tälle puhelimelle asennettuihin sovelluksiin, kun laitteet on yhdistetty."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Salli, että <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> voi saada sovellukselta (<strong><xliff:g id="APP_NAME">%1$s</xliff:g>) etäpääsyoikeuden tälle tabletille asennettuihin sovelluksiin, kun laitteet on yhdistetty."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Salli, että <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> voi saada sovellukselta (<strong><xliff:g id="APP_NAME">%1$s</xliff:g>) etäpääsyoikeuden tälle laitteelle asennettuihin sovelluksiin, kun laitteet on yhdistetty."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Laitteidenväliset palvelut"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Palvelua käytetään sovellusten striimaukseen laitteiden välillä"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Salli pääsy tähän tietoon puhelimellasi: <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Ilmoitukset"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Voi lukea kaikkia ilmoituksia, kuten sopimuksiin, viesteihin ja kuviin liittyviä tietoja"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Voi lukea kaikkia ilmoituksia, esim. kontakteihin, viesteihin ja kuviin liittyviä tietoja"</string>
<string name="permission_storage" msgid="6831099350839392343">"Kuvat ja media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Palvelut"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Palvelu jakaa kuvia, mediaa ja ilmoituksia puhelimelta muille laitteille"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Palvelu jakaa kuvia, mediaa ja ilmoituksia puhelimelta muille laitteille"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"laite"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Salli"</string>
<string name="consent_no" msgid="2640796915611404382">"Älä salli"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Siirrä sovellusluvat kelloon"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Sovellukset, jotka on asennettu kelloon käyttöönoton aikana, käyttävät samoja lupia kuin puhelin. Näin kello on helpompi ottaa käyttöön.\n\n Näihin lupiin saattaa kuulua pääsy kellon mikrofoniin ja sijaintiin."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index 5bc0439..3b2eeff 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Applications"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Diffusez les applications de votre téléphone"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Autorisez <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations à partir de votre téléphone"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Permettez à l\'application <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> de donner à l\'appareil <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> un accès à distance aux applications installées sur ce téléphone lorsqu\'il est connecté."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Permettez à l\'application <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> de donner à l\'appareil <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> un accès à distance aux applications installées sur cette tablette lorsqu\'elle est connectée."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Permettez à l\'application <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> de donner à l\'appareil <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> un accès à distance aux applications installées sur cet appareil lorsqu\'il est connecté."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Services multiappareils"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ce service est utilisé pour diffuser des applications entre vos appareils"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorisez <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations à partir de votre téléphone"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Peut lire toutes les notifications, y compris les renseignements tels que les contacts, les messages et les photos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Peut lire toutes les notifications, y compris les renseignements tels que les contacts, les messages et les photos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Photos et fichiers multimédias"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Ce service partage des photos, du contenu multimédia et des notifications à partir de votre téléphone vers d\'autres appareils"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Ce service partage des photos, du contenu multimédia et des notifications à partir de votre téléphone vers d\'autres appareils"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transférer les autorisations de l\'application à votre montre"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Pour faciliter la configuration de votre montre, les applications installées sur celle-ci reprennent les mêmes autorisations que celles installées sur votre téléphone.\n\n Ces autorisations peuvent comprendre l\'accès au microphone et à la position de votre montre."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index acf4cd6..9c54bac 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Applis"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Caster les applis de votre téléphone"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations depuis votre téléphone"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à distance aux applis installées sur <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> quand ce téléphone est connecté à Internet."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à distance aux applis installées sur <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> quand cette tablette est connectée à Internet."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à distance aux applis installées sur <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> quand cet appareil est connecté à Internet."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Services inter-appareils"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ce service est utilisé pour caster des applis d\'un appareil à l\'autre"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations depuis votre téléphone"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Peut lire toutes les notifications, y compris des informations, comme les contacts, messages et photos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Peut lire toutes les notifications, y compris des informations comme les contacts, messages et photos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Photos et contenus multimédias"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Ce service partage les photos, les contenus multimédias et les notifications de votre téléphone vers d\'autres appareils"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Ce service partage les photos, les contenus multimédias et les notifications de votre téléphone vers d\'autres appareils"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transférer les autorisations de l\'appli vers la montre"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Pour que votre montre soit plus facile à configurer, les applis qui y sont installées pendant la configuration utiliseront les mêmes autorisations que votre téléphone.\n\n Il peut s\'agir, par exemple, de l\'accès au micro et à la position de votre montre."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index d5f8515..275d7dc 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplicacións"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Emite as aplicacións do teu teléfono"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que a aplicación <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información desde o teu teléfono"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> lle outorgue a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acceso remoto a aplicacións instaladas neste teléfono cando teña conexión a Internet."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> lle outorgue a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acceso remoto a aplicacións instaladas nesta tableta cando teña conexión a Internet."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> lle outorgue a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acceso remoto a aplicacións instaladas neste dispositivo cando teña conexión a Internet."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizos multidispositivo"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Este servizo utilízase para reproducir aplicacións en tempo real entre os teus dispositivos"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información desde o teu teléfono"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notificacións"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Pode ler todas as notificacións (que poden incluír información como contactos, mensaxes e fotos)"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificacións (que poden incluír información como contactos, mensaxes e fotos)"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotos e contido multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servizos de Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Este servizo comparte con outros dispositivos as fotos, o contido multimedia e as notificacións do teu teléfono"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Este servizo comparte con outros dispositivos as fotos, o contido multimedia e as notificacións do teu teléfono"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Non permitir"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Aceptar"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir os permisos de aplicacións ao reloxo"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para que che resulte máis doado configurar o reloxo, as aplicacións que instales nel durante a configuración usarán os mesmos permisos que o teléfono.\n\n Entre estes permisos poden estar incluídos os de acceso ao micrófono e á localización do teléfono."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index adfc6a0..a4a1cc4 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"ઍપ"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"તમારા ફોનની ઍપ સ્ટ્રીમ કરો"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને મંજૂરી આપો"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"જ્યારે કનેક્ટ કરવામાં આવે, ત્યારે આ ફોન પર ઇન્સ્ટૉલ કરવામાં આવેલી ઍપ્લિકેશનોનો રિમોટ ઍક્સેસ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ને પ્રદાન કરવા દો."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"જ્યારે કનેક્ટ કરવામાં આવે, ત્યારે આ ટૅબ્લેટ પર ઇન્સ્ટૉલ કરવામાં આવેલી ઍપ્લિકેશનોનો રિમોટ ઍક્સેસ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ને પ્રદાન કરવા દો."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"જ્યારે કનેક્ટ કરવામાં આવે, ત્યારે આ ડિવાઇસ પર ઇન્સ્ટૉલ કરવામાં આવેલી ઍપ્લિકેશનોનો રિમોટ ઍક્સેસ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ને પ્રદાન કરવા દો."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ક્રોસ-ડિવાઇસ સેવાઓ"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"આ સેવાનો ઉપયોગ તમારા ડિવાઇસ વચ્ચે ઍપ સ્ટ્રીમ કરવા માટે કરવામાં આવે છે"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને મંજૂરી આપો"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"નોટિફિકેશન"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"સંપર્કો, મેસેજ અને ફોટા જેવી માહિતી સહિતના બધા નોટિફિકેશન વાંચી શકે છે"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"સંપર્કો, મેસેજ અને ફોટા જેવી માહિતી સહિતના બધા નોટિફિકેશન વાંચી શકે છે"</string>
<string name="permission_storage" msgid="6831099350839392343">"ફોટા અને મીડિયા"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play સેવાઓ"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"આ સેવા ફોટા, મીડિયા અને નોટિફિકેશનને તમારા ફોન પરથી અન્ય ડિવાઇસ પર શેર કરે છે"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"આ સેવા ફોટા, મીડિયા અને નોટિફિકેશનને તમારા ફોન પરથી અન્ય ડિવાઇસ પર શેર કરે છે"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ડિવાઇસ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"મંજૂરી આપો"</string>
<string name="consent_no" msgid="2640796915611404382">"મંજૂરી આપશો નહીં"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ઓકે"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"તમારી ઘડિયાળમાં ઍપ પરવાનગીઓ ટ્રાન્સફર કરો"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"તમારી ઘડિયાળનું સેટઅપ કરવાનું સરળ બનાવવા માટે, સેટઅપ દરમિયાન તમારી ઘડિયાળ પર ઇન્સ્ટૉલ કરેલી ઍપ દ્વારા તમારા ફોન પર મળેલી પરવાનગીઓનો ઉપયોગ કરવામાં આવશે.\n\n આ પરવાનગીઓમાં તમારી ઘડિયાળના માઇક્રોફોન અને સ્થાન સંબંધિત માહિતીનો ઍક્સેસ શામેલ હોઈ શકે છે."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index 71c5f12..4e9c838 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"ऐप्लिकेशन"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"अपने फ़ोन के ऐप्लिकेशन को स्ट्रीम करें"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"कनेक्ट होने पर, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> के रिमोट ऐक्सेस की अनुमति दें, ताकि इस फ़ोन पर इंस्टॉल किए गए ऐप्लिकेशन ऐक्सेस किए जा सकें."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"कनेक्ट होने पर, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> के रिमोट ऐक्सेस की अनुमति दें, ताकि इस टैबलेट पर इंस्टॉल किए गए ऐप्लिकेशन ऐक्सेस किए जा सकें."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"कनेक्ट होने पर, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> के रिमोट ऐक्सेस की अनुमति दें, ताकि इस डिवाइस पर इंस्टॉल किए गए ऐप्लिकेशन ऐक्सेस किए जा सकें."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"इस सेवा का इस्तेमाल, आपके डिवाइसों के बीच ऐप्लिकेशन कास्ट करने के लिए किया जाता है"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"सूचनाएं"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"इससे सभी सूचनाएं देखी जा सकती हैं. इसमें संपर्क, मैसेज, और फ़ोटो जैसी जानकारी शामिल है"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"इससे सभी सूचनाएं देखी जा सकती हैं. इसमें संपर्क, मैसेज, और फ़ोटो जैसी जानकारी शामिल होती है"</string>
<string name="permission_storage" msgid="6831099350839392343">"फ़ोटो और मीडिया"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवाएं"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"इस सेवा की मदद से, आपके फ़ोन से फ़ोटो, मीडिया, और सूचनाओं को दूसरे डिवाइसों के साथ शेयर किया जाता है"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"इस सेवा की मदद से, आपके फ़ोन से फ़ोटो, मीडिया, और सूचनाओं को दूसरे डिवाइसों के साथ शेयर किया जाता है"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"अनुमति दें"</string>
<string name="consent_no" msgid="2640796915611404382">"अनुमति न दें"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ठीक है"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ऐप्लिकेशन से जुड़ी अनुमतियों को अपनी वॉच में ट्रांसफ़र करें"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"वॉच को सेट अप करने की प्रोसेस को आसान बनाने के लिए, उस पर इंस्टॉल किए गए ऐप्लिकेशन को भी वही अनुमतियां मिलेंगी जो आपने उन ऐप्लिकेशन को फ़ोन पर दी होंगी.\n\n इन अनुमतियों में, आपकी वॉच के माइक्रोफ़ोन और जगह की जानकारी का ऐक्सेस शामिल हो सकता है."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index fd7e302..3c610e0 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Streaming aplikacija vašeg telefona"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Omogućite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa informacijama s vašeg telefona"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Dopustite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da telefonu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> omogući udaljeni pristup aplikacijama koje su instalirane na tom telefonu kada su povezani."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Dopustite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da tabletu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> omogući udaljeni pristup aplikacijama koje su instalirane na tom tabletu kada su povezani."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Dopustite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da uređaju <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> omogući udaljeni pristup aplikacijama koje su instalirane na tom uređaju kada su povezani."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na različitim uređajima"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ova se usluga koristi za streaming aplikacija između vaših uređaja"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Omogućite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa informacijama s vašeg telefona"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Obavijesti"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Može čitati sve obavijesti, uključujući informacije kao što su kontakti, poruke i fotografije"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Može čitati sve obavijesti, uključujući informacije kao što su kontakti, poruke i fotografije"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Usluge za Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Ova usluga dijeli fotografije, medijske sadržaje i obavijesti s vašeg telefona na druge uređaje"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Ova usluga dijeli fotografije, medijske sadržaje i obavijesti s vašeg telefona na druge uređaje"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Dopusti"</string>
<string name="consent_no" msgid="2640796915611404382">"Nemoj dopustiti"</string>
- <string name="consent_ok" msgid="3662376764371001106">"U redu"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prijenos dopuštenja aplikacije na sat"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Kako bi postavljanje sata bilo jednostavnije, aplikacije instalirane na satu će tijekom postavljanja upotrebljavati ista dopuštenja kao telefon.\n\n Ta dopuštenja mogu uključivati pristup mikrofonu i lokaciji sata."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index c9ef48a..baf0b9f 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Alkalmazások"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"A telefon alkalmazásainak streamelése"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Engedélyezheti a(z) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> alkalmazásnak, hogy a(z) <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> eszköz számára távoli hozzáférést biztosítson a telefonra telepített alkalmazásokhoz, amikor a telefon csatlakoztatva van."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Engedélyezheti a(z) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> alkalmazásnak, hogy a(z) <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> eszköz számára távoli hozzáférést biztosítson a táblagépre telepített alkalmazásokhoz, amikor a táblagép csatlakoztatva van."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Engedélyezheti a(z) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> alkalmazásnak, hogy a(z) <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> eszköz számára távoli hozzáférést biztosítson az eszközre telepített alkalmazásokhoz, amikor az eszköz csatlakoztatva van."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Többeszközös szolgáltatások"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ez a szolgáltatás az eszközök közötti alkalmazásstreamelésre szolgál"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Értesítések"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Elolvashat minden értesítést, ideértve az olyan információkat, mint a névjegyek, az üzenetek és a fotók"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Elolvashat minden értesítést, ideértve az olyan információkat, mint a névjegyek, az üzenetek és a fotók"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotók és médiatartalmak"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-szolgáltatások"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Ezzel a szolgáltatással fényképeket, médiatartalmakat és értesítéseket küldhet át a telefonjáról más eszközökre"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Ezzel a szolgáltatással fényképeket, médiatartalmakat és értesítéseket küldhet át a telefonjáról más eszközökre"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Engedélyezés"</string>
<string name="consent_no" msgid="2640796915611404382">"Tiltás"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Alkalmazásengedélyek átvitele az órára"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Az óra beállításának megkönnyítése érdekében a beállítás során az órára telepített alkalmazások ugyanazokat az engedélyeket használják majd, mint a telefonja.\n\n Ezek az engedélyek magukban foglalhatják az óra mikrofonjához és helyadataihoz való hozzáférést."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index 77c8bef..8a6ae3f 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Հավելվածներ"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Հեռարձակել հեռախոսի հավելվածները"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Թույլատրեք <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Թույլ տվեք, որ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածը կապի հաստատման դեպքում <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-ին տրամադրի այս հեռախոսում տեղադրված հավելվածներ հեռակա մուտք գործելու թույլտվություն։"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Թույլ տվեք, որ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածը կապի հաստատման դեպքում <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-ին տրամադրի այս պլանշետում տեղադրված հավելվածներ հեռակա մուտք գործելու թույլտվություն։"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Թույլ տվեք, որ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածը ինտերնետ կապի հաստատման դեպքում <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-ին տրամադրի այս սարքում տեղադրված հավելվածներ հեռակա մուտք գործելու թույլտվություն։"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Միջսարքային ծառայություններ"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Այս ծառայությունն օգտագործվում է ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Թույլատրեք <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Ծանուցումներ"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Կարող է կարդալ բոլոր ծանուցումները, ներառյալ տեղեկությունները, օրինակ՝ կոնտակտները, հաղորդագրությունները և լուսանկարները"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Կարող է կարդալ բոլոր ծանուցումները, ներառյալ տեղեկությունները, օրինակ՝ կոնտակտները, հաղորդագրությունները և լուսանկարները"</string>
<string name="permission_storage" msgid="6831099350839392343">"Լուսանկարներ և մուլտիմեդիա"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ծառայություններ"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Այս ծառայությունը ձեր հեռախոսից լուսանկարներ, մեդիա ֆայլեր և ծանուցումներ է ուղարկում այլ սարքերի"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Այս ծառայությունը ձեր հեռախոսից լուսանկարներ, մեդիա ֆայլեր և ծանուցումներ է ուղարկում այլ սարքերի"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Թույլատրել"</string>
<string name="consent_no" msgid="2640796915611404382">"Չթույլատրել"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Եղավ"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Հավելվածների թույլտվությունների տեղափոխում ժամացույց"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Կարգավորման ժամանակ ժամացույցում տեղադրված հավելվածների համար կօգտագործվեն նույն թույլտվությունները, ինչ հեռախոսում։\n\n Այդ թույլտվությունները կարող են ներառել ժամացույցի խոսափողի կամ տեղադրության տվյալների օգտագործումը։"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index ff4363c..2259679 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplikasi"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Melakukan streaming aplikasi ponsel Anda"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> untuk mengakses informasi ini dari ponsel Anda"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> memberikan akses jarak jauh ke <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> guna mengakses aplikasi yang diinstal di ponsel ini saat terhubung."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> memberikan akses jarak jauh ke <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> guna mengakses aplikasi yang diinstal di tablet ini saat terhubung."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> memberikan akses jarak jauh ke <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> guna mengakses aplikasi yang diinstal di perangkat ini saat terhubung."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Layanan lintas perangkat"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Layanan ini digunakan untuk menstreaming aplikasi antar-perangkat"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses informasi ini dari ponsel Anda"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notifikasi"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Dapat membaca semua notifikasi, termasuk informasi seperti kontak, pesan, dan foto"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Dapat membaca semua notifikasi, termasuk informasi seperti kontak, pesan, dan foto"</string>
<string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Layanan Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Layanan ini membagikan foto, media, dan notifikasi dari ponsel Anda ke perangkat lain"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Layanan ini membagikan foto, media, dan notifikasi dari ponsel Anda ke perangkat lain"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Izinkan"</string>
<string name="consent_no" msgid="2640796915611404382">"Jangan izinkan"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Oke"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer izin aplikasi ke smartwatch"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Untuk mempermudah penyiapan smartwatch, aplikasi yang diinstal di smartwatch selama penyiapan akan menggunakan izin yang sama dengan ponsel.\n\n Izin ini dapat meliputi akses ke mikrofon dan lokasi smartwatch."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index b8646c7..3e55948 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Forrit"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Streymdu forritum símans"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Veita <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aðgang að þessum upplýsingum úr símanum þínum"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Leyfa <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> að veita <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> fjaraðgang að forritum sem eru sett upp í þessum síma þegar tenging er á."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Leyfa <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> að veita <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> fjaraðgang að forritum sem eru sett upp í þessari spjaldtölvu þegar tenging er á."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Leyfa <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> að veita <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> fjaraðgang að forritum sem eru sett upp í þessu tæki þegar tenging er á."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Þjónustur á milli tækja"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Þessi þjónusta er notuð til að streyma forritum á milli tækjanna þinna"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Veita <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aðgang að þessum upplýsingum úr símanum þínum"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Tilkynningar"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Getur lesið allar tilkynningar, þar á meðal upplýsingar á borð við samninga, skilaboð og myndir"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Getur lesið allar tilkynningar, þar á meðal upplýsingar á borð við tengiliði skilaboð og myndir"</string>
<string name="permission_storage" msgid="6831099350839392343">"Myndir og efni"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Þjónusta Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Þessi þjónusta deilir myndum, margmiðlunarefni og tilkynningum úr símanum yfir í önnur tæki"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Þessi þjónusta deilir myndum, margmiðlunarefni og tilkynningum úr símanum yfir í önnur tæki"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Leyfa"</string>
<string name="consent_no" msgid="2640796915611404382">"Ekki leyfa"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Í lagi"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Flytja heimildir forrita yfir í úrið"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Til að auðvelda uppsetningu úrsins munu forrit sem eru sett upp í úrinu við uppsetningu nota sömu heimildir og stilltar eru í símanum.\n\n Þessar heimildir kunna að fela í sér aðgang að hljóðnema og staðsetningu úrsins."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 4dfb69b..5f04e0f 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"App"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Trasmetti in streaming le app del tuo telefono"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Consenti all\'app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di accedere a queste informazioni dal tuo telefono"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Consenti all\'app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di fornire l\'accesso remoto a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> per accedere alle applicazioni installate su questo telefono quando è connesso."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Consenti all\'app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di fornire l\'accesso remoto a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> per accedere alle applicazioni installate su questo tablet quando è connesso."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Consenti all\'app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di fornire l\'accesso remoto a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> per accedere alle applicazioni installate su questo dispositivo quando è connesso."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizi cross-device"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Questo servizio viene utilizzato per trasmettere in streaming le app tra i dispositivi"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Consenti a <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di accedere a questa informazione dal tuo telefono"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notifiche"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Puoi leggere tutte le notifiche, incluse le informazioni come contatti, messaggi e foto"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Puoi leggere tutte le notifiche, incluse le informazioni come contatti, messaggi e foto"</string>
<string name="permission_storage" msgid="6831099350839392343">"Foto e contenuti multimediali"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Questo servizio condivide foto, contenuti multimediali e notifiche del telefono con altri dispositivi"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Questo servizio condivide foto, contenuti multimediali e notifiche del telefono con altri dispositivi"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Consenti"</string>
<string name="consent_no" msgid="2640796915611404382">"Non consentire"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Trasferisci le autorizzazioni app all\'orologio"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Per facilitare la configurazione dell\'orologio, le app installate su quest\'ultimo durante la configurazione useranno le stesse autorizzazioni delle app sul telefono.\n\n Queste autorizzazioni potrebbero includere l\'accesso al microfono e alla posizione dell\'orologio."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index a6373c1..d8af8aa 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"אפליקציות"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"שידור אפליקציות מהטלפון"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"מתן אישור לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> לגשת למידע הזה מהטלפון שלך"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"האפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> יכולה לספק ל-<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> גישה מרחוק כדי לגשת לאפליקציות שמותקנות בטלפון הזה כשיש חיבור."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"האפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> יכולה לספק ל-<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> גישה מרחוק כדי לגשת לאפליקציות שמותקנות בטאבלט הזה כשיש חיבור."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"האפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> יכולה לספק למכשיר <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> גישה מרחוק כדי לגשת לאפליקציות שמותקנות במכשיר הזה כשיש חיבור."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"שירותים למספר מכשירים"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"השירות הזה משמש לשידור אפליקציות בין המכשירים שברשותך"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"מתן אישור לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> לגשת למידע הזה מהטלפון שלך"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"התראות"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"גישה לכל ההתראות, כולל מידע כמו אנשי קשר, הודעות ותמונות"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"גישת קריאה לכל ההתראות, כולל מידע כמו אנשי קשר, הודעות ותמונות."</string>
<string name="permission_storage" msgid="6831099350839392343">"תמונות ומדיה"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"השירות הזה משמש לשיתוף של תמונות, מדיה והתראות מהטלפון שלך עם מכשירים אחרים"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"השירות הזה משמש לשיתוף של תמונות, מדיה והתראות מהטלפון שלך עם מכשירים אחרים"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"יש אישור"</string>
<string name="consent_no" msgid="2640796915611404382">"אין אישור"</string>
- <string name="consent_ok" msgid="3662376764371001106">"אישור"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"העברת ההרשאות הניתנות לאפליקציות אל השעון שלך"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"כדי לפשט את הגדרת השעון, אפליקציות שמותקנות במהלך ההגדרה יקבלו את אותן הרשאות שניתנו בטלפון.\n\n ההרשאות האלה עשויות לכלול גישה למיקרופון ולמיקום של השעון."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index 392ca0a..54371c7 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"アプリ"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"スマートフォンのアプリのストリーミング"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"スマートフォンのこの情報へのアクセスを <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に許可"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"インターネット接続時に <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> がスマートフォン内にインストールされているアプリにリモートでアクセスすることを <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に許可します。"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"インターネット接続時に <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> がタブレット内にインストールされているアプリにリモートでアクセスすることを <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に許可します。"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"インターネット接続時に <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> がデバイス内にインストールされているアプリにリモートでアクセスすることを <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に許可します。"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"クロスデバイス サービス"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"本サービスは、デバイス間でのアプリのストリーミングに使用されます"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"このスマートフォンからの情報へのアクセスを <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に許可"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"通知"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"連絡先、メッセージ、写真に関する情報を含め、すべての通知を読み取ることができます"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"連絡先、メッセージ、写真に関する情報を含め、すべての通知を読み取ることができます"</string>
<string name="permission_storage" msgid="6831099350839392343">"写真とメディア"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 開発者サービス"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"本サービスは、スマートフォンから他のデバイスに写真、メディア、通知を共有します"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"本サービスは、スマートフォンから他のデバイスに写真、メディア、通知を共有します"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"許可"</string>
<string name="consent_no" msgid="2640796915611404382">"許可しない"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"スマートウォッチへのアプリの権限の移行"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"スマートウォッチのセットアップを簡単にするため、セットアップ時にスマートウォッチにインストールされたアプリに、スマートフォンと同じ権限が適用されます。\n\n これらの権限には、スマートウォッチのマイクや位置情報へのアクセス権も含まれることがあります。"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index f057b8b..f0c3dc98 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"აპები"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"თქვენი ტელეფონის აპების სტრიმინგი"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ნება დართეთ, რომ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"მიეცით <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-ს საშუალება, <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-ისთვის დაუშვას დისტანციური წვდომა ამ ტელეფონზე დაინსტალირებულ აპებზე მასთან დაკავშირებისას."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"მიეცით <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-ს საშუალება, <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-ისთვის დაუშვას დისტანციური წვდომა ამ ტაბლეტზე დაინსტალირებულ აპებზე მასთან დაკავშირებისას."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"მიეცით <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-ს საშუალება, <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-ისთვის დაუშვას დისტანციური წვდომა ამ მოწყობილობაზე დაინსტალირებულ აპებზე მასთან დაკავშირებისას."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"მოწყობილობათშორისი სერვისები"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"ეს სერვისი გამოიყენება აპების მოწყობილობებს შორის სტრიმინგისთვის"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ნება დართეთ, რომ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"შეტყობინებები"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"შეუძლია წაიკითხოს ყველა შეტყობინება, მათ შორის ისეთი ინფორმაცია, როგორიცაა კონტრაქტები, ტექსტური გზავნილები და ფოტოები"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"შეუძლია წაიკითხოს ყველა შეტყობინება, მათ შორის ისეთი ინფორმაცია, როგორიცაა კონტაქტები, ტექსტური შეტყობინებები და ფოტოები"</string>
<string name="permission_storage" msgid="6831099350839392343">"ფოტოები და მედია"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"ეს სერვისი ფოტოებს, მედიას და შეტყობინებებს აზიარებს თქვენი ტელეფონიდან სხვა მოწყობილობებზე"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"ეს სერვისი ფოტოებს, მედიას და შეტყობინებებს აზიარებს თქვენი ტელეფონიდან სხვა მოწყობილობებზე"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"დაშვება"</string>
<string name="consent_no" msgid="2640796915611404382">"არ დაიშვას"</string>
- <string name="consent_ok" msgid="3662376764371001106">"კარგი"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"აპის ნებართვების საათისთვის გადაცემა"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"საათის დაყენების გასამარტივებლად თქვენს საათში დაინსტალირებული აპები იმავე ნებართვებს გამოიყენებს, რასაც ტელეფონზე იყენებს.\n\n ეს ნებართვები, შესაძლოა, მოიცავდეს თქვენი საათის მიკროფონსა და მდებარეობაზე წვდომას."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 365020c5..6e46869 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Қолданбалар"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Телефон қолданбаларын трансляциялайды."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> желіге қосылған кезде, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына осы телефонға орнатылған қолданбаларды қашықтан пайдалануына рұқсат етіңіз."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> желіге қосылған кезде, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына осы планшетке орнатылған қолданбаларды қашықтан пайдалануына рұқсат етіңіз."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> желіге қосылған кезде, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына осы құрылғыға орнатылған қолданбаларды қашықтан пайдалануына рұқсат етіңіз."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Аралық құрылғы қызметтері"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Бұл қызмет құрылғылар арасында қолданбаларды трансляциялау үшін пайдаланылады."</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Хабарландырулар"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Барлық хабарландыруды, соның ішінде контактілер, хабарлар және фотосуреттер сияқты ақпаратты оқи алады."</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Барлық хабарландыруды, соның ішінде контактілер, хабарлар және фотосуреттер сияқты ақпаратты оқи алады."</string>
<string name="permission_storage" msgid="6831099350839392343">"Фотосуреттер мен медиафайлдар"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play қызметтері"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Бұл қызмет телефоныңыздағы фотосуреттерді, мультимедианы және хабарландыруларды басқа құрылғылармен бөліседі."</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Бұл қызмет телефоныңыздағы фотосуреттерді, мультимедианы және хабарландыруларды басқа құрылғылармен бөліседі."</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Рұқсат беру"</string>
<string name="consent_no" msgid="2640796915611404382">"Рұқсат бермеу"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Жарайды"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Қолданба рұқсаттарын сағатқа ауыстыру"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Реттеу кезінде сағатқа орнатылған қолданбалар телефондағыдай рұқсаттарды пайдаланады. Осылайша сағат оңай реттеледі.\n\n Бұл рұқсаттар сағаттың микрофоны мен геодерегін пайдалануды қамтиды."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index e1dbaf5..814b327 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"កម្មវិធី"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"បញ្ចាំងកម្មវិធីរបស់ទូរសព្ទអ្នក"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ចូលប្រើព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ផ្ដល់ការចូលប្រើពីចម្ងាយដល់ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ដើម្បីចូលប្រើកម្មវិធី ដែលបានដំឡើងនៅលើទូរសព្ទនេះ នៅពេលភ្ជាប់អ៊ីនធឺណិត។"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ផ្ដល់ការចូលប្រើពីចម្ងាយដល់ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ដើម្បីចូលប្រើកម្មវិធី ដែលបានដំឡើងនៅលើថេប្លេតនេះ នៅពេលភ្ជាប់អ៊ីនធឺណិត។"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ផ្ដល់ការចូលប្រើពីចម្ងាយដល់ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ដើម្បីចូលប្រើកម្មវិធី ដែលបានដំឡើងនៅលើឧបករណ៍នេះ នៅពេលភ្ជាប់អ៊ីនធឺណិត។"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"សេវាកម្មឆ្លងកាត់ឧបករណ៍"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"សេវាកម្មនេះត្រូវបានប្រើដើម្បីភ្ជាប់កម្មវិធីរវាងឧបករណ៍របស់អ្នក"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ចូលមើលព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"ការជូនដំណឹង"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"អាចអានការជូនដំណឹងទាំងអស់ រួមទាំងព័ត៌មានដូចជាទំនាក់ទំនង សារ និងរូបថត"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"អាចអានការជូនដំណឹងទាំងអស់ រួមទាំងព័ត៌មានដូចជាទំនាក់ទំនង សារ និងរូបថត"</string>
<string name="permission_storage" msgid="6831099350839392343">"រូបថត និងមេឌៀ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"សេវាកម្ម Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"សេវាកម្មនេះចែករំលែករូបថត មេឌៀ និងការជូនដំណឹងពីទូរសព្ទរបស់អ្នកទៅឧបករណ៍ផ្សេងទៀត"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"សេវាកម្មនេះចែករំលែករូបថត មេឌៀ និងការជូនដំណឹងពីទូរសព្ទរបស់អ្នកទៅឧបករណ៍ផ្សេងទៀត"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"អនុញ្ញាត"</string>
<string name="consent_no" msgid="2640796915611404382">"កុំអនុញ្ញាត"</string>
- <string name="consent_ok" msgid="3662376764371001106">"យល់ព្រម"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ផ្ទេរការអនុញ្ញាតកម្មវិធីទៅនាឡិការបស់អ្នក"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ដើម្បីជួយឱ្យការរៀបចំនាឡិការបស់អ្នកកាន់តែងាយស្រួល កម្មវិធីដែលបានដំឡើងនៅលើនាឡិការបស់អ្នកអំឡុងពេលរៀបចំនឹងប្រើការអនុញ្ញាតដូចគ្នានឹងទូរសព្ទរបស់អ្នកដែរ។\n\n ការអនុញ្ញាតទាំងនេះអាចរួមបញ្ចូលសិទ្ធិចូលប្រើទីតាំង និងមីក្រូហ្វូនរបស់នាឡិកាអ្នក។"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index 0d01ce7..7ba67a6 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"ಆ್ಯಪ್ಗಳು"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"ನಿಮ್ಮ ಫೋನ್ನ ಆ್ಯಪ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಿ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"ಕನೆಕ್ಟ್ ಆದಾಗ ಈ ಫೋನ್ನಲ್ಲಿ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾದ ಆ್ಯಪ್ಗಳನ್ನು ಪ್ರವೇಶಿಸುವುದಕ್ಕಾಗಿ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ಗೆ ರಿಮೋಟ್ ಪ್ರವೇಶವನ್ನು ಒದಗಿಸಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"ಕನೆಕ್ಟ್ ಆದಾಗ ಈ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾದ ಆ್ಯಪ್ಗಳನ್ನು ಪ್ರವೇಶಿಸುವುದಕ್ಕಾಗಿ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ಗೆ ರಿಮೋಟ್ ಪ್ರವೇಶವನ್ನು ಒದಗಿಸಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"ಕನೆಕ್ಟ್ ಆದಾಗ ಈ ಸಾಧನದಲ್ಲಿ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾದ ಆ್ಯಪ್ಗಳನ್ನು ಪ್ರವೇಶಿಸುವುದಕ್ಕಾಗಿ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ಗೆ ರಿಮೋಟ್ ಪ್ರವೇಶವನ್ನು ಒದಗಿಸಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ಕ್ರಾಸ್-ಸಾಧನ ಸೇವೆಗಳು"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ಈ ಸೇವೆಯನ್ನು ಬಳಸಲಾಗುತ್ತದೆ"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"ಅಧಿಸೂಚನೆಗಳು"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"ಒಪ್ಪಂದಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಫೋಟೋಗಳಂತಹ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಂತೆ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ಓದಬಹುದು"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"ಸಂಪರ್ಕಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಫೋಟೋಗಳಂತಹ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಂತೆ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ಓದಬಹುದು"</string>
<string name="permission_storage" msgid="6831099350839392343">"ಫೋಟೋಗಳು ಮತ್ತು ಮಾಧ್ಯಮ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ಸೇವೆಗಳು"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"ಈ ಸೇವೆಯು, ನಿಮ್ಮ ಫೋನ್ನಿಂದ ಇತರ ಸಾಧನಗಳಿಗೆ ಫೋಟೋಗಳು, ಮಾಧ್ಯಮ ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತದೆ"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"ಈ ಸೇವೆಯು, ನಿಮ್ಮ ಫೋನ್ನಿಂದ ಇತರ ಸಾಧನಗಳಿಗೆ ಫೋಟೋಗಳು, ಮಾಧ್ಯಮ ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತದೆ"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ಸಾಧನ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ಅನುಮತಿಸಿ"</string>
<string name="consent_no" msgid="2640796915611404382">"ಅನುಮತಿಸಬೇಡಿ"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ಸರಿ"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ಆ್ಯಪ್ ಅನುಮತಿಗಳನ್ನು ನಿಮ್ಮ ವಾಚ್ಗೆ ವರ್ಗಾವಣೆ ಮಾಡಿ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ನಿಮ್ಮ ವಾಚ್ ಸೆಟಪ್ ಮಾಡುವುದನ್ನು ಸುಲಭವಾಗಿಸಲು, ಸೆಟಪ್ನ ಸಮಯದಲ್ಲಿ ನಿಮ್ಮ ವಾಚ್ನಲ್ಲಿ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್ಗಳು, ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿನ ಅನುಮತಿಗಳನ್ನೇ ಬಳಸಿಕೊಳ್ಳುತ್ತವೆ.\n\n ಈ ಅನುಮತಿಗಳು ನಿಮ್ಮ ವಾಚ್ನ ಮೈಕ್ರೊಫೋನ್ ಮತ್ತು ಸ್ಥಳದ ಪ್ರವೇಶವನ್ನು ಒಳಗೊಳ್ಳಬಹುದು."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 2b98ce3..35ca203 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"앱"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"휴대전화의 앱을 스트리밍합니다."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 앱이 휴대전화에서 이 정보에 액세스하도록 허용합니다."</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"연결 시 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>에서 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>에 이 휴대전화에 설치된 애플리케이션에 원격으로 액세스할 수 있는 권한을 제공하도록 허용합니다."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"연결 시 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>에서 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>에 이 태블릿에 설치된 애플리케이션에 원격으로 액세스할 수 있는 권한을 제공하도록 허용합니다."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"연결 시 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>에서 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>에 이 기기에 설치된 애플리케이션에 원격으로 액세스할 수 있는 권한을 제공하도록 허용합니다."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"교차 기기 서비스"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"이 서비스는 기기 간에 앱을 스트리밍하는 데 사용됩니다."</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 앱이 휴대전화에서 이 정보에 액세스하도록 허용합니다."</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"알림"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"연락처, 메시지, 사진 등의 정보를 포함한 모든 알림을 읽을 수 있습니다."</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"연락처, 메시지, 사진 등의 정보를 포함한 모든 알림을 읽을 수 있습니다."</string>
<string name="permission_storage" msgid="6831099350839392343">"사진 및 미디어"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 서비스"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"이 서비스는 휴대전화의 사진, 미디어 및 알림을 다른 기기와 공유합니다."</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"이 서비스는 휴대전화의 사진, 미디어 및 알림을 다른 기기와 공유합니다."</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"기기"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"허용"</string>
<string name="consent_no" msgid="2640796915611404382">"허용 안함"</string>
- <string name="consent_ok" msgid="3662376764371001106">"확인"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"앱 권한을 시계로 이전"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"시계를 더 쉽게 설정하기 위해 설정하는 동안 시계에 설치된 앱에서 휴대전화와 동일한 권한을 사용합니다.\n\n 이러한 권한에는 시계의 마이크 및 위치 정보에 대한 액세스가 포함될 수 있습니다."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 1f320dd..0f1d82e 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Колдонмолор"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Телефондогу колдонмолорду алып ойнотуу"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна Интернетке туташкан <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> телефонундагы колдонмолорго алыстан кирүү мүмкүнчүлүгүн бериңиз."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна Интернетке туташкан <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> планшетиндеги колдонмолорго алыстан кирүү мүмкүнчүлүгүн бериңиз."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна Интернетке туташкан <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> түзмөгүндөгү колдонмолорго алыстан кирүү мүмкүнчүлүгүн бериңиз."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Түзмөктөр аралык кызматтар"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Бул кызмат түзмөктөрүңүздүн ортосунда колдонмолорду тышкы экранга чыгаруу үчүн колдонулат"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Билдирмелер"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Бардык билдирмелерди, анын ичинде байланыштар, билдирүүлөр жана сүрөттөр сыяктуу маалыматты окуй алат"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Бардык билдирмелерди, анын ичинде байланыштар, билдирүүлөр жана сүрөттөр сыяктуу маалыматты окуй алат"</string>
<string name="permission_storage" msgid="6831099350839392343">"Сүрөттөр жана медиа"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play кызматтары"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Бул кызмат сүрөттөрдү, медиа файлдарды жана билдирмелерди телефонуңуздан башка түзмөктөр менен бөлүшөт"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Бул кызмат сүрөттөрдү, медиа файлдарды жана билдирмелерди телефонуңуздан башка түзмөктөр менен бөлүшөт"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Уруксат берүү"</string>
<string name="consent_no" msgid="2640796915611404382">"Уруксат берилбесин"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Макул"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Колдонмонун уруксаттарын саатка өткөрүү"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Сааттын жөндөлүшүн жеңилдетүү үчүн жөндөө учурунда саатыңызга орнотулган колдонмолор телефонуңуздагы уруксаттарды колдонот.\n\n Мындай уруксаттарга саатыңыздын микрофонун же жайгашкан жерин колдонуу кириши мүмкүн."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index debbf76..e353659 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"ແອັບ"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"ສະຕຣີມແອັບຂອງໂທລະສັບທ່ານ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ອະນຸຍາດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"ໃຫ້ສິດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ເພື່ອເຂົ້າເຖິງ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ຈາກໄລຍະໄກເພື່ອເຂົ້າເຖິງແອັບພລິເຄຊັນທີ່ຕິດຕັ້ງຢູ່ໂທລະສັບນີ້ເມື່ອເຊື່ອມຕໍ່ແລ້ວ."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"ໃຫ້ສິດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ເພື່ອເຂົ້າເຖິງ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ຈາກໄລຍະໄກເພື່ອເຂົ້າເຖິງແອັບພລິເຄຊັນທີ່ຕິດຕັ້ງຢູ່ແທັບເລັດນີ້ເມື່ອເຊື່ອມຕໍ່ແລ້ວ."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"ໃຫ້ສິດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ເພື່ອເຂົ້າເຖິງ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ຈາກໄລຍະໄກເພື່ອເຂົ້າເຖິງແອັບພລິເຄຊັນທີ່ຕິດຕັ້ງຢູ່ອຸປະກອນນີ້ເມື່ອເຊື່ອມຕໍ່ແລ້ວ."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ບໍລິການຂ້າມອຸປະກອນ"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"ບໍລິການນີ້ໃຊ້ເພື່ອສະຕຣີມແອັບລະຫວ່າງອຸປະກອນຂອງທ່ານ"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ອະນຸຍາດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"ການແຈ້ງເຕືອນ"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"ສາມາດອ່ານການແຈ້ງເຕືອນທັງໝົດ, ຮວມທັງຂໍ້ມູນ ເຊັ່ນ: ລາຍຊື່ຜູ້ຕິດຕໍ່, ຂໍ້ຄວາມ ແລະ ຮູບພາບ"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"ສາມາດອ່ານການແຈ້ງເຕືອນທັງໝົດ, ຮວມທັງຂໍ້ມູນ ເຊັ່ນ: ລາຍຊື່ຜູ້ຕິດຕໍ່, ຂໍ້ຄວາມ ແລະ ຮູບພາບ"</string>
<string name="permission_storage" msgid="6831099350839392343">"ຮູບພາບ ແລະ ມີເດຍ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"ບໍລິການ Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"ບໍລິການນີ້ຈະແບ່ງປັນຮູບພາບ, ມີເດຍ ແລະ ການແຈ້ງເຕືອນຈາກໂທລະສັບຂອງທ່ານໄປຫາອຸປະກອນອື່ນ"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"ບໍລິການນີ້ຈະແບ່ງປັນຮູບພາບ, ມີເດຍ ແລະ ການແຈ້ງເຕືອນຈາກໂທລະສັບຂອງທ່ານໄປຫາອຸປະກອນອື່ນ"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ອະນຸຍາດ"</string>
<string name="consent_no" msgid="2640796915611404382">"ບໍ່ອະນຸຍາດ"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ຕົກລົງ"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ໂອນຍ້າຍການອະນຸຍາດແອັບໄປຫາໂມງຂອງທ່ານ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ເພື່ອເຮັດໃຫ້ຕັ້ງຄ່າໂມງຂອງທ່ານໄດ້ງ່າຍຂຶ້ນ, ແອັບທີ່ຕິດຕັ້ງຢູ່ໂມງຂອງທ່ານໃນລະຫວ່າງການຕັ້ງຄ່າຈະໃຊ້ການອະນຸຍາດດຽວກັນກັບໂທລະສັບຂອງທ່ານ.\n\n ການອະນຸຍາດເຫຼົ່ານີ້ອາດຮວມສິດເຂົ້າເຖິງໄມໂຄຣໂຟນ ແລະ ສະຖານທີ່ຂອງທ່ານນຳ."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index 3904ad3..c795c0d 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Programos"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Telefono programų perdavimas srautu"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Leisti <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pasiekti šią informaciją iš jūsų telefono"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Leiskite <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prisijungus suteikti <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> nuotolinę prieigą prie šiame telefone įdiegtų programų."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Leiskite <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prisijungus suteikti <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> nuotolinę prieigą prie šiame planšetiniame kompiuteryje įdiegtų programų."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Leiskite <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prisijungus suteikti <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> nuotolinę prieigą prie šiame įrenginyje įdiegtų programų."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Pasl. keliuose įrenginiuose"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ši paslauga naudojama perduoti programas srautu tarp jūsų įrenginių"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Leisti <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pasiekti šią informaciją iš jūsų telefono"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Pranešimai"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Galima skaityti visus pranešimus, įskaitant tokią informaciją kaip sutartys, pranešimai ir nuotraukos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Galima skaityti visus pranešimus, įskaitant tokią informaciją kaip kontaktai, pranešimai ir nuotraukos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Nuotraukos ir medija"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"„Google Play“ paslaugos"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Naudojant šią paslaugą, telefone esančias nuotraukas, mediją ir pranešimus galima bendrinti su kitais įrenginiais"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Naudojant šią paslaugą, telefone esančias nuotraukas, mediją ir pranešimus galima bendrinti su kitais įrenginiais"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Leisti"</string>
<string name="consent_no" msgid="2640796915611404382">"Neleisti"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Gerai"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Laikrodžio programų perkėlimo leidimai"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Kad būtų lengviau nustatyti laikrodį, jame atliekant sąranką įdiegtoms programoms bus naudojami tie patys leidimai kaip jūsų telefone.\n\n Šie leidimai gali apimti prieigą prie laikrodžio mikrofono ir vietovės."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index 71bc792..6ee557b 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Lietotnes"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Var straumēt jūsu tālruņa lietotnes"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> piekļūt šai informācijai no jūsu tālruņa"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> nodrošināt attālu piekļuvi tālrunim <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>, lai piekļūtu šajā tālrunī instalētajām lietojumprogrammām, kamēr ir izveidots savienojums."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> nodrošināt attālu piekļuvi planšetdatoram <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>, lai piekļūtu šajā planšetdatorā instalētajām lietojumprogrammām, kamēr ir izveidots savienojums."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> nodrošināt attālu piekļuvi ierīcei <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>, lai piekļūtu šajā ierīcē instalētajām lietojumprogrammām, kamēr ir izveidots savienojums."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Vairāku ierīču pakalpojumi"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Šis pakalpojums tiek izmantots, lai straumētu lietotnes jūsu ierīcēs"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> piekļūt šai informācijai no jūsu tālruņa"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Paziņojumi"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Var lasīt visus paziņojumus, tostarp tādu informāciju kā kontaktpersonas, ziņojumus un fotoattēlus"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Var lasīt visus paziņojumus, tostarp tādu informāciju kā kontaktpersonas, ziņojumi un fotoattēli."</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotoattēli un multivides faili"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play pakalpojumi"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Šis pakalpojums kopīgo fotoattēlus, multivides saturu un paziņojumus no jūsu tālruņa citās ierīcēs"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Šis pakalpojums kopīgo fotoattēlus, multivides saturu un paziņojumus no jūsu tālruņa citās ierīcēs"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Atļaut"</string>
<string name="consent_no" msgid="2640796915611404382">"Neatļaut"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Labi"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Lietotņu atļauju pārsūtīšana uz pulksteni"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Lai atvieglotu pulksteņa iestatīšanu, iestatīšanas laikā pulkstenī instalētās lietotnes saņems tādas pašas atļaujas, kādas tām ir tālrunī.\n\n Tostarp lietotnes var saņemt atļauju piekļūt pulksteņa mikrofonam un atrašanās vietai."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index 851651f..bb198df 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Апликации"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Стримувајте ги апликациите на телефонот"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Овозможете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да пристапува до овие податоци на телефонот"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Дозволете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да обезбеди далечински пристап на <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> за да пристапува до апликации инсталирани на телефонов кога ќе се поврзе."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Дозволете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да обезбеди далечински пристап на <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> за да пристапува до апликации инсталирани на таблетов кога ќе се поврзе."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Дозволете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да обезбеди далечински пристап на <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> за да пристапува до апликации инсталирани на уредов кога ќе се поврзе."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Повеќенаменски услуги"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Услугава се користи за стриминг на апликации помеѓу вашите уреди"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Овозможете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да пристапува до овие податоци на телефонот"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Известувања"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"може да ги чита сите известувања, вклучително и податоци како договори, пораки и фотографии"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"може да ги чита сите известувања, вклучително и податоци како контакти, пораки и фотографии"</string>
<string name="permission_storage" msgid="6831099350839392343">"Аудиовизуелни содржини"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Услуги на Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Услугава споделува фотографии, аудиовизуелни содржини и известувања од вашиот телефон на други уреди"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Услугава споделува фотографии, аудиовизуелни содржини и известувања од вашиот телефон на други уреди"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"уред"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
<string name="consent_no" msgid="2640796915611404382">"Не дозволувај"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Во ред"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Префрлете ги дозволите за апликациите на вашиот часовник"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"За полесно поставувањето на часовникот, апликациите инсталирани на часовникот при поставувањето ќе ги користат истите дозволи како на телефонот.\n\n Овие дозволи може да опфаќаат пристап до микрофонот и локацијата на часовникот."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index 9e330e6..b8c44a5 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"ആപ്പുകൾ"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"നിങ്ങളുടെ ഫോണിലെ ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്സസ് ചെയ്യാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ആപ്പിനെ അനുവദിക്കുക"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"കണക്റ്റ് ചെയ്യുമ്പോൾ, ഈ ഫോണിൽ ഇൻസ്റ്റാൾ ചെയ്തിട്ടുള്ള ആപ്പുകൾ ആക്സസ് ചെയ്യാനുള്ള റിമോട്ട് ആക്സസ് <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> എന്നതിന് നൽകാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> എന്നതിനെ അനുവദിക്കുക."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"കണക്റ്റ് ചെയ്യുമ്പോൾ, ഈ ടാബ്ലെറ്റിൽ ഇൻസ്റ്റാൾ ചെയ്തിട്ടുള്ള ആപ്പുകൾ ആക്സസ് ചെയ്യാനുള്ള റിമോട്ട് ആക്സസ് <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> എന്നതിന് നൽകാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> എന്നതിനെ അനുവദിക്കുക."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"കണക്റ്റ് ചെയ്യുമ്പോൾ, ഈ ഉപകരണത്തിൽ ഇൻസ്റ്റാൾ ചെയ്തിട്ടുള്ള ആപ്പുകൾ ആക്സസ് ചെയ്യാനുള്ള റിമോട്ട് ആക്സസ് <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> എന്നതിന് നൽകാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> എന്നതിനെ അനുവദിക്കുക."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ക്രോസ്-ഉപകരണ സേവനങ്ങൾ"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"നിങ്ങളുടെ ഉപകരണങ്ങൾക്കിടയിൽ ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ ഈ സേവനം ഉപയോഗിക്കുന്നു"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്സസ് ചെയ്യാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ആപ്പിനെ അനുവദിക്കുക"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"അറിയിപ്പുകൾ"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"കോൺടാക്റ്റുകൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ ഉൾപ്പെടെ, എല്ലാ അറിയിപ്പുകളും വായിക്കാനാകും"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"കോൺടാക്റ്റുകൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ മുതലായ വിവരങ്ങൾ ഉൾപ്പെടെയുള്ള എല്ലാ അറിയിപ്പുകളും വായിക്കാനാകും"</string>
<string name="permission_storage" msgid="6831099350839392343">"ഫോട്ടോകളും മീഡിയയും"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play സേവനങ്ങൾ"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"ഈ സേവനം നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഫോട്ടോകളും മീഡിയയും അറിയിപ്പുകളും മറ്റ് ഉപകരണങ്ങളിലേക്ക് അയയ്ക്കുന്നു"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"ഈ സേവനം നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഫോട്ടോകളും മീഡിയയും അറിയിപ്പുകളും മറ്റ് ഉപകരണങ്ങളിലേക്ക് അയയ്ക്കുന്നു"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ഉപകരണം"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"അനുവദിക്കുക"</string>
<string name="consent_no" msgid="2640796915611404382">"അനുവദിക്കരുത്"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ശരി"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"നിങ്ങളുടെ വാച്ചിലേക്ക് ആപ്പ് അനുമതികൾ കൈമാറുക"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"നിങ്ങളുടെ വാച്ച് സജ്ജീകരിക്കുന്നത് എളുപ്പമാക്കാൻ, സജ്ജീകരിക്കുമ്പോൾ ഫോണിലുള്ള അതേ അനുമതികൾ നിങ്ങളുടെ വാച്ചിൽ ഇൻസ്റ്റാൾ ചെയ്തിട്ടുള്ള ആപ്പുകൾ ഉപയോഗിക്കും.\n\n ഈ അനുമതികളിൽ നിങ്ങളുടെ വാച്ചിന്റെ മൈക്രോഫോണിലേക്കും ലോക്കേഷനിലേക്കുമുള്ള ആക്സസ് ഉൾപ്പെട്ടേക്കാം."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index 00c032d..7233c04 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Аппууд"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Таны утасны аппуудыг дамжуулах"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-г холбогдсон үед энэ утсанд суулгасан аппуудад хандахын тулд алсын хандалт өгөхийг зөвшөөрнө үү."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-г холбогдсон үед энэ таблетад суулгасан аппуудад хандахын тулд алсын хандалт өгөхийг зөвшөөрнө үү."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-г холбогдсон үед энэ төхөөрөмжид суулгасан аппуудад хандахын тулд алсын хандалт өгөхийг зөвшөөрнө үү."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Төхөөрөмж хоорондын үйлчилгээ"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Энэ үйлчилгээг таны төхөөрөмжүүд хооронд аппууд дамжуулахад ашигладаг"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Мэдэгдэл"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Гэрээ, мессеж болон зураг зэрэг мэдээллийг оруулаад бүх мэдэгдлийг унших боломжтой"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Харилцагчид, мессеж болон зураг зэрэг мэдээллийг оруулаад бүх мэдэгдлийг унших боломжтой"</string>
<string name="permission_storage" msgid="6831099350839392343">"Зураг болон медиа"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play үйлчилгээ"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Энэ үйлчилгээ зураг, медиа болон мэдэгдлийг таны утаснаас бусад төхөөрөмж рүү хуваалцана"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Энэ үйлчилгээ зураг, медиа болон мэдэгдлийг таны утаснаас бусад төхөөрөмж рүү хуваалцана"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Зөвшөөрөх"</string>
<string name="consent_no" msgid="2640796915611404382">"Бүү зөвшөөр"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Цагандаа аппын зөвшөөрлийг шилжүүлэх"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Таны цагийг тохируулахад илүү хялбар болгохын тулд тохируулгын үеэр таны цаган дээр суулгасан аппууд нь утастай тань ижил зөвшөөрлийг ашиглана.\n\n Эдгээр зөвшөөрөлд таны цагийн микрофон болон байршлын хандалт зэрэг багтаж магадгүй."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index 303b141..d2aa48c 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"ॲप्स"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"फोनवरील ॲप्स स्ट्रीम करा"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला ही माहिती तुमच्या फोनवरून अॅक्सेस करण्यासाठी अनुमती द्या"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"कनेक्ट केलेले असताना या फोनवरील अॅप्लिकेशन अॅक्सेस करता यावीत यासाठी <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> चा रिमोट अॅक्सेस द्या."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"कनेक्ट केलेले असताना या टॅबलेटवरील अॅप्लिकेशन अॅक्सेस करता यावीत यासाठी <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> चा रिमोट अॅक्सेस द्या."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"कनेक्ट केलेले असताना या डिव्हाइसवरील अॅप्लिकेशन अॅक्सेस करता यावीत यासाठी <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> चा रिमोट अॅक्सेस द्या."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिव्हाइस सेवा"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"ही सेवा तुमच्या डिव्हाइस दरम्यान अॅप्स स्ट्रीम करण्यासाठी वापरली जाते"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला ही माहिती तुमच्या फोनवरून अॅक्सेस करण्यासाठी अनुमती द्या"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"सूचना"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"करार, मेसेज आणि फोटो यांसारख्या माहितीच्या समावेशासह सर्व सूचना वाचू शकते"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"संपर्क, मेसेज आणि फोटो यांसारख्या माहितीचा समावेश असलेल्या सर्व सूचना वाचू शकते"</string>
<string name="permission_storage" msgid="6831099350839392343">"फोटो आणि मीडिया"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवा"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"ही सेवा तुमच्या फोनवरून इतर डिव्हाइसवर फोटो, मीडिया आणि सूचना शेअर करते"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"ही सेवा तुमच्या फोनवरून इतर डिव्हाइसवर फोटो, मीडिया आणि सूचना शेअर करते"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"अनुमती द्या"</string>
<string name="consent_no" msgid="2640796915611404382">"अनुमती देऊ नका"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ओके"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"अॅप परवानग्या तुमच्या वॉचवर ट्रान्सफर करा"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"तुमचे वॉच सेट करणे आणखी सोपे करण्यासाठी, सेटअपदरम्यान तुमच्या वॉचवर इंस्टॉल केलेली ॲप्स ही तुमच्या फोनप्रमाणेच परवानग्या वापरतील.\n\n या परवानग्यांमध्ये तुमच्या वॉचचा मायक्रोफोन आणि स्थानाच्या अॅक्सेसचा समावेश असू शकतो."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index e234089..efc7412 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apl"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Strim apl telefon anda"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Benarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses maklumat ini daripada telefon anda"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Membenarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> memberi akses jauh kepada <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> untuk mengakses aplikasi yang dipasang pada telefon ini apabila disambungkan."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Membenarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> memberi akses jauh kepada <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> untuk mengakses aplikasi yang dipasang pada tablet ini apabila disambungkan."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Membenarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> memberi akses jauh kepada <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> untuk mengakses aplikasi yang dipasang pada peranti ini apabila disambungkan."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Perkhidmatan silang peranti"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Perkhidmatan ini digunakan untuk menstrim apl antara peranti anda"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Benarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> untuk mengakses maklumat ini daripada telefon anda"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Pemberitahuan"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Boleh membaca semua pemberitahuan, termasuk maklumat seperti kenalan, mesej dan foto"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Boleh membaca semua pemberitahuan, termasuk maklumat seperti kenalan, mesej dan foto"</string>
<string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Perkhidmatan Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Perkhidmatan ini berkongsi foto, media dan pemberitahuan daripada telefon anda kepada peranti lain"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Perkhidmatan ini berkongsi foto, media dan pemberitahuan daripada telefon anda kepada peranti lain"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Benarkan"</string>
<string name="consent_no" msgid="2640796915611404382">"Jangan benarkan"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Pindahkan kebenaran apl pada jam tangan anda"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Untuk memudahkan penyediaan jam tangan anda, apl yang dipasang pada jam tangan anda semasa persediaan akan menggunakan kebenaran yang sama seperti telefon anda.\n\n Kebenaran ini mungkin termasuk akses kepada mikrofon dan lokasi jam tangan anda."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index 61a60b2..96e346e 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"အက်ပ်များ"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"သင့်ဖုန်းရှိအက်ပ်များကို တိုက်ရိုက်လွှင့်နိုင်သည်"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ကို သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုမည်"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"ချိတ်ဆက်ထားသည့်အခါ ဤဖုန်းတွင် ထည့်သွင်းထားသော အပလီကေးရှင်းများကို သုံးခွင့်ရရန်အတွက် <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ကိုအဝေးမှ သုံးခွင့်ပေးနိုင်ရန် <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> အားခွင့်ပြုပါ။"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"ချိတ်ဆက်ထားသည့်အခါ ဤတက်ဘလက်တွင် ထည့်သွင်းထားသော အပလီကေးရှင်းများကို သုံးခွင့်ရရန်အတွက် <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ကိုအဝေးမှ သုံးခွင့်ပေးနိုင်ရန် <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> အားခွင့်ပြုပါ။"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"ချိတ်ဆက်ထားသည့်အခါ ဤစက်တွင် ထည့်သွင်းထားသော အပလီကေးရှင်းများကို သုံးခွင့်ရရန်အတွက် <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ကိုအဝေးမှ သုံးခွင့်ပေးနိုင်ရန် <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> အားခွင့်ပြုပါ။"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"စက်များကြားသုံး ဝန်ဆောင်မှုများ"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"သင့်စက်များကြား အက်ပ်များ တိုက်ရိုက်လွှင့်ရန် ဤဝန်ဆောင်မှုကို အသုံးပြုသည်"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ကို သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုမည်"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"အကြောင်းကြားချက်များ"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"အဆက်အသွယ်၊ မက်ဆေ့ဂျ်နှင့် ဓာတ်ပုံကဲ့သို့ အချက်အလက်များအပါအဝင် အကြောင်းကြားချက်အားလုံးကို ဖတ်နိုင်သည်"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"အဆက်အသွယ်၊ မက်ဆေ့ဂျ်နှင့် ဓာတ်ပုံကဲ့သို့ အချက်အလက်များအပါအဝင် အကြောင်းကြားချက်အားလုံးကို ဖတ်နိုင်သည်"</string>
<string name="permission_storage" msgid="6831099350839392343">"ဓာတ်ပုံနှင့် မီဒီယာများ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ဝန်ဆောင်မှုများ"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"ဤဝန်ဆောင်မှုသည် ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များကို သင့်ဖုန်းမှ အခြားစက်များသို့ မျှဝေသည်"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"ဤဝန်ဆောင်မှုသည် ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များကို သင့်ဖုန်းမှ အခြားစက်များသို့ မျှဝေသည်"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ခွင့်ပြုရန်"</string>
<string name="consent_no" msgid="2640796915611404382">"ခွင့်မပြုပါ"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"သင်၏နာရီသို့ အက်ပ်ခွင့်ပြုချက်များ လွှဲပြောင်းရန်"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"သင်၏နာရီ စနစ်ထည့်သွင်းရာတွင် ပိုလွယ်ကူစေရန် စနစ်ထည့်သွင်းနေစဉ်အတွင်း နာရီတွင်ထည့်သွင်းသော အက်ပ်များသည် သင့်ဖုန်းနှင့် အလားတူခွင့်ပြုချက်များကို သုံးပါမည်။\n\n ဤခွင့်ပြုချက်များတွင် သင့်နာရီ၏ မိုက်ခရိုဖုန်းနှင့် တည်နေရာတို့ကို သုံးခွင့် ပါဝင်နိုင်သည်။"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 078a2d4..8bbe71b5 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apper"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Strøm appene på telefonen"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Gi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilgang til denne informasjonen fra telefonen din"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Tillat at <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gir <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ekstern tilgang til apper som er installert på denne telefonen, når den er koblet til internett."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Tillat at <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gir <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ekstern tilgang til apper som er installert på dette nettbrettet, når det er koblet til internett."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Tillat at <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gir <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ekstern tilgang til apper som er installert på denne enheten, når den er koblet til internett."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester på flere enheter"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Denne tjenesten brukes til å strømme apper mellom enhetene dine"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Gi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilgang til denne informasjonen fra telefonen din"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Varsler"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Kan lese alle varsler, inkludert informasjon som kontrakter, meldinger og bilder"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Kan lese alle varsler, inkludert informasjon som kontakter, meldinger og bilder"</string>
<string name="permission_storage" msgid="6831099350839392343">"Bilder og medier"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Denne tjenesten deler bilder, medier og varsler fra telefonen din til andre enheter"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Denne tjenesten deler bilder, medier og varsler fra telefonen din til andre enheter"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Tillat"</string>
<string name="consent_no" msgid="2640796915611404382">"Ikke tillat"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Overfør apptillatelser til klokken din"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"For å gjøre det enklere å konfigurere klokken din bruker apper som installeres på klokken under konfigureringen, samme tillatelser som på telefonen.\n\n Disse tillatelsene kan inkludere tilgang til mikrofonen på klokken og posisjon."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index fd8a6cf..2a27219 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"एपहरू"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"आफ्नो फोनका एपहरू प्रयोग गर्नुहोस्"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"यो डिभाइस इन्टरनेटमा कनेक्ट भएका बेला, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>लाई <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> लाई यो फोनमा इन्स्टल गरिएका एप टाढैबाट प्रयोग गर्ने अनुमति दिन दिनुहोस्।"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"यो डिभाइस इन्टरनेटमा कनेक्ट भएका बेला, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>लाई <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> लाई यो ट्याब्लेटमा इन्स्टल गरिएका एप टाढैबाट प्रयोग गर्ने अनुमति दिन दिनुहोस्।"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"यो डिभाइस इन्टरनेटमा कनेक्ट भएका बेला, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> लाई <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> लाई यो डिभाइसमा इन्स्टल गरिएका एप टाढैबाट प्रयोग गर्ने अनुमति दिन दिनुहोस्।"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रस-डिभाइस सेवाहरू"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"यो सेवा तपाईंको एउटा डिभाइसबाट अर्को डिभाइसमा एपहरू स्ट्रिम गर्न प्रयोग गरिन्छ"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"सूचनाहरू"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"कन्ट्याक्ट, म्यासेज र फोटोलगायतका व्यक्तिगत जानकारीसहित तपाईंका सूचनाहरू पढ्न सक्छ"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"कन्ट्याक्ट, म्यासेज र फोटोलगायतका जानकारीसहित सबै सूचनाहरू पढ्न सक्छ"</string>
<string name="permission_storage" msgid="6831099350839392343">"फोटो र मिडिया"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"यो सेवाले तपाईंको फोनबाट अन्य डिभाइसमा फोटो, मिडिया र सूचनाहरू सेयर गर्छ"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"यो सेवाले तपाईंको फोनबाट अन्य डिभाइसमा फोटो, मिडिया र सूचनाहरू सेयर गर्छ"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"अनुमति दिनुहोस्"</string>
<string name="consent_no" msgid="2640796915611404382">"अनुमति नदिनुहोस्"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ठिक छ"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"एपलाई दिइएका अनुमति घडीमा ट्रान्स्फर गर्नुहोस्"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"तपाईंको घडी सेटअप गर्ने कार्य सजिलो बनाउनका लागि सेटअप गर्ने क्रममा तपाईंको घडीमा इन्स्टल गरिएका एपहरूले पनि तपाईंको फोनमा दिइएको जस्तै अनुमति प्रयोग गर्ने छन्।\n\n यी अनुमतिमा तपाईंको घडीको माइक्रोफोन र लोकेसन प्रयोग गर्ने जस्ता अनुमति पर्न सक्छन्।"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index 76ec957..3b27f9d 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"De apps van je telefoon streamen"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang geven tot deze informatie op je telefoon"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Toestaan dat <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> als er verbinding is <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> externe toegang geeft tot apps die zijn geïnstalleerd op deze telefoon."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Toestaan dat <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> als er verbinding is <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> externe toegang geeft tot apps die zijn geïnstalleerd op deze tablet."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Toestaan dat <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> als er verbinding is <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> externe toegang geeft tot apps die zijn geïnstalleerd op dit apparaat."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device-services"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Met deze service kun je apps streamen tussen je apparaten"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang geven tot deze informatie op je telefoon"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Meldingen"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Kan alle meldingen lezen, waaronder informatie zoals contacten, berichten en foto\'s"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Kan alle meldingen lezen, waaronder informatie zoals contacten, berichten en foto\'s"</string>
<string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Met deze service kun je foto\'s, media en meldingen vanaf je telefoon met andere apparaten delen"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Met deze service kun je foto\'s, media en meldingen vanaf je telefoon met andere apparaten delen"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Toestaan"</string>
<string name="consent_no" msgid="2640796915611404382">"Niet toestaan"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"App-rechten overzetten naar je horloge"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"We willen het makkelijker voor je maken om je horloge in te stellen. Daarom gebruiken apps die tijdens het instellen worden geïnstalleerd op je horloge, dezelfde rechten als op je telefoon.\n\n Deze rechten kunnen toegang tot de microfoon en locatie van je horloge omvatten."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 6b66492..540a1db 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"ଆପ୍ସ"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"ଆପଣଙ୍କ ଫୋନର ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରନ୍ତୁ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ, ଏହି ଫୋନଟି ସଂଯୁକ୍ତ ହୋଇଥିବା ବେଳେ ଏଥିରେ ଇନଷ୍ଟଲ କରାଯାଇଥିବା ଆପ୍ଲିକେସନଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>କୁ ରିମୋଟ ଆକ୍ସେସ ପ୍ରଦାନ କରିବାକୁ ଦିଅନ୍ତୁ।"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ, ଏହି ଟାବଲେଟଟି ସଂଯୁକ୍ତ ହୋଇଥିବା ବେଳେ ଏଥିରେ ଇନଷ୍ଟଲ କରାଯାଇଥିବା ଆପ୍ଲିକେସନଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>କୁ ରିମୋଟ ଆକ୍ସେସ ପ୍ରଦାନ କରିବାକୁ ଦିଅନ୍ତୁ।"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ, ଏହି ଡିଭାଇସଟି ସଂଯୁକ୍ତ ହୋଇଥିବା ବେଳେ ଏଥିରେ ଇନଷ୍ଟଲ କରାଯାଇଥିବା ଆପ୍ଲିକେସନଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>କୁ ରିମୋଟ ଆକ୍ସେସ ପ୍ରଦାନ କରିବାକୁ ଦିଅନ୍ତୁ।"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"କ୍ରସ-ଡିଭାଇସ ସେବାଗୁଡ଼ିକ"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ ଏହି ସେବାକୁ ବ୍ୟବହାର କରାଯାଏ"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"ଯୋଗାଯୋଗ, ମେସେଜ ଏବଂ ଫଟୋଗୁଡ଼ିକ ପରି ସୂଚନା ସମେତ ସମସ୍ତ ବିଜ୍ଞପ୍ତିକୁ ପଢ଼ିପାରିବ"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"ଯୋଗାଯୋଗ, ମେସେଜ ଏବଂ ଫଟୋଗୁଡ଼ିକ ପରି ସୂଚନା ସମେତ ସମସ୍ତ ବିଜ୍ଞପ୍ତିକୁ ପଢ଼ିପାରିବ"</string>
<string name="permission_storage" msgid="6831099350839392343">"ଫଟୋ ଏବଂ ମିଡିଆ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ସେବାଗୁଡ଼ିକ"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"ଏହି ସେବା ଆପଣଙ୍କ ଫୋନରୁ ଅନ୍ୟ ଡିଭାଇସଗୁଡ଼ିକୁ ଫଟୋ, ମିଡିଆ ଏବଂ ବିଜ୍ଞପ୍ତି ସେୟାର କରେ"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"ଏହି ସେବା ଆପଣଙ୍କ ଫୋନରୁ ଅନ୍ୟ ଡିଭାଇସଗୁଡ଼ିକୁ ଫଟୋ, ମିଡିଆ ଏବଂ ବିଜ୍ଞପ୍ତି ସେୟାର କରେ"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="consent_no" msgid="2640796915611404382">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ଠିକ୍ ଅଛି"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ଆପଣଙ୍କ ୱାଚକୁ ଆପ ଅନୁମତିଗୁଡ଼ିକ ଟ୍ରାନ୍ସଫର କରନ୍ତୁ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ଆପଣଙ୍କ ୱାଚ ସେଟ ଅପ କରିବାକୁ ସହଜ କରିବା ପାଇଁ, ସେଟଅପ ସମୟରେ ଆପଣଙ୍କର ୱାଚରେ ଇନଷ୍ଟଲ କରାଯାଇଥିବା ଆପଗୁଡ଼ିକ ଆପଣଙ୍କ ଫୋନରେ ଥିବା ଆପଗୁଡ଼ିକ ପରି ସମାନ ଅନୁମତିଗୁଡ଼ିକ ବ୍ୟବହାର କରିବ।\n\n ଏହି ଅନୁମତିଗୁଡ଼ିକରେ ଆପଣଙ୍କ ୱାଚର ମାଇକ୍ରୋଫୋନ ଏବଂ ଲୋକେସନକୁ ଆକ୍ସେସ ଅନ୍ତର୍ଭୁକ୍ତ ହୋଇପାରେ।"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 93b018e..04199d6 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"ਐਪਾਂ"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"ਆਪਣੇ ਫ਼ੋਨ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰੋ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"ਕਨੈਕਟ ਹੋਣ \'ਤੇ ਇਸ ਫ਼ੋਨ \'ਤੇ ਸਥਾਪਤ ਐਪਲੀਕੇਸ਼ਨਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਲਈ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ਨੂੰ ਰਿਮੋਟ ਪਹੁੰਚ ਮੁਹੱਈਆ ਕਰਵਾਉਣ ਦਿਓ।"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"ਕਨੈਕਟ ਹੋਣ \'ਤੇ ਇਸ ਟੈਬਲੈੱਟ \'ਤੇ ਸਥਾਪਤ ਐਪਲੀਕੇਸ਼ਨਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਲਈ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ਨੂੰ ਰਿਮੋਟ ਪਹੁੰਚ ਮੁਹੱਈਆ ਕਰਵਾਉਣ ਦਿਓ।"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"ਕਨੈਕਟ ਹੋਣ \'ਤੇ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਸਥਾਪਤ ਐਪਲੀਕੇਸ਼ਨਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਲਈ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ਨੂੰ ਰਿਮੋਟ ਪਹੁੰਚ ਮੁਹੱਈਆ ਕਰਵਾਉਣ ਦਿਓ।"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ਕ੍ਰਾਸ-ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"ਇਸ ਸੇਵਾ ਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਲਈ ਕੀਤੀ ਜਾਂਦੀ ਹੈ"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"ਸੂਚਨਾਵਾਂ"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"ਤੁਸੀਂ ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਪੜ੍ਹ ਸਕਦੇ ਹੋ, ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਸੰਪਰਕਾਂ, ਸੁਨੇਹਿਆਂ ਅਤੇ ਫ਼ੋਟੋਆਂ ਵਰਗੀ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੁੰਦੀ ਹੈ"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"ਤੁਸੀਂ ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਪੜ੍ਹ ਸਕਦੇ ਹੋ, ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਸੰਪਰਕਾਂ, ਸੁਨੇਹਿਆਂ ਅਤੇ ਫ਼ੋਟੋਆਂ ਵਰਗੀ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੁੰਦੀ ਹੈ"</string>
<string name="permission_storage" msgid="6831099350839392343">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਮੀਡੀਆ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ਸੇਵਾਵਾਂ"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"ਇਹ ਸੇਵਾ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਹੋਰ ਡੀਵਾਈਸਾਂ \'ਤੇ ਸਾਂਝਾ ਕਰਦੀ ਹੈ"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"ਇਹ ਸੇਵਾ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਹੋਰ ਡੀਵਾਈਸਾਂ \'ਤੇ ਸਾਂਝਾ ਕਰਦੀ ਹੈ"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ਇਜਾਜ਼ਤ ਦਿਓ"</string>
<string name="consent_no" msgid="2640796915611404382">"ਇਜਾਜ਼ਤ ਨਾ ਦਿਓ"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ਠੀਕ ਹੈ"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ਐਪ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਆਪਣੀ ਘੜੀ \'ਤੇ ਟ੍ਰਾਂਸਫ਼ਰ ਕਰੋ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ਤੁਹਾਡੀ ਘੜੀ ਦਾ ਸੈੱਟਅੱਪ ਕਰਨਾ ਆਸਾਨ ਬਣਾਉਣ ਲਈ, ਤੁਹਾਡੀ ਘੜੀ \'ਤੇ ਸਥਾਪਤ ਐਪਾਂ ਸੈੱਟਅੱਪ ਦੌਰਾਨ ਉਹੀ ਇਜਾਜ਼ਤਾਂ ਵਰਤਣਗੀਆਂ ਜੋ ਤੁਹਾਡਾ ਫ਼ੋਨ ਵਰਤਦਾ ਹੈ।\n\n ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਵਿੱਚ ਤੁਹਾਡੀ ਘੜੀ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਅਤੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ।"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index a15af4b..e5f8553 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplikacje"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Odtwarzaj strumieniowo aplikacje z telefonu"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Zezwól aplikacji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na dostęp do tych informacji na Twoim telefonie"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Zezwól na zapewnianie przez aplikację <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> zdalnego dostępu do aplikacji zainstalowanych na telefonie <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> po połączeniu jej z tym telefonem."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Zezwól na zapewnianie przez aplikację <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> zdalnego dostępu do aplikacji zainstalowanych na tablecie <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> po połączeniu jej z tym tabletem."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Zezwól na zapewnianie przez aplikację <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> zdalnego dostępu do aplikacji zainstalowanych na urządzeniu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> po połączeniu jej z urządzeniem."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usługi na innym urządzeniu"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ta usługa jest używana do strumieniowego odtwarzania danych z aplikacji między urządzeniami"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Zezwól aplikacji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na dostęp do tych informacji na Twoim telefonie"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Powiadomienia"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Może odczytywać wszystkie powiadomienia, w tym informacje takie jak kontakty, wiadomości i zdjęcia"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Może odczytywać wszystkie powiadomienia, w tym informacje takie jak kontakty, wiadomości i zdjęcia"</string>
<string name="permission_storage" msgid="6831099350839392343">"Zdjęcia i multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Usługi Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Ta usługa udostępnia zdjęcia, multimedia i powiadomienia z telefonu innym urządzeniom"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Ta usługa udostępnia zdjęcia, multimedia i powiadomienia z telefonu innym urządzeniom"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Zezwól"</string>
<string name="consent_no" msgid="2640796915611404382">"Nie zezwalaj"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Przenieś uprawnienia aplikacji na zegarek"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Aby łatwiej było skonfigurować zegarek, aplikacje zainstalowane na nim podczas konfiguracji będą korzystały z tych samych uprawnień co telefon.\n\n Może to oznaczać dostęp do mikrofonu i lokalizacji na zegarku."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 7d22823..7cd3a37 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Faça streaming dos apps do seu smartphone"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse essas informações do smartphone"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Permita que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> conceda ao <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acesso remoto aos aplicativos instalados no smartphone quando ele estiver conectado."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Permita que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> conceda ao <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acesso remoto aos aplicativos instalados no tablet quando ele estiver conectado."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Permita que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> conceda ao <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acesso remoto aos aplicativos instalados no dispositivo quando ele estiver conectado."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Este serviço é usado para fazer streaming de apps entre seus dispositivos"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorizar que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse essas informações do smartphone"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notificações"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Este serviço compartilha fotos, mídia e notificações do seu smartphone para outros dispositivos"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Este serviço compartilha fotos, mídia e notificações do seu smartphone para outros dispositivos"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir as permissões de apps para o relógio"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para facilitar a configuração do relógio, os apps instalados nele durante a configuração vão usar as mesmas permissões que o smartphone.\n\n Essas permissões podem incluir acesso ao microfone ou à localização do relógio."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index e0c717c..de412eb 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Faça stream das apps do telemóvel"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permita que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aceda a estas informações do seu telemóvel"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Permita que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> forneça acesso remoto ao <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> para aceder a aplicações instaladas neste telemóvel quando estiver ligado."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Permita que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> forneça acesso remoto ao <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> para aceder a aplicações instaladas neste tablet quando estiver ligado."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Permita que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> forneça acesso remoto ao <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> para aceder a aplicações instaladas neste dispositivo quando estiver ligado."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Este serviço é utilizado para fazer stream de apps entre os seus dispositivos"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permita que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aceda a estas informações do seu telemóvel"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notificações"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Pode ler todas as notificações, incluindo informações como contratos, mensagens e fotos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contratos, mensagens e fotos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotos e multimédia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Serviços do Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Este serviço partilha fotos, conteúdo multimédia e notificações do seu telemóvel para outros dispositivos"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Este serviço partilha fotos, conteúdo multimédia e notificações do seu telemóvel para outros dispositivos"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfira as autorizações da app para o seu relógio"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para facilitar a configuração do seu relógio, as apps instaladas no mesmo durante a configuração utilizarão as mesmas autorizações que o telemóvel.\n\n Estas autorizações podem incluir o acesso ao microfone e à localização do seu relógio."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 7d22823..7cd3a37 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Apps"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Faça streaming dos apps do seu smartphone"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse essas informações do smartphone"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Permita que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> conceda ao <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acesso remoto aos aplicativos instalados no smartphone quando ele estiver conectado."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Permita que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> conceda ao <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acesso remoto aos aplicativos instalados no tablet quando ele estiver conectado."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Permita que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> conceda ao <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> acesso remoto aos aplicativos instalados no dispositivo quando ele estiver conectado."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Este serviço é usado para fazer streaming de apps entre seus dispositivos"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorizar que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse essas informações do smartphone"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notificações"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Este serviço compartilha fotos, mídia e notificações do seu smartphone para outros dispositivos"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Este serviço compartilha fotos, mídia e notificações do seu smartphone para outros dispositivos"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
<string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir as permissões de apps para o relógio"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para facilitar a configuração do relógio, os apps instalados nele durante a configuração vão usar as mesmas permissões que o smartphone.\n\n Essas permissões podem incluir acesso ao microfone ou à localização do relógio."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 61b47fb..c14e682 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplicații"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Să redea în stream aplicațiile telefonului"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permiteți ca <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să acceseze aceste informații de pe telefon"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Lăsați <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să ofere acces la distanță pentru <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ca să se poată accesa aplicațiile instalate pe acest telefon când se conectează utilizatorul."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Lăsați <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să ofere acces la distanță pentru <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ca să se poată accesa aplicațiile instalate pe această tabletă când se conectează utilizatorul."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Lăsați <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să ofere acces la distanță pentru <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ca să se poată accesa aplicațiile instalate pe acest dispozitiv când se conectează utilizatorul."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicii pe mai multe dispozitive"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Acest serviciu se folosește pentru a proiecta aplicații între dispozitive"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permiteți ca <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să acceseze aceste informații de pe telefon"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Notificări"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Poate să citească toate notificările, inclusiv informații cum ar fi contracte, mesaje și fotografii"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Poate să citească toate notificările, inclusiv informații cum ar fi agenda, mesajele și fotografiile"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotografii și media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servicii Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Serviciul trimite fotografii, conținut media și notificări de pe telefon pe alte dispozitive"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Serviciul trimite fotografii, conținut media și notificări de pe telefon pe alte dispozitive"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permiteți"</string>
<string name="consent_no" msgid="2640796915611404382">"Nu permiteți"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferați permisiunile pentru aplicații pe ceas"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Ca să configurați mai ușor ceasul, aplicațiile instalate pe ceas în timpul procesului de configurare vor folosi aceleași permisiuni ca telefonul.\n\n Între acestea se poate număra accesul la microfonul și locația ceasului."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index 062314f..3fe10b3 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Приложения"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Трансляция приложений с телефона."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Разрешите приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> получать эту информацию с вашего телефона"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Разрешить приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> при наличии подключения предоставить устройству <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> удаленный доступ к приложениям, установленным на этом телефоне."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Разрешить приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> при наличии подключения предоставить устройству <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> удаленный доступ к приложениям, установленным на этом планшете."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Разрешить приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> при наличии подключения предоставить устройству <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> удаленный доступ к приложениям, установленным на этом устройстве."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервисы стриминга приложений"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Этот сервис используется для трансляции приложений с одного устройства на другое."</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Разрешите приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> получать эту информацию с вашего телефона"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Уведомления"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Чтение всех уведомлений, в том числе сведений о контактах, сообщениях и фотографиях."</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Чтение всех уведомлений, в том числе сведений о контактах, сообщениях и фотографиях."</string>
<string name="permission_storage" msgid="6831099350839392343">"Фотографии и медиафайлы"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сервисы Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Этот сервис используется для отправки фотографий, медиафайлов и уведомлений с вашего телефона на другие устройства."</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Этот сервис используется для отправки фотографий, медиафайлов и уведомлений с вашего телефона на другие устройства."</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Разрешить"</string>
<string name="consent_no" msgid="2640796915611404382">"Запретить"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ОК"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Перенос разрешений для приложений на часы"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Для приложений, установленных на часы во время настройки, будут использоваться те же разрешения, что и на телефоне.\n\n Например, может быть включен доступ к микрофону на часах или сведениям о местоположении."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 65f7865..548e0c2 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"යෙදුම්"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"ඔබගේ දුරකථනයේ යෙදුම් ප්රවාහ කරන්න"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්රවේශ වීමට ඉඩ දෙන්න"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"සම්බන්ධ වූ විට මෙම දුරකථනයේ ස්ථාපනය කර ඇති යෙදුම් වෙත ප්රවේශ වීමට <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> හට දුරස්ථ ප්රවේශය ලබා දීමට ඉඩ දෙන්න."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"සම්බන්ධ වූ විට මෙම ටැබ්ලටයේ ස්ථාපනය කර ඇති යෙදුම් වෙත ප්රවේශ වීමට <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> හට දුරස්ථ ප්රවේශය ලබා දීමට ඉඩ දෙන්න."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"සම්බන්ධ වූ විට මෙම උපාංගයේ ස්ථාපනය කර ඇති යෙදුම් වෙත ප්රවේශ වීමට <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> හට දුරස්ථ ප්රවේශය ලබා දීමට ඉඩ දෙන්න."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"හරස්-උපාංග සේවා"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"මෙම සේවාව ඔබගේ උපාංග අතර යෙදුම් ප්රවාහ කිරීමට භාවිත වේ"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්රවේශ වීමට ඉඩ දෙන්න"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"දැනුම්දීම්"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"ගිවිසුම්, පණිවිඩ සහ ඡායාරූප වැනි තොරතුරු ඇතුළුව සියලු දැනුම්දීම් කියවිය හැකිය"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"සම්බන්ධතා, පණිවිඩ සහ ඡායාරූප වැනි තොරතුරු ඇතුළුව සියලු දැනුම්දීම් කියවිය හැකිය"</string>
<string name="permission_storage" msgid="6831099350839392343">"ඡායාරූප සහ මාධ්ය"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play සේවා"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"මෙම සේවාව ඔබගේ දුරකථනයෙන් වෙනත් උපාංග වෙත ඡායාරූප, මාධ්ය සහ දැනුම්දීම් බෙදා ගනී"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"මෙම සේවාව ඔබගේ දුරකථනයෙන් වෙනත් උපාංග වෙත ඡායාරූප, මාධ්ය සහ දැනුම්දීම් බෙදා ගනී"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ඉඩ දෙන්න"</string>
<string name="consent_no" msgid="2640796915611404382">"ඉඩ නොදෙන්න"</string>
- <string name="consent_ok" msgid="3662376764371001106">"හරි"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ඔබගේ ඔරලෝසුවට යෙදුම් අවසර මාරු කිරීම"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"ඔබගේ ඔරලෝසුව පිහිටුවීම පහසු කිරීමට, පිහිටුවීමේදී ඔබගේ ඔරලෝසුවේ ස්ථාපනය කර ඇති යෙදුම් ඔබගේ දුරකථනයට සමාන අවසර භාවිත කරනු ඇත.\n\n මෙම අවසරවලට ඔබගේ ඔරලෝසුවේ මයික්රෆෝනයට සහ ස්ථානයට ප්රවේශය ඇතුළත් විය හැකිය."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 167eac8..878d264 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplikácie"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Streamujte aplikácie telefónu"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prístup k týmto informáciám z vášho telefónu"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> vzdialený prístup k telefónu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>, aby mala po pripojení prístup k aplikáciám, ktoré sú v ňom nainštalované."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> vzdialený prístup k tabletu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>, aby mala po pripojení prístup k aplikáciám, ktoré sú v ňom nainštalované."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> vzdialený prístup k zariadeniu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>, aby mala po pripojení prístup k aplikáciám, ktoré sú v ňom nainštalované."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pre viacero zariadení"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Pomocou tejto služby sa streamujú aplikácie medzi vašimi zariadeniami"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prístup k týmto informáciám z vášho telefónu"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Upozornenia"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Môže čítať všetky upozornenia vrátane informácií, ako sú kontakty, správy a fotky"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Môže čítať všetky upozornenia vrátane informácií, ako sú kontakty, správy a fotky"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotky a médiá"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Táto služba zdieľa fotky, médiá a upozornenia z vášho telefónu do iných zariadení"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Táto služba zdieľa fotky, médiá a upozornenia z vášho telefónu do iných zariadení"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Povoliť"</string>
<string name="consent_no" msgid="2640796915611404382">"Nepovoliť"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Presun povolení aplikácie do hodiniek"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"V rámci zjednodušenia nastavenia hodiniek budú aplikácie nainštalované do hodiniek pri nastavovaní používať rovnaké povolenia ako váš telefón.\n\n Tieto povolenia môžu zahrnovať prístup k mikrofónu a polohe hodiniek."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 5b79582..0734ee1 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplikacije"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Pretočno predvajanje aplikacij telefona"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dovolite, da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dostopa do teh podatkov v vašem telefonu."</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dovoli oddaljen dostop do telefona <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> za dostop do aplikacij, nameščenih v tem telefonu, ko je povezan v internet."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dovoli oddaljen dostop do tabličnega računalnika <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> za dostop do aplikacij, nameščenih v tem tabličnem računalniku, ko je povezan v internet."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dovoli oddaljen dostop do naprave <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> za dostop do aplikacij, nameščenih v tej napravi, ko je povezana v internet."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Storitve za zunanje naprave"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ta storitev se uporablja za pretočno predvajanje aplikacij med napravami."</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Dovolite, da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dostopa do teh podatkov v vašem telefonu."</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Obvestila"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Lahko bere vsa obvestila, vključno s podatki, kot so pogodbe, sporočila in fotografije."</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Lahko bere vsa obvestila, vključno s podatki, kot so stiki, sporočila in fotografije."</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotografije in predstavnost"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Storitve Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Ta storitev deli fotografije, predstavnost in obvestila v telefonu z drugimi napravami."</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Ta storitev deli fotografije, predstavnost in obvestila v telefonu z drugimi napravami."</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Dovoli"</string>
<string name="consent_no" msgid="2640796915611404382">"Ne dovoli"</string>
- <string name="consent_ok" msgid="3662376764371001106">"V redu"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prenos dovoljenj za aplikacije v uro"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Za lažjo nastavitev ure bodo aplikacije, ki so bile med nastavljanjem nameščene v uri, uporabljale enaka dovoljenja kot tiste v telefonu.\n\n Ta dovoljenja lahko vključujejo dostop do mikrofona in lokacije ure."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index b69fa8a..7352a0d 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Aplikacionet"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Transmeto aplikacionet e telefonit tënd"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ketë qasje në këtë informacion nga telefoni yt"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ofrojë <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> qasje në distancë për të pasur qasje në aplikacionet e instaluara në këtë telefon kur lidhet."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ofrojë <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> qasje në distancë për të pasur qasje në aplikacionet e instaluara në këtë tablet kur lidhet."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> t\'i ofrojë <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> qasje në distancë për të pasur qasje në aplikacionet e instaluara në këtë pajisje kur lidhet."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Shërbimet mes pajisjeve"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ky shërbim përdoret për të transmetuar aplikacione mes pajisjeve të tua"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ketë qasje në këtë informacion nga telefoni yt"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Njoftimet"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Mund të lexojë të gjitha njoftimet, duke përfshirë informacione si kontaktet, mesazhet dhe fotografitë"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Mund të lexojë të gjitha njoftimet, duke përfshirë informacione si kontaktet, mesazhet dhe fotografitë"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotografitë dhe media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Shërbimet e Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Ky shërbim ndan fotografitë, median dhe njoftimet nga telefoni yt te pajisjet e tjera"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Ky shërbim ndan fotografitë, median dhe njoftimet nga telefoni yt te pajisjet e tjera"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Lejo"</string>
<string name="consent_no" msgid="2640796915611404382">"Mos lejo"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Në rregull"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfero lejet e aplikacionit te ora jote"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Për ta bërë më të lehtë konfigurimin e orës, aplikacionet e instaluara në orën tënde gjatë konfigurimit do të përdorin të njëjtat leje si telefoni yt.\n\n Këto leje mund të përfshijnë qasje në mikrofonin dhe vendndodhjen e orës."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index d40a112..efa0c76 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Апликације"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Стримујте апликације на телефону"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа овим информацијама са телефона"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Дозволите апликацији <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да даљински приступа апликацијама инсталираним на телефону <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> када је повезан."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Дозволите апликацији <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да даљински приступа апликацијама инсталираним на таблету <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> када је повезан."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Дозволите апликацији <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да даљински приступа апликацијама инсталираним на уређају <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> када је повезан."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуге на више уређаја"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ова услуга се користи за стримовање апликација између уређаја"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа овим информацијама са телефона"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Обавештења"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Може да чита сва обавештења, укључујући информације попут уговора, порука и слика"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Може да чита сва обавештења, укључујући информације попут контаката, порука и слика"</string>
<string name="permission_storage" msgid="6831099350839392343">"Слике и медији"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play услуге"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Ова услуга дели слике, медијски садржај и обавештења са телефона на друге уређаје"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Ова услуга дели слике, медијски садржај и обавештења са телефона на друге уређаје"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
<string name="consent_no" msgid="2640796915611404382">"Не дозволи"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Потврди"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Пренесите дозволе за апликације на сат"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Да бисмо поједноставили подешавање сата, апликације инсталиране на сату током подешавања ће користити исте дозволе као телефон.\n\n Те дозволе могу да обухватају приступ микрофону и локацији сата."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index fff01ed..198c308 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Appar"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Streama telefonens appar"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Ge <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> åtkomstbehörighet till denna information på telefonen"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Låt <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ge <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> fjärråtkomst till åt appar som är installerade på den här telefonen när den är ansluten."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Låt <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ge <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> fjärråtkomst till appar som är installerade på den här surfplattan när den är ansluten."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Låt <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ge <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> fjärråtkomst till appar som är installerade på den här enheten när den är ansluten."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjänster för flera enheter"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Den här tjänsten används för att streama appar mellan dina enheter"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Ge <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> åtkomstbehörighet till denna information på telefonen"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Aviseringar"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Kan läsa alla aviseringar, inklusive information som kontakter, meddelanden och foton"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Kan läsa alla aviseringar, inklusive information som kontakter, meddelanden och foton"</string>
<string name="permission_storage" msgid="6831099350839392343">"Foton och media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjänster"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Den här tjänsten delar foton, media och aviseringar från telefonen till andra enheter"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Den här tjänsten delar foton, media och aviseringar från telefonen till andra enheter"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Tillåt"</string>
<string name="consent_no" msgid="2640796915611404382">"Tillåt inte"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Överför appbehörigheter till klockan"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Appar som installeras på klockan under konfigureringen får samma behörigheter som de har på telefonen så att konfigureringen ska bli enklare.\n\n Behörigheterna kan omfatta åtkomst till klockans mikrofon och plats."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index 2533a97..a0f99dd 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Programu"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Tiririsha programu za simu yako"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Ruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifikie maelezo haya kutoka kwenye simu yako"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Ruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> iipe <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ufikiaji wa mbali wa programu zilizosakinishwa kwenye simu hii wakati imeunganishwa."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Ruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> iipe <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ufikiaji wa mbali wa programu zilizosakinishwa kwenye kompyuta hii kibao wakati imeunganishwa."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Ruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> iipe <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ufikiaji wa mbali wa programu zilizosakinishwa kwenye kifaa hiki wakati kimeunganishwa."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Huduma za kifaa kilichounganishwa kwingine"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Huduma hii inatumika kutiririsha programu kati ya vifaa vyako"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Ruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifikie maelezo haya kutoka kwenye simu yako"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Arifa"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Inaweza kusoma arifa zote, ikiwa ni pamoja na maelezo kama vile mikataba, ujumbe na picha"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Inaweza kusoma arifa zote, ikiwa ni pamoja na maelezo kama vile anwani, ujumbe na picha"</string>
<string name="permission_storage" msgid="6831099350839392343">"Picha na maudhui"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Huduma za Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Huduma hii inashiriki picha, maudhui na arifa kutoka kwenye simu yako kwenda kwenye vifaa vingine"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Huduma hii inashiriki picha, maudhui na arifa kutoka kwenye simu yako kwenda kwenye vifaa vingine"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Ruhusu"</string>
<string name="consent_no" msgid="2640796915611404382">"Usiruhusu"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Sawa"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Hamishia idhini za programu kwenye saa yako"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Ili kurahisisha kuweka mipangilio ya saa yako, programu ambazo zimesakinishwa kwenye saa yako wakati wa kuweka mipangilio zitatumia ruhusa sawa na zinazotumika kwenye simu yako.\n\n Ruhusa hizi huenda zikajumuisha ufikiaji wa maikrofoni ya saa yako na maelezo ya mahali ilipo saa yako."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index 3f55444..fd81674 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"ஆப்ஸ்"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"உங்கள் மொபைலின் ஆப்ஸை ஸ்ட்ரீம் செய்யலாம்"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"மொபைலில் உள்ள இந்தத் தகவல்களை அணுக, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதிக்கவும்"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"இணைக்கப்பட்டிருக்கும்போது இந்த மொபைலில் நிறுவப்பட்டிருக்கும் ஆப்ஸை அணுகுவதற்கான தொலைநிலை அணுகலை <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> சாதனத்திற்கு வழங்க <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதிக்கும்."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"இணைக்கப்பட்டிருக்கும்போது இந்த டேப்லெட்டில் நிறுவப்பட்டிருக்கும் ஆப்ஸை அணுகுவதற்கான தொலைநிலை அணுகலை <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> சாதனத்திற்கு வழங்க <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதிக்கும்."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"இணைக்கப்பட்டிருக்கும்போது இந்தச் சாதனத்தில் நிறுவப்பட்டிருக்கும் ஆப்ஸை அணுகுவதற்கான தொலைநிலை அணுகலை <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> சாதனத்திற்கு வழங்க <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதிக்கும்."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"சாதனங்களுக்கு இடையேயான சேவைகள்"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸை ஸ்ட்ரீம் செய்ய இந்தச் சேவை பயன்படுத்தப்படுகிறது"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"உங்கள் மொபைலிலிருந்து இந்தத் தகவலை அணுக <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதியுங்கள்"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"அறிவிப்புகள்"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"ஒப்பந்தங்கள், மெசேஜ்கள், படங்கள் போன்ற தகவல்கள் உட்பட அனைத்து அறிவிப்புகளையும் படிக்க முடியும்"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"தொடர்புகள், மெசேஜ்கள், படங்கள் போன்ற தகவல்கள் உட்பட அனைத்து அறிவிப்புகளையும் படிக்க முடியும்"</string>
<string name="permission_storage" msgid="6831099350839392343">"படங்கள் மற்றும் மீடியா"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play சேவைகள்"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை உங்கள் மொபைலில் இருந்து பிற சாதனங்களுக்கு இந்தச் சேவை பகிர்கிறது"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை உங்கள் மொபைலில் இருந்து பிற சாதனங்களுக்கு இந்தச் சேவை பகிர்கிறது"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"அனுமதி"</string>
<string name="consent_no" msgid="2640796915611404382">"அனுமதிக்க வேண்டாம்"</string>
- <string name="consent_ok" msgid="3662376764371001106">"சரி"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"ஆப்ஸ் அனுமதிகளை உங்கள் வாட்ச்சிற்கு மாற்றுதல்"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"உங்கள் வாட்ச் அமைவை எளிதாக்க, உங்கள் மொபைலில் வழங்கியுள்ள அனுமதிகளையே அமைவின்போது வாட்ச்சில் நிறுவப்பட்ட ஆப்ஸும் பயன்படுத்தும்.\n\n உங்கள் வாட்ச்சிலுள்ள மைக்ரோஃபோன், இருப்பிடம் ஆகியவற்றுக்கான அணுகலும் இந்த அனுமதிகளில் அடங்கக்கூடும்."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index 552834e..f431fe4 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"యాప్లు"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"మీ ఫోన్ యాప్లను స్ట్రీమ్ చేయండి"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> యాప్ను అనుమతించండి"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"కనెక్ట్ అయినప్పుడు ఈ ఫోన్లో ఇన్స్టాల్ చేయబడిన యాప్లను యాక్సెస్ చేయడానికి <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> రిమోట్ యాక్సెస్ను అందించడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ను అనుమతించండి."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"కనెక్ట్ అయినప్పుడు ఈ టాబ్లెట్లో ఇన్స్టాల్ చేయబడిన యాప్లను యాక్సెస్ చేయడానికి <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> రిమోట్ యాక్సెస్ను అందించడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ను అనుమతించండి."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"కనెక్ట్ అయినప్పుడు ఈ పరికరంలో ఇన్స్టాల్ చేయబడిన యాప్లను యాక్సెస్ చేయడానికి <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> రిమోట్ యాక్సెస్ను అందించడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ను అనుమతించండి."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"క్రాస్-డివైజ్ సర్వీసులు"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"మీ పరికరాల మధ్య యాప్లను స్ట్రీమ్ చేయడానికి ఈ సర్వీస్ ఉపయోగించబడుతుంది"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> యాప్ను అనుమతించండి"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"నోటిఫికేషన్లు"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"ఒప్పందాలు, మెసేజ్లు, ఫోటోల వంటి సమాచారంతో సహా అన్ని నోటిఫికేషన్లను చదవగలరు"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"కాంటాక్ట్లు, మెసేజ్లు, ఫోటోల వంటి సమాచారంతో సహా అన్ని నోటిఫికేషన్లను చదవగలరు"</string>
<string name="permission_storage" msgid="6831099350839392343">"ఫోటోలు, మీడియా"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play సర్వీసులు"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"ఈ సర్వీస్ మీ ఫోన్ నుండి ఇతర పరికరాలకు ఫోటోలు, మీడియా, ఇంకా నోటిఫికేషన్లను షేర్ చేస్తుంది"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"ఈ సర్వీస్ మీ ఫోన్ నుండి ఇతర పరికరాలకు ఫోటోలు, మీడియా, ఇంకా నోటిఫికేషన్లను షేర్ చేస్తుంది"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"పరికరం"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"అనుమతించు"</string>
<string name="consent_no" msgid="2640796915611404382">"అనుమతించవద్దు"</string>
- <string name="consent_ok" msgid="3662376764371001106">"సరే"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"మీ వాచ్కు యాప్ అనుమతులను బదిలీ చేయండి"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"మీ వాచ్ను సెటప్ చేయడాన్ని సులభతరం చేయడానికి, సెటప్ సమయంలో మీ వాచ్లో ఇన్స్టాల్ చేయబడిన యాప్లు మీ ఫోన్లో యాప్లకు ఉన్న అవే అనుమతులను ఉపయోగిస్తాయి.\n\n ఈ అనుమతులతో మీ వాచ్ మైక్రోఫోన్, అలాగే లొకేషన్ కూడా ఉండవచ్చు."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index c15ce03..7fec885 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"แอป"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"สตรีมแอปของโทรศัพท์คุณ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> มอบสิทธิ์เข้าถึงแอปพลิเคชันที่ติดตั้งในโทรศัพท์เครื่องนี้จากระยะไกลให้แก่ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> เมื่อมีการเชื่อมต่อ"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> มอบสิทธิ์เข้าถึงแอปพลิเคชันที่ติดตั้งในแท็บเล็ตเครื่องนี้จากระยะไกลให้แก่ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> เมื่อมีการเชื่อมต่อ"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> มอบสิทธิ์เข้าถึงแอปพลิเคชันที่ติดตั้งในอุปกรณ์เครื่องนี้จากระยะไกลให้แก่ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> เมื่อมีการเชื่อมต่อ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"บริการหลายอุปกรณ์"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"บริการนี้ใช้เพื่อสตรีมแอประหว่างอุปกรณ์"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"การแจ้งเตือน"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"สามารถอ่านการแจ้งเตือนทั้งหมด รวมถึงข้อมูลอย่าง รายชื่อผู้ติดต่อ ข้อความ และรูปภาพ"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"สามารถอ่านการแจ้งเตือนทั้งหมด รวมถึงข้อมูลอย่างรายชื่อติดต่อ ข้อความ และรูปภาพ"</string>
<string name="permission_storage" msgid="6831099350839392343">"รูปภาพและสื่อ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"บริการ Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"บริการนี้แชร์รูปภาพ สื่อ และการแจ้งเตือนจากโทรศัพท์กับอุปกรณ์อื่นๆ"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"บริการนี้แชร์รูปภาพ สื่อ และการแจ้งเตือนจากโทรศัพท์กับอุปกรณ์อื่นๆ"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"อุปกรณ์"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"อนุญาต"</string>
<string name="consent_no" msgid="2640796915611404382">"ไม่อนุญาต"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ตกลง"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"โอนสิทธิ์ของแอปไปยังนาฬิกา"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"แอปที่ติดตั้งในนาฬิการะหว่างการตั้งค่าจะใช้สิทธิ์เดียวกันกับโทรศัพท์เพื่อให้การตั้งค่านาฬิกาง่ายขึ้น\n\n สิทธิ์เหล่านี้อาจรวมการเข้าถึงไมโครโฟนและตำแหน่งของนาฬิกา"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index ee5ec16..eddd711 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Mga App"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"I-stream ang mga app ng iyong telepono"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na i-access ang impormasyong ito sa iyong telepono"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na bigyan ang <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ng malayuang access para ma-access ang mga application na naka-install sa teleponong ito kapag nakakonekta."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na bigyan ang <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ng malayuang access para ma-access ang mga application na naka-install sa tablet na ito kapag nakakonekta."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na bigyan ang <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ng malayuang access para ma-access ang mga application na naka-install sa device na ito kapag nakakonekta."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Mga cross-device na serbisyo"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Ginagamit ang serbisyong ito para mag-stream ng mga app sa pagitan ng iyong mga device"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na i-access ang impormasyon sa iyong telepono"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Mga Notification"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Mababasa ang lahat ng notification, kasama ang impormasyon gaya ng mga kontrata, mensahe, at larawan"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Magbasa ng lahat ng notification, kabilang ang impormasyon gaya ng mga contact, mensahe, at larawan"</string>
<string name="permission_storage" msgid="6831099350839392343">"Mga larawan at media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Mga serbisyo ng Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Nagbabahagi ang serbisyong ito ng mga larawan, media, at notification mula sa iyong telepono patungo sa iba pang device"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Nagbabahagi ang serbisyong ito ng mga larawan, media, at notification mula sa iyong telepono patungo sa iba pang device"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Payagan"</string>
<string name="consent_no" msgid="2640796915611404382">"Huwag payagan"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Ilipat sa iyong relo ang mga pahintulot sa app"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Para gawing mas madali na i-set up ang iyong relo, gagamitin ng mga app na naka-install sa relo mo sa oras ng pag-set up ang mga pahintulot na ginagamit din sa iyong telepono.\n\n Posibleng kasama sa mga pahintulot na ito ang access sa mikropono at lokasyon ng iyong relo."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 07a5c2a..37031ef 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Uygulamalar"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun uygulamalarını akışla aktarın"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, internete bağlanan bu telefondaki yüklü uygulamalara erişebilmesi için <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> adlı cihaza uzaktan erişim izni verin."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, internete bağlanan bu tabletteki yüklü uygulamalara erişebilmesi için <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> adlı cihaza uzaktan erişim izni verin."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, internete bağlanan bu cihazdaki yüklü uygulamalara erişebilmesi için <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> adlı cihaza uzaktan erişim izni verin."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlar arası hizmetler"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Bu hizmet, cihazlarınız arasında uygulama aktarmak için kullanılır"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Bildirimler"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Kişiler, mesajlar ve fotoğraflar da dahil olmak üzere tüm bildirimleri okuyabilir"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Kişiler, mesajlar ve fotoğraflar da dahil olmak üzere tüm bildirimleri okuyabilir"</string>
<string name="permission_storage" msgid="6831099350839392343">"Fotoğraflar ve medya"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play hizmetleri"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Bu hizmet, telefonunuzdaki fotoğraf, medya ve bildirimleri diğer cihazlarla paylaşır"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Bu hizmet, telefonunuzdaki fotoğraf, medya ve bildirimleri diğer cihazlarla paylaşır"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string>
<string name="consent_no" msgid="2640796915611404382">"İzin verme"</string>
- <string name="consent_ok" msgid="3662376764371001106">"Tamam"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Uygulama izinlerini saatinize aktarma"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Kurulum sırasında saatinize yüklenen uygulamalar, saat kurulumunuzu kolaylaştırmak için telefonunuzla aynı izinleri kullanır.\n\n Saatinizin mikrofonuna ve konumuna erişim bu izinlere dahil olabilir."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 8ab5bf1..b90f507 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Додатки"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Транслювати додатки телефона"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Надайте додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ до цієї інформації з телефона"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Дозвольте додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> за наявності з’єднання надавати пристрою <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> віддалений доступ до додатків, установлених на цьому телефоні."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Дозвольте додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> за наявності з’єднання надавати пристрою <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> віддалений доступ до додатків, установлених на цьому планшеті."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Дозвольте додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> за наявності з’єднання надавати пристрою <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> віддалений доступ до додатків, установлених на цьому пристрої."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервіси для кількох пристроїв"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Цей сервіс використовується для трансляції додатків між вашими пристроями"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Надайте додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ до цієї інформації з телефона"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Сповіщення"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Може читати всі сповіщення, зокрема таку інформацію, як контакти, повідомлення та фотографії"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Може читати всі сповіщення, зокрема таку інформацію, як контакти, повідомлення та фотографії"</string>
<string name="permission_storage" msgid="6831099350839392343">"Фотографії та медіафайли"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сервіси Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Цей сервіс передає фотографії, медіафайли та сповіщення з вашого телефона на інші пристрої"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Цей сервіс передає фотографії, медіафайли та сповіщення з вашого телефона на інші пристрої"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Дозволити"</string>
<string name="consent_no" msgid="2640796915611404382">"Не дозволяти"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Перенести дозволи для додатків на годинник"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Задля зручності додатки, установлені на годиннику протягом налаштування, використовуватимуть ті самі дозволи, що й на телефоні.\n\n До таких дозволів може належати доступ до мікрофона й геоданих годинника."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index 0c36865..f6fec4b 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"ایپس"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"اپنے فون کی ایپس کی سلسلہ بندی کریں"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو اپنے فون سے ان معلومات تک رسائی حاصل کرنے کی اجازت دیں"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"منسلک ہونے پر، اس فون پر انسٹال کردہ ایپلیکیشنز تک رسائی حاصل کرنے کے لیے <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> کے لیے ریموٹ تک رسائی فراہم کرنے کی اجازت دیں۔"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"منسلک ہونے پر، اس ٹیبلیٹ پر انسٹال کردہ ایپلیکیشنز تک رسائی حاصل کرنے کے لیے <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> کے لیے ریموٹ تک رسائی فراہم کرنے کی اجازت دیں۔"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"منسلک ہونے پر، اس آلے پر انسٹال کردہ ایپلیکیشنز تک رسائی حاصل کرنے کے لیے <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> کے لیے ریموٹ تک رسائی فراہم کرنے کی اجازت دیں۔"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"کراس آلے کی سروس"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"یہ سروس آپ کے آلات کے درمیان ایپس کو اسٹریم کرنے کے لیے استعمال ہوتی ہے"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"اپنے فون سے اس معلومات تک رسائی حاصل Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کرنے کی اجازت دیں"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"اطلاعات"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"معاہدوں، پیغامات اور تصاویر جیسی معلومات سمیت تمام اطلاعات پڑھ سکتے ہیں"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"رابطوں، پیغامات اور تصاویر جیسی معلومات سمیت تمام اطلاعات پڑھ سکتے ہیں"</string>
<string name="permission_storage" msgid="6831099350839392343">"تصاویر اور میڈیا"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play سروسز"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"یہ سروس آپ کے فون سے دیگر آلات پر تصاویر، میڈیا اور اطلاعات کا اشتراک کرتی ہے"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"یہ سروس آپ کے فون سے دیگر آلات پر تصاویر، میڈیا اور اطلاعات کا اشتراک کرتی ہے"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"آلہ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"اجازت دیں"</string>
<string name="consent_no" msgid="2640796915611404382">"اجازت نہ دیں"</string>
- <string name="consent_ok" msgid="3662376764371001106">"ٹھیک ہے"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"اپنی گھڑی پر ایپ کی اجازتیں منتقل کریں"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"آپ کی گھڑی کو سیٹ اپ کرنے کے عمل کو زیادہ آسان بنانے کے لیے، سیٹ اپ کے دوران آپ کی گھڑی پر انسٹال کردہ ایپس انہیں اجازتوں کا استعمال کریں گی جن کا استعمال آپ کا فون کرتا ہے۔\n\n ان اجازتوں میں آپ کی گھڑی کے مائیکروفون اور مقام تک کی رسائی شامل ہو سکتی ہے۔"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 59fc98f..cc7ca6e 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Ilovalar"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Telefondagi ilovalarni translatsiya qilish"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ulanganda ushbu telefonda oʻrnatilgan ilovalarga masofadan kirish ruxsatini bering."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ulanganda ushbu planshetda oʻrnatilgan ilovalarga masofadan kirish ruxsatini bering."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ulanganda ushbu qurilmada oʻrnatilgan ilovalarga masofadan kirish ruxsatini bering."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Qurilmalararo xizmatlar"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Bu xizmat ilovalarni qurilmalararo translatsiya qilishda ishlatiladi"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Bildirishnomalar"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Barcha bildirishnomalarni, jumladan, kontaktlar, xabarlar va suratlarni oʻqishi mumkin"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Barcha bildirishnomalarni, jumladan, kontaktlar, xabarlar va suratlarni oʻqishi mumkin"</string>
<string name="permission_storage" msgid="6831099350839392343">"Suratlar va media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play xizmatlari"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Bu xizmat telefondagi rasm, media va bildirishnomalarni boshqa qurilmalarga ulashadi"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Bu xizmat telefondagi rasm, media va bildirishnomalarni boshqa qurilmalarga ulashadi"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Ruxsat"</string>
<string name="consent_no" msgid="2640796915611404382">"Ruxsat berilmasin"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Ilova uchun ruxsatlarni soatingizga uzating"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Soatingizni sozlashni qulaylashtirish maqsadida sozlash paytida soatingizga oʻrnatilgan ilovalar telefoningiz bilan bir xil ruxsatlardan foydalanadi.\n\n Bunday ruxsatlarga soatingiz mikrofoni va joylashuv axborotiga ruxsatlar kirishi mumkin."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 8a96c4a..32efbec 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Ứng dụng"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Truyền các ứng dụng trên điện thoại của bạn"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập vào thông tin này trên điện thoại của bạn"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập từ xa vào các ứng dụng đã cài đặt trên <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> khi điện thoại này có kết nối."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập từ xa vào các ứng dụng đã cài đặt trên <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> khi máy tính bảng này có kết nối."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập từ xa vào các ứng dụng đã cài đặt trên <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> khi thiết bị này có kết nối."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Dịch vụ trên nhiều thiết bị"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Dịch vụ này được dùng để truyền ứng dụng giữa các thiết bị"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập vào thông tin này trên điện thoại của bạn"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Thông báo"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Có thể đọc tất cả các thông báo, kể cả những thông tin như hợp đồng, tin nhắn và ảnh"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Có thể đọc tất cả các thông báo, kể cả những thông tin như danh bạ, tin nhắn và ảnh"</string>
<string name="permission_storage" msgid="6831099350839392343">"Ảnh và nội dung nghe nhìn"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Dịch vụ Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Dịch vụ này chia sẻ ảnh, nội dung nghe nhìn và thông báo từ điện thoại của bạn sang các thiết bị khác"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Dịch vụ này chia sẻ ảnh, nội dung nghe nhìn và thông báo từ điện thoại của bạn sang các thiết bị khác"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Cho phép"</string>
<string name="consent_no" msgid="2640796915611404382">"Không cho phép"</string>
- <string name="consent_ok" msgid="3662376764371001106">"OK"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Chuyển quyền cho ứng dụng sang đồng hồ"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Để thiết lập đồng hồ dễ dàng hơn, trong quá trình thiết lập, các ứng dụng được cài đặt trên đồng hồ của bạn sẽ sử dụng các quyền giống như trên điện thoại.\n\n Các quyền này có thể bao gồm quyền sử dụng micrô và thông tin vị trí của đồng hồ."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 1ee43c9..42d93eb 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"应用"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"流式传输手机的应用内容"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”<strong></strong>访问您手机中的这项信息"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"在 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> 连接到网络后,允许 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 远程访问该手机上安装的应用。"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"在 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> 连接到网络后,允许 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 远程访问该平板电脑上安装的应用。"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"在 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> 连接到网络后,允许 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 远程访问该设备上安装的应用。"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨设备服务"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"此服务用于在设备之间流式传输应用内容"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允许 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 访问您手机中的这项信息"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"通知"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"可以读取所有通知,包括合同、消息和照片等信息"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"可以读取所有通知,包括合同、消息和照片等信息"</string>
<string name="permission_storage" msgid="6831099350839392343">"照片和媒体内容"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服务"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"此服务可将您手机中的照片、媒体内容和通知分享给其他设备"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"此服务可将您手机中的照片、媒体内容和通知分享给其他设备"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"设备"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"允许"</string>
<string name="consent_no" msgid="2640796915611404382">"不允许"</string>
- <string name="consent_ok" msgid="3662376764371001106">"确定"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"将应用权限转让给手表"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"为了让您更轻松地设置手表,在设置过程中安装在手表上的应用将使用与手机相同的权限。\n\n这些权限可能包括使用手表的麦克风和位置信息。"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index fa2f0fc..d665d0f 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"應用程式"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"串流播放手機應用程式內容"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取您手機中的這項資料"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"讓「<xliff:g id="APP_NAME">%1$s</xliff:g>」在「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」連線時可透過遠端方式存取此手機上安裝的應用程式。"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"讓「<xliff:g id="APP_NAME">%1$s</xliff:g>」在「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」連線時可透過遠端方式存取此平板電腦上安裝的應用程式。"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"讓「<xliff:g id="APP_NAME">%1$s</xliff:g>」在「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」連線時可透過遠端方式存取此裝置上安裝的應用程式。"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"此服務是用來在裝置間串流應用程式的內容"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取您手機中的這項資料"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"通知"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"可以讀取所有通知,包括聯絡人、訊息和電話等資訊"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"可以讀取所有通知,包括聯絡人、訊息和電話等資訊"</string>
<string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"此服務可將手機上的相片、媒體及通知分享到其他裝置"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"此服務可將手機上的相片、媒體及通知分享到其他裝置"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"允許"</string>
<string name="consent_no" msgid="2640796915611404382">"不允許"</string>
- <string name="consent_ok" msgid="3662376764371001106">"確定"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"將應用程式權限轉移至手錶"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"為簡化手錶的設定程序,在設定過程中安裝到手錶上的應用程式都將沿用手機上的權限。\n\n這些權限可能包括手錶麥克風和位置的存取權。"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index abefde4..68958ad 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"應用程式"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"串流傳輸手機應用程式內容"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取手機中的這項資訊"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>在「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>連上網際網路時可從遠端存取該手機上安裝的應用程式。"</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>在「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>連上網際網路時可從遠端存取該平板電腦上安裝的應用程式。"</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>在「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>連上網際網路時可從遠端存取該裝置上安裝的應用程式。"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"這項服務是用來在裝置間串流傳輸應用程式的內容"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取你手機中的這項資訊"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"通知"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"可以讀取所有通知,包括聯絡人、訊息和電話等資訊"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"可讀取所有通知,包括聯絡人、訊息和電話等資訊"</string>
<string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"這項服務可將手機上的相片、媒體及通知分享到其他裝置"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"這項服務可將手機上的相片、媒體及通知分享到其他裝置"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"允許"</string>
<string name="consent_no" msgid="2640796915611404382">"不允許"</string>
- <string name="consent_ok" msgid="3662376764371001106">"確定"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"將應用程式權限轉移到手錶上"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"為簡化手錶的設定程序,只要是在設定過程中安裝到手錶上的應用程式,都將沿用手機上的權限。\n\n 這些權限可能包括手錶的麥克風和位置資訊存取權。"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index 1c7cad3..3f5031f 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -25,27 +25,26 @@
<string name="permission_apps" msgid="6142133265286656158">"Ama-app"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"Sakaza ama-app wefoni yakho"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Vumela i-<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifinyelele lolu lwazi kusukela efonini yakho"</string>
- <string name="summary_app_streaming" product="default" msgid="6105916810614498138">"Vumela <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ukunikezela <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ngokufinyelela kwerimothi kuma-applications afakiwe kule foni uma ixhunyiwe."</string>
- <string name="summary_app_streaming" product="tablet" msgid="2996373715966272792">"Vumela <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ukunikezela <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ngokufinyelela kwerimothi kuma-applications afakiwe kule thebhulethi uma ixhunyiwe."</string>
- <string name="summary_app_streaming" product="device" msgid="7614171699434639963">"Vumela <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ukunikezela <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ngokufinyelela kwerimothi kuma-applications afakiwe kule divayisi uma ixhunyiwe."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Amasevisi amadivayisi amaningi"</string>
- <string name="helper_summary_app_streaming" msgid="5344341720432827388">"Le sevisi isetshenziselwa ukusakaza-bukhoma ama-app phakathi kwamadivayisi akho"</string>
+ <!-- no translation found for helper_summary_app_streaming (7380294597268573523) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Vumela <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ukufinyelela lolu lwazi kusuka efonini yakho"</string>
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="permission_notification" msgid="693762568127741203">"Izaziso"</string>
- <string name="permission_notification_summary" msgid="4398672775023193663">"Ingafunda zonke izaziso, okufaka phakathi ulwazi olufana nomakhontilaki, imiyalezo, nezithombe"</string>
+ <string name="permission_notification_summary" msgid="884075314530071011">"Ingafunda zonke izaziso, okubandakanya ulwazi olufana noxhumana nabo, imilayezo, nezithombe"</string>
<string name="permission_storage" msgid="6831099350839392343">"Izithombe nemidiya"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Amasevisi we-Google Play"</string>
- <string name="helper_summary_computer" product="default" msgid="467996390095403648">"Le sevisi yabelana ngezithombe, imidiya, nezaziso kusukela kufoni yakho ukuya kwamanye amadivaysi"</string>
- <string name="helper_summary_computer" product="tablet" msgid="467996390095403648">"Le sevisi yabelana ngezithombe, imidiya, nezaziso kusukela kufoni yakho ukuya kwamanye amadivaysi"</string>
+ <!-- no translation found for helper_summary_computer (1676407599909474428) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Vumela"</string>
<string name="consent_no" msgid="2640796915611404382">"Ungavumeli"</string>
- <string name="consent_ok" msgid="3662376764371001106">"KULUNGILE"</string>
+ <!-- no translation found for consent_back (2560683030046918882) -->
+ <skip />
<string name="permission_sync_confirmation_title" msgid="667074294393493186">"Dlulisela izimvume ze-app ewashini lakho"</string>
<string name="permission_sync_summary" msgid="8873391306499120778">"Ukuze wenze kube lula ukusetha iwashi lakho, ama-app afakwe ewashini lakho phakathi nokusetha azosebenzisa izimvume ezifanayo nezefoni yakho.\n\n Lezi zimvume zingabandakanya ukufinyelela kumakrofoni nendawo yewashi lakho."</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values/styles.xml b/packages/CompanionDeviceManager/res/values/styles.xml
index faa3032..c38323f 100644
--- a/packages/CompanionDeviceManager/res/values/styles.xml
+++ b/packages/CompanionDeviceManager/res/values/styles.xml
@@ -108,4 +108,11 @@
<item name="android:background">@android:color/system_accent1_300</item>
</style>
+ <style name="Spinner"
+ parent="@android:style/Widget.Material.Light.ProgressBar.Large">
+ <item name="android:layout_width">56dp</item>
+ <item name="android:layout_height">56dp</item>
+ <item name="android:indeterminate">true</item>
+ <item name="android:layout_centerInParent">true</item>
+ </style>
</resources>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index b596816..37cbf30 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -122,7 +122,10 @@
// Progress indicator is only shown while we are looking for the first suitable device for a
// multiple device association.
- private ProgressBar mProgressIndicator;
+ private ProgressBar mMultipleDeviceSpinner;
+ // Progress indicator is only shown while we are looking for the first suitable device for a
+ // single device association.
+ private ProgressBar mSingleDeviceSpinner;
// Present for self-managed association requests and "single-device" regular association
// regular.
@@ -255,7 +258,7 @@
setContentView(R.layout.activity_confirmation);
mMultipleDeviceList = findViewById(R.id.multiple_device_list);
- mAssociationConfirmationDialog = findViewById(R.id.activity_confirmation);
+ mAssociationConfirmationDialog = findViewById(R.id.association_confirmation);
mVendorHeader = findViewById(R.id.vendor_header);
mTitle = findViewById(R.id.title);
@@ -269,7 +272,8 @@
mDeviceListRecyclerView = findViewById(R.id.device_list);
- mProgressIndicator = findViewById(R.id.spinner);
+ mMultipleDeviceSpinner = findViewById(R.id.spinner_multiple_device);
+ mSingleDeviceSpinner = findViewById(R.id.spinner_single_device);
mDeviceAdapter = new DeviceListAdapter(this, this::onListItemClick);
mPermissionListRecyclerView = findViewById(R.id.permission_list);
@@ -468,8 +472,10 @@
deviceFilterPairs -> updateSingleDeviceUi(
deviceFilterPairs, deviceProfile, appLabel));
+ mSingleDeviceSpinner.setVisibility(View.VISIBLE);
mPermissionListRecyclerView.setVisibility(View.GONE);
mDeviceListRecyclerView.setVisibility(View.GONE);
+ mAssociationConfirmationDialog.setVisibility(View.GONE);
}
private void updateSingleDeviceUi(List<DeviceFilterPair<?>> deviceFilterPairs,
@@ -499,6 +505,8 @@
mTitle.setText(title);
mSummary.setText(summary);
mProfileIcon.setImageDrawable(profileIcon);
+ mSingleDeviceSpinner.setVisibility(View.GONE);
+ mAssociationConfirmationDialog.setVisibility(View.VISIBLE);
}
private void initUiForMultipleDevices(CharSequence appLabel) {
@@ -535,7 +543,7 @@
deviceFilterPairs -> {
// Dismiss the progress bar once there's one device found for multiple devices.
if (deviceFilterPairs.size() >= 1) {
- mProgressIndicator.setVisibility(View.GONE);
+ mMultipleDeviceSpinner.setVisibility(View.GONE);
}
mDeviceAdapter.setDevices(deviceFilterPairs);
@@ -546,7 +554,7 @@
mButtonNotAllow.setVisibility(View.GONE);
mButtonNotAllowMultipleDevices.setVisibility(View.VISIBLE);
mMultipleDeviceList.setVisibility(View.VISIBLE);
- mProgressIndicator.setVisibility(View.VISIBLE);
+ mMultipleDeviceSpinner.setVisibility(View.VISIBLE);
}
private void onListItemClick(int position) {
diff --git a/packages/ConnectivityT/OWNERS b/packages/ConnectivityT/OWNERS
deleted file mode 100644
index adbcd4b..0000000
--- a/packages/ConnectivityT/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# OWNERS block for code move: b/222234190
-reminv@google.com
-
-# file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking
-# per-file **IpSec* = file:/services/core/java/com/android/server/vcn/OWNERS
diff --git a/packages/ConnectivityT/framework-t/Android.bp b/packages/ConnectivityT/framework-t/Android.bp
deleted file mode 100644
index bc27852..0000000
--- a/packages/ConnectivityT/framework-t/Android.bp
+++ /dev/null
@@ -1,205 +0,0 @@
-//
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
- // See: http://go/android-license-faq
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-// NetworkStats related libraries.
-
-filegroup {
- name: "framework-connectivity-netstats-internal-sources",
- srcs: [
- "src/android/app/usage/*.java",
- "src/android/net/DataUsageRequest.*",
- "src/android/net/INetworkStatsService.aidl",
- "src/android/net/INetworkStatsSession.aidl",
- "src/android/net/NetworkIdentity.java",
- "src/android/net/NetworkIdentitySet.java",
- "src/android/net/NetworkStateSnapshot.*",
- "src/android/net/NetworkStats.*",
- "src/android/net/NetworkStatsAccess.*",
- "src/android/net/NetworkStatsCollection.*",
- "src/android/net/NetworkStatsHistory.*",
- "src/android/net/NetworkTemplate.*",
- "src/android/net/TrafficStats.java",
- "src/android/net/UnderlyingNetworkInfo.*",
- "src/android/net/netstats/**/*.*",
- ],
- path: "src",
- visibility: [
- "//visibility:private",
- ],
-}
-
-filegroup {
- name: "framework-connectivity-netstats-aidl-export-sources",
- srcs: [
- "aidl-export/android/net/NetworkStats.aidl",
- "aidl-export/android/net/NetworkTemplate.aidl",
- ],
- path: "aidl-export",
- visibility: [
- "//visibility:private",
- ],
-}
-
-filegroup {
- name: "framework-connectivity-netstats-sources",
- srcs: [
- ":framework-connectivity-netstats-internal-sources",
- ":framework-connectivity-netstats-aidl-export-sources",
- ],
- visibility: [
- "//visibility:private",
- ],
-}
-
-// Nsd related libraries.
-
-filegroup {
- name: "framework-connectivity-nsd-internal-sources",
- srcs: [
- "src/android/net/nsd/*.aidl",
- "src/android/net/nsd/*.java",
- ],
- path: "src",
- visibility: [
- "//visibility:private",
- ],
-}
-
-filegroup {
- name: "framework-connectivity-nsd-aidl-export-sources",
- srcs: [
- "aidl-export/android/net/nsd/*.aidl",
- ],
- path: "aidl-export",
- visibility: [
- "//visibility:private",
- ],
-}
-
-filegroup {
- name: "framework-connectivity-nsd-sources",
- srcs: [
- ":framework-connectivity-nsd-internal-sources",
- ":framework-connectivity-nsd-aidl-export-sources",
- ],
- visibility: [
- "//visibility:private",
- ],
-}
-
-// IpSec related libraries.
-
-filegroup {
- name: "framework-connectivity-ipsec-sources",
- srcs: [
- "src/android/net/IIpSecService.aidl",
- "src/android/net/IpSec*.*",
- ],
- path: "src",
- visibility: [
- "//visibility:private",
- ],
-}
-
-// Ethernet related libraries.
-
-filegroup {
- name: "framework-connectivity-ethernet-sources",
- srcs: [
- "src/android/net/EthernetManager.java",
- "src/android/net/EthernetNetworkManagementException.java",
- "src/android/net/EthernetNetworkManagementException.aidl",
- "src/android/net/EthernetNetworkSpecifier.java",
- "src/android/net/EthernetNetworkUpdateRequest.java",
- "src/android/net/EthernetNetworkUpdateRequest.aidl",
- "src/android/net/IEthernetManager.aidl",
- "src/android/net/IEthernetServiceListener.aidl",
- "src/android/net/INetworkInterfaceOutcomeReceiver.aidl",
- "src/android/net/ITetheredInterfaceCallback.aidl",
- ],
- path: "src",
- visibility: [
- "//visibility:private",
- ],
-}
-
-// Connectivity-T common libraries.
-
-filegroup {
- name: "framework-connectivity-tiramisu-internal-sources",
- srcs: [
- "src/android/net/ConnectivityFrameworkInitializerTiramisu.java",
- ],
- path: "src",
- visibility: [
- "//visibility:private",
- ],
-}
-
-// TODO: remove this empty filegroup.
-filegroup {
- name: "framework-connectivity-tiramisu-sources",
- srcs: [],
- visibility: ["//frameworks/base"],
-}
-
-filegroup {
- name: "framework-connectivity-tiramisu-updatable-sources",
- srcs: [
- ":framework-connectivity-ethernet-sources",
- ":framework-connectivity-ipsec-sources",
- ":framework-connectivity-netstats-sources",
- ":framework-connectivity-nsd-sources",
- ":framework-connectivity-tiramisu-internal-sources",
- ],
- visibility: [
- "//frameworks/base",
- "//packages/modules/Connectivity:__subpackages__",
- ],
-}
-
-cc_library_shared {
- name: "libframework-connectivity-tiramisu-jni",
- min_sdk_version: "30",
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- // Don't warn about S API usage even with
- // min_sdk 30: the library is only loaded
- // on S+ devices
- "-Wno-unguarded-availability",
- "-Wthread-safety",
- ],
- srcs: [
- "jni/android_net_TrafficStats.cpp",
- "jni/onload.cpp",
- ],
- shared_libs: [
- "libandroid",
- "liblog",
- "libnativehelper",
- ],
- stl: "none",
- apex_available: [
- "com.android.tethering",
- ],
-}
diff --git a/packages/ConnectivityT/framework-t/aidl-export/android/net/NetworkTemplate.aidl b/packages/ConnectivityT/framework-t/aidl-export/android/net/NetworkTemplate.aidl
deleted file mode 100644
index 3d37488..0000000
--- a/packages/ConnectivityT/framework-t/aidl-export/android/net/NetworkTemplate.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, 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.net;
-
-parcelable NetworkTemplate;
diff --git a/packages/ConnectivityT/framework-t/aidl-export/android/net/nsd/NsdServiceInfo.aidl b/packages/ConnectivityT/framework-t/aidl-export/android/net/nsd/NsdServiceInfo.aidl
deleted file mode 100644
index 657bdd1..0000000
--- a/packages/ConnectivityT/framework-t/aidl-export/android/net/nsd/NsdServiceInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.nsd;
-
-@JavaOnlyStableParcelable parcelable NsdServiceInfo;
\ No newline at end of file
diff --git a/packages/ConnectivityT/framework-t/jni/android_net_TrafficStats.cpp b/packages/ConnectivityT/framework-t/jni/android_net_TrafficStats.cpp
deleted file mode 100644
index f3c58b1..0000000
--- a/packages/ConnectivityT/framework-t/jni/android_net_TrafficStats.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android/file_descriptor_jni.h>
-#include <android/multinetwork.h>
-#include <nativehelper/JNIHelp.h>
-
-namespace android {
-
-static jint tagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor, jint tag, jint uid) {
- int fd = AFileDescriptor_getFd(env, fileDescriptor);
- if (fd == -1) return -EBADF;
- return android_tag_socket_with_uid(fd, tag, uid);
-}
-
-static jint untagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor) {
- int fd = AFileDescriptor_getFd(env, fileDescriptor);
- if (fd == -1) return -EBADF;
- return android_untag_socket(fd);
-}
-
-static const JNINativeMethod gMethods[] = {
- /* name, signature, funcPtr */
- { "native_tagSocketFd", "(Ljava/io/FileDescriptor;II)I", (void*) tagSocketFd },
- { "native_untagSocketFd", "(Ljava/io/FileDescriptor;)I", (void*) untagSocketFd },
-};
-
-int register_android_net_TrafficStats(JNIEnv* env) {
- return jniRegisterNativeMethods(env, "android/net/TrafficStats", gMethods, NELEM(gMethods));
-}
-
-}; // namespace android
-
diff --git a/packages/ConnectivityT/framework-t/jni/onload.cpp b/packages/ConnectivityT/framework-t/jni/onload.cpp
deleted file mode 100644
index 1fb42c6..0000000
--- a/packages/ConnectivityT/framework-t/jni/onload.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "FrameworkConnectivityJNI"
-
-#include <log/log.h>
-#include <nativehelper/JNIHelp.h>
-
-namespace android {
-
-int register_android_net_TrafficStats(JNIEnv* env);
-
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
- JNIEnv *env;
- if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
- __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
- return JNI_ERR;
- }
-
- if (register_android_net_TrafficStats(env) < 0) return JNI_ERR;
-
- return JNI_VERSION_1_6;
-}
-
-}; // namespace android
-
diff --git a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStats.java b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStats.java
deleted file mode 100644
index 74fe4bd..0000000
--- a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStats.java
+++ /dev/null
@@ -1,744 +0,0 @@
-/**
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy
- * of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-
-package android.app.usage;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.INetworkStatsService;
-import android.net.INetworkStatsSession;
-import android.net.NetworkStatsHistory;
-import android.net.NetworkTemplate;
-import android.net.TrafficStats;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.net.module.util.CollectionUtils;
-
-import dalvik.system.CloseGuard;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-
-/**
- * Class providing enumeration over buckets of network usage statistics. {@link NetworkStats} objects
- * are returned as results to various queries in {@link NetworkStatsManager}.
- */
-public final class NetworkStats implements AutoCloseable {
- private final static String TAG = "NetworkStats";
-
- private final CloseGuard mCloseGuard = CloseGuard.get();
-
- /**
- * Start timestamp of stats collected
- */
- private final long mStartTimeStamp;
-
- /**
- * End timestamp of stats collected
- */
- private final long mEndTimeStamp;
-
- /**
- * Non-null array indicates the query enumerates over uids.
- */
- private int[] mUids;
-
- /**
- * Index of the current uid in mUids when doing uid enumeration or a single uid value,
- * depending on query type.
- */
- private int mUidOrUidIndex;
-
- /**
- * Tag id in case if was specified in the query.
- */
- private int mTag = android.net.NetworkStats.TAG_NONE;
-
- /**
- * State in case it was not specified in the query.
- */
- private int mState = Bucket.STATE_ALL;
-
- /**
- * The session while the query requires it, null if all the stats have been collected or close()
- * has been called.
- */
- private INetworkStatsSession mSession;
- private NetworkTemplate mTemplate;
-
- /**
- * Results of a summary query.
- */
- private android.net.NetworkStats mSummary = null;
-
- /**
- * Results of detail queries.
- */
- private NetworkStatsHistory mHistory = null;
-
- /**
- * Where we are in enumerating over the current result.
- */
- private int mEnumerationIndex = 0;
-
- /**
- * Recycling entry objects to prevent heap fragmentation.
- */
- private android.net.NetworkStats.Entry mRecycledSummaryEntry = null;
- private NetworkStatsHistory.Entry mRecycledHistoryEntry = null;
-
- /** @hide */
- NetworkStats(Context context, NetworkTemplate template, int flags, long startTimestamp,
- long endTimestamp, INetworkStatsService statsService)
- throws RemoteException, SecurityException {
- // Open network stats session
- mSession = statsService.openSessionForUsageStats(flags, context.getOpPackageName());
- mCloseGuard.open("close");
- mTemplate = template;
- mStartTimeStamp = startTimestamp;
- mEndTimeStamp = endTimestamp;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mCloseGuard != null) {
- mCloseGuard.warnIfOpen();
- }
- close();
- } finally {
- super.finalize();
- }
- }
-
- // -------------------------BEGINNING OF PUBLIC API-----------------------------------
-
- /**
- * Buckets are the smallest elements of a query result. As some dimensions of a result may be
- * aggregated (e.g. time or state) some values may be equal across all buckets.
- */
- public static class Bucket {
- /** @hide */
- @IntDef(prefix = { "STATE_" }, value = {
- STATE_ALL,
- STATE_DEFAULT,
- STATE_FOREGROUND
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface State {}
-
- /**
- * Combined usage across all states.
- */
- public static final int STATE_ALL = -1;
-
- /**
- * Usage not accounted for in any other state.
- */
- public static final int STATE_DEFAULT = 0x1;
-
- /**
- * Foreground usage.
- */
- public static final int STATE_FOREGROUND = 0x2;
-
- /**
- * Special UID value for aggregate/unspecified.
- */
- public static final int UID_ALL = android.net.NetworkStats.UID_ALL;
-
- /**
- * Special UID value for removed apps.
- */
- public static final int UID_REMOVED = TrafficStats.UID_REMOVED;
-
- /**
- * Special UID value for data usage by tethering.
- */
- public static final int UID_TETHERING = TrafficStats.UID_TETHERING;
-
- /** @hide */
- @IntDef(prefix = { "METERED_" }, value = {
- METERED_ALL,
- METERED_NO,
- METERED_YES
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Metered {}
-
- /**
- * Combined usage across all metered states. Covers metered and unmetered usage.
- */
- public static final int METERED_ALL = -1;
-
- /**
- * Usage that occurs on an unmetered network.
- */
- public static final int METERED_NO = 0x1;
-
- /**
- * Usage that occurs on a metered network.
- *
- * <p>A network is classified as metered when the user is sensitive to heavy data usage on
- * that connection.
- */
- public static final int METERED_YES = 0x2;
-
- /** @hide */
- @IntDef(prefix = { "ROAMING_" }, value = {
- ROAMING_ALL,
- ROAMING_NO,
- ROAMING_YES
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Roaming {}
-
- /**
- * Combined usage across all roaming states. Covers both roaming and non-roaming usage.
- */
- public static final int ROAMING_ALL = -1;
-
- /**
- * Usage that occurs on a home, non-roaming network.
- *
- * <p>Any cellular usage in this bucket was incurred while the device was connected to a
- * tower owned or operated by the user's wireless carrier, or a tower that the user's
- * wireless carrier has indicated should be treated as a home network regardless.
- *
- * <p>This is also the default value for network types that do not support roaming.
- */
- public static final int ROAMING_NO = 0x1;
-
- /**
- * Usage that occurs on a roaming network.
- *
- * <p>Any cellular usage in this bucket as incurred while the device was roaming on another
- * carrier's network, for which additional charges may apply.
- */
- public static final int ROAMING_YES = 0x2;
-
- /** @hide */
- @IntDef(prefix = { "DEFAULT_NETWORK_" }, value = {
- DEFAULT_NETWORK_ALL,
- DEFAULT_NETWORK_NO,
- DEFAULT_NETWORK_YES
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface DefaultNetworkStatus {}
-
- /**
- * Combined usage for this network regardless of default network status.
- */
- public static final int DEFAULT_NETWORK_ALL = -1;
-
- /**
- * Usage that occurs while this network is not a default network.
- *
- * <p>This implies that the app responsible for this usage requested that it occur on a
- * specific network different from the one(s) the system would have selected for it.
- */
- public static final int DEFAULT_NETWORK_NO = 0x1;
-
- /**
- * Usage that occurs while this network is a default network.
- *
- * <p>This implies that the app either did not select a specific network for this usage,
- * or it selected a network that the system could have selected for app traffic.
- */
- public static final int DEFAULT_NETWORK_YES = 0x2;
-
- /**
- * Special TAG value for total data across all tags
- */
- public static final int TAG_NONE = android.net.NetworkStats.TAG_NONE;
-
- private int mUid;
- private int mTag;
- private int mState;
- private int mDefaultNetworkStatus;
- private int mMetered;
- private int mRoaming;
- private long mBeginTimeStamp;
- private long mEndTimeStamp;
- private long mRxBytes;
- private long mRxPackets;
- private long mTxBytes;
- private long mTxPackets;
-
- private static int convertSet(@State int state) {
- switch (state) {
- case STATE_ALL: return android.net.NetworkStats.SET_ALL;
- case STATE_DEFAULT: return android.net.NetworkStats.SET_DEFAULT;
- case STATE_FOREGROUND: return android.net.NetworkStats.SET_FOREGROUND;
- }
- return 0;
- }
-
- private static @State int convertState(int networkStatsSet) {
- switch (networkStatsSet) {
- case android.net.NetworkStats.SET_ALL : return STATE_ALL;
- case android.net.NetworkStats.SET_DEFAULT : return STATE_DEFAULT;
- case android.net.NetworkStats.SET_FOREGROUND : return STATE_FOREGROUND;
- }
- return 0;
- }
-
- private static int convertUid(int uid) {
- switch (uid) {
- case TrafficStats.UID_REMOVED: return UID_REMOVED;
- case TrafficStats.UID_TETHERING: return UID_TETHERING;
- }
- return uid;
- }
-
- private static int convertTag(int tag) {
- switch (tag) {
- case android.net.NetworkStats.TAG_NONE: return TAG_NONE;
- }
- return tag;
- }
-
- private static @Metered int convertMetered(int metered) {
- switch (metered) {
- case android.net.NetworkStats.METERED_ALL : return METERED_ALL;
- case android.net.NetworkStats.METERED_NO: return METERED_NO;
- case android.net.NetworkStats.METERED_YES: return METERED_YES;
- }
- return 0;
- }
-
- private static @Roaming int convertRoaming(int roaming) {
- switch (roaming) {
- case android.net.NetworkStats.ROAMING_ALL : return ROAMING_ALL;
- case android.net.NetworkStats.ROAMING_NO: return ROAMING_NO;
- case android.net.NetworkStats.ROAMING_YES: return ROAMING_YES;
- }
- return 0;
- }
-
- private static @DefaultNetworkStatus int convertDefaultNetworkStatus(
- int defaultNetworkStatus) {
- switch (defaultNetworkStatus) {
- case android.net.NetworkStats.DEFAULT_NETWORK_ALL : return DEFAULT_NETWORK_ALL;
- case android.net.NetworkStats.DEFAULT_NETWORK_NO: return DEFAULT_NETWORK_NO;
- case android.net.NetworkStats.DEFAULT_NETWORK_YES: return DEFAULT_NETWORK_YES;
- }
- return 0;
- }
-
- public Bucket() {
- }
-
- /**
- * Key of the bucket. Usually an app uid or one of the following special values:<p />
- * <ul>
- * <li>{@link #UID_REMOVED}</li>
- * <li>{@link #UID_TETHERING}</li>
- * <li>{@link android.os.Process#SYSTEM_UID}</li>
- * </ul>
- * @return Bucket key.
- */
- public int getUid() {
- return mUid;
- }
-
- /**
- * Tag of the bucket.<p />
- * @return Bucket tag.
- */
- public int getTag() {
- return mTag;
- }
-
- /**
- * Usage state. One of the following values:<p/>
- * <ul>
- * <li>{@link #STATE_ALL}</li>
- * <li>{@link #STATE_DEFAULT}</li>
- * <li>{@link #STATE_FOREGROUND}</li>
- * </ul>
- * @return Usage state.
- */
- public @State int getState() {
- return mState;
- }
-
- /**
- * Metered state. One of the following values:<p/>
- * <ul>
- * <li>{@link #METERED_ALL}</li>
- * <li>{@link #METERED_NO}</li>
- * <li>{@link #METERED_YES}</li>
- * </ul>
- * <p>A network is classified as metered when the user is sensitive to heavy data usage on
- * that connection. Apps may warn before using these networks for large downloads. The
- * metered state can be set by the user within data usage network restrictions.
- */
- public @Metered int getMetered() {
- return mMetered;
- }
-
- /**
- * Roaming state. One of the following values:<p/>
- * <ul>
- * <li>{@link #ROAMING_ALL}</li>
- * <li>{@link #ROAMING_NO}</li>
- * <li>{@link #ROAMING_YES}</li>
- * </ul>
- */
- public @Roaming int getRoaming() {
- return mRoaming;
- }
-
- /**
- * Default network status. One of the following values:<p/>
- * <ul>
- * <li>{@link #DEFAULT_NETWORK_ALL}</li>
- * <li>{@link #DEFAULT_NETWORK_NO}</li>
- * <li>{@link #DEFAULT_NETWORK_YES}</li>
- * </ul>
- */
- public @DefaultNetworkStatus int getDefaultNetworkStatus() {
- return mDefaultNetworkStatus;
- }
-
- /**
- * Start timestamp of the bucket's time interval. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @return Start of interval.
- */
- public long getStartTimeStamp() {
- return mBeginTimeStamp;
- }
-
- /**
- * End timestamp of the bucket's time interval. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @return End of interval.
- */
- public long getEndTimeStamp() {
- return mEndTimeStamp;
- }
-
- /**
- * Number of bytes received during the bucket's time interval. Statistics are measured at
- * the network layer, so they include both TCP and UDP usage.
- * @return Number of bytes.
- */
- public long getRxBytes() {
- return mRxBytes;
- }
-
- /**
- * Number of bytes transmitted during the bucket's time interval. Statistics are measured at
- * the network layer, so they include both TCP and UDP usage.
- * @return Number of bytes.
- */
- public long getTxBytes() {
- return mTxBytes;
- }
-
- /**
- * Number of packets received during the bucket's time interval. Statistics are measured at
- * the network layer, so they include both TCP and UDP usage.
- * @return Number of packets.
- */
- public long getRxPackets() {
- return mRxPackets;
- }
-
- /**
- * Number of packets transmitted during the bucket's time interval. Statistics are measured
- * at the network layer, so they include both TCP and UDP usage.
- * @return Number of packets.
- */
- public long getTxPackets() {
- return mTxPackets;
- }
- }
-
- /**
- * Fills the recycled bucket with data of the next bin in the enumeration.
- * @param bucketOut Bucket to be filled with data. If null, the method does
- * nothing and returning false.
- * @return true if successfully filled the bucket, false otherwise.
- */
- public boolean getNextBucket(@Nullable Bucket bucketOut) {
- if (mSummary != null) {
- return getNextSummaryBucket(bucketOut);
- } else {
- return getNextHistoryBucket(bucketOut);
- }
- }
-
- /**
- * Check if it is possible to ask for a next bucket in the enumeration.
- * @return true if there is at least one more bucket.
- */
- public boolean hasNextBucket() {
- if (mSummary != null) {
- return mEnumerationIndex < mSummary.size();
- } else if (mHistory != null) {
- return mEnumerationIndex < mHistory.size()
- || hasNextUid();
- }
- return false;
- }
-
- /**
- * Closes the enumeration. Call this method before this object gets out of scope.
- */
- @Override
- public void close() {
- if (mSession != null) {
- try {
- mSession.close();
- } catch (RemoteException e) {
- Log.w(TAG, e);
- // Otherwise, meh
- }
- }
- mSession = null;
- if (mCloseGuard != null) {
- mCloseGuard.close();
- }
- }
-
- // -------------------------END OF PUBLIC API-----------------------------------
-
- /**
- * Collects device summary results into a Bucket.
- * @throws RemoteException
- */
- Bucket getDeviceSummaryForNetwork() throws RemoteException {
- mSummary = mSession.getDeviceSummaryForNetwork(mTemplate, mStartTimeStamp, mEndTimeStamp);
-
- // Setting enumeration index beyond end to avoid accidental enumeration over data that does
- // not belong to the calling user.
- mEnumerationIndex = mSummary.size();
-
- return getSummaryAggregate();
- }
-
- /**
- * Collects summary results and sets summary enumeration mode.
- * @throws RemoteException
- */
- void startSummaryEnumeration() throws RemoteException {
- mSummary = mSession.getSummaryForAllUid(mTemplate, mStartTimeStamp, mEndTimeStamp,
- false /* includeTags */);
- mEnumerationIndex = 0;
- }
-
- /**
- * Collects tagged summary results and sets summary enumeration mode.
- * @throws RemoteException
- */
- void startTaggedSummaryEnumeration() throws RemoteException {
- mSummary = mSession.getTaggedSummaryForAllUid(mTemplate, mStartTimeStamp, mEndTimeStamp);
- mEnumerationIndex = 0;
- }
-
- /**
- * Collects history results for uid and resets history enumeration index.
- */
- void startHistoryUidEnumeration(int uid, int tag, int state) {
- mHistory = null;
- try {
- mHistory = mSession.getHistoryIntervalForUid(mTemplate, uid,
- Bucket.convertSet(state), tag, NetworkStatsHistory.FIELD_ALL,
- mStartTimeStamp, mEndTimeStamp);
- setSingleUidTagState(uid, tag, state);
- } catch (RemoteException e) {
- Log.w(TAG, e);
- // Leaving mHistory null
- }
- mEnumerationIndex = 0;
- }
-
- /**
- * Collects history results for network and resets history enumeration index.
- */
- void startHistoryDeviceEnumeration() {
- try {
- mHistory = mSession.getHistoryIntervalForNetwork(
- mTemplate, NetworkStatsHistory.FIELD_ALL, mStartTimeStamp, mEndTimeStamp);
- } catch (RemoteException e) {
- Log.w(TAG, e);
- mHistory = null;
- }
- mEnumerationIndex = 0;
- }
-
- /**
- * Starts uid enumeration for current user.
- * @throws RemoteException
- */
- void startUserUidEnumeration() throws RemoteException {
- // TODO: getRelevantUids should be sensitive to time interval. When that's done,
- // the filtering logic below can be removed.
- int[] uids = mSession.getRelevantUids();
- // Filtering of uids with empty history.
- final ArrayList<Integer> filteredUids = new ArrayList<>();
- for (int uid : uids) {
- try {
- NetworkStatsHistory history = mSession.getHistoryIntervalForUid(mTemplate, uid,
- android.net.NetworkStats.SET_ALL, android.net.NetworkStats.TAG_NONE,
- NetworkStatsHistory.FIELD_ALL, mStartTimeStamp, mEndTimeStamp);
- if (history != null && history.size() > 0) {
- filteredUids.add(uid);
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Error while getting history of uid " + uid, e);
- }
- }
- mUids = CollectionUtils.toIntArray(filteredUids);
- mUidOrUidIndex = -1;
- stepHistory();
- }
-
- /**
- * Steps to next uid in enumeration and collects history for that.
- */
- private void stepHistory(){
- if (hasNextUid()) {
- stepUid();
- mHistory = null;
- try {
- mHistory = mSession.getHistoryIntervalForUid(mTemplate, getUid(),
- android.net.NetworkStats.SET_ALL, android.net.NetworkStats.TAG_NONE,
- NetworkStatsHistory.FIELD_ALL, mStartTimeStamp, mEndTimeStamp);
- } catch (RemoteException e) {
- Log.w(TAG, e);
- // Leaving mHistory null
- }
- mEnumerationIndex = 0;
- }
- }
-
- private void fillBucketFromSummaryEntry(Bucket bucketOut) {
- bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid);
- bucketOut.mTag = Bucket.convertTag(mRecycledSummaryEntry.tag);
- bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set);
- bucketOut.mDefaultNetworkStatus = Bucket.convertDefaultNetworkStatus(
- mRecycledSummaryEntry.defaultNetwork);
- bucketOut.mMetered = Bucket.convertMetered(mRecycledSummaryEntry.metered);
- bucketOut.mRoaming = Bucket.convertRoaming(mRecycledSummaryEntry.roaming);
- bucketOut.mBeginTimeStamp = mStartTimeStamp;
- bucketOut.mEndTimeStamp = mEndTimeStamp;
- bucketOut.mRxBytes = mRecycledSummaryEntry.rxBytes;
- bucketOut.mRxPackets = mRecycledSummaryEntry.rxPackets;
- bucketOut.mTxBytes = mRecycledSummaryEntry.txBytes;
- bucketOut.mTxPackets = mRecycledSummaryEntry.txPackets;
- }
-
- /**
- * Getting the next item in summary enumeration.
- * @param bucketOut Next item will be set here.
- * @return true if a next item could be set.
- */
- private boolean getNextSummaryBucket(@Nullable Bucket bucketOut) {
- if (bucketOut != null && mEnumerationIndex < mSummary.size()) {
- mRecycledSummaryEntry = mSummary.getValues(mEnumerationIndex++, mRecycledSummaryEntry);
- fillBucketFromSummaryEntry(bucketOut);
- return true;
- }
- return false;
- }
-
- Bucket getSummaryAggregate() {
- if (mSummary == null) {
- return null;
- }
- Bucket bucket = new Bucket();
- if (mRecycledSummaryEntry == null) {
- mRecycledSummaryEntry = new android.net.NetworkStats.Entry();
- }
- mSummary.getTotal(mRecycledSummaryEntry);
- fillBucketFromSummaryEntry(bucket);
- return bucket;
- }
-
- /**
- * Getting the next item in a history enumeration.
- * @param bucketOut Next item will be set here.
- * @return true if a next item could be set.
- */
- private boolean getNextHistoryBucket(@Nullable Bucket bucketOut) {
- if (bucketOut != null && mHistory != null) {
- if (mEnumerationIndex < mHistory.size()) {
- mRecycledHistoryEntry = mHistory.getValues(mEnumerationIndex++,
- mRecycledHistoryEntry);
- bucketOut.mUid = Bucket.convertUid(getUid());
- bucketOut.mTag = Bucket.convertTag(mTag);
- bucketOut.mState = mState;
- bucketOut.mDefaultNetworkStatus = Bucket.DEFAULT_NETWORK_ALL;
- bucketOut.mMetered = Bucket.METERED_ALL;
- bucketOut.mRoaming = Bucket.ROAMING_ALL;
- bucketOut.mBeginTimeStamp = mRecycledHistoryEntry.bucketStart;
- bucketOut.mEndTimeStamp = mRecycledHistoryEntry.bucketStart +
- mRecycledHistoryEntry.bucketDuration;
- bucketOut.mRxBytes = mRecycledHistoryEntry.rxBytes;
- bucketOut.mRxPackets = mRecycledHistoryEntry.rxPackets;
- bucketOut.mTxBytes = mRecycledHistoryEntry.txBytes;
- bucketOut.mTxPackets = mRecycledHistoryEntry.txPackets;
- return true;
- } else if (hasNextUid()) {
- stepHistory();
- return getNextHistoryBucket(bucketOut);
- }
- }
- return false;
- }
-
- // ------------------ UID LOGIC------------------------
-
- private boolean isUidEnumeration() {
- return mUids != null;
- }
-
- private boolean hasNextUid() {
- return isUidEnumeration() && (mUidOrUidIndex + 1) < mUids.length;
- }
-
- private int getUid() {
- // Check if uid enumeration.
- if (isUidEnumeration()) {
- if (mUidOrUidIndex < 0 || mUidOrUidIndex >= mUids.length) {
- throw new IndexOutOfBoundsException(
- "Index=" + mUidOrUidIndex + " mUids.length=" + mUids.length);
- }
- return mUids[mUidOrUidIndex];
- }
- // Single uid mode.
- return mUidOrUidIndex;
- }
-
- private void setSingleUidTagState(int uid, int tag, int state) {
- mUidOrUidIndex = uid;
- mTag = tag;
- mState = state;
- }
-
- private void stepUid() {
- if (mUids != null) {
- ++mUidOrUidIndex;
- }
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java
deleted file mode 100644
index f41475b..0000000
--- a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java
+++ /dev/null
@@ -1,1238 +0,0 @@
-/**
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy
- * of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-
-package android.app.usage;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.annotation.WorkerThread;
-import android.app.usage.NetworkStats.Bucket;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.DataUsageRequest;
-import android.net.INetworkStatsService;
-import android.net.Network;
-import android.net.NetworkStack;
-import android.net.NetworkStateSnapshot;
-import android.net.NetworkTemplate;
-import android.net.UnderlyingNetworkInfo;
-import android.net.netstats.IUsageCallback;
-import android.net.netstats.NetworkStatsDataMigrationUtils;
-import android.net.netstats.provider.INetworkStatsProviderCallback;
-import android.net.netstats.provider.NetworkStatsProvider;
-import android.os.Build;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.net.module.util.NetworkIdentityUtils;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * Provides access to network usage history and statistics. Usage data is collected in
- * discrete bins of time called 'Buckets'. See {@link NetworkStats.Bucket} for details.
- * <p />
- * Queries can define a time interval in the form of start and end timestamps (Long.MIN_VALUE and
- * Long.MAX_VALUE can be used to simulate open ended intervals). By default, apps can only obtain
- * data about themselves. See the below note for special cases in which apps can obtain data about
- * other applications.
- * <h3>
- * Summary queries
- * </h3>
- * {@link #querySummaryForDevice} <p />
- * {@link #querySummaryForUser} <p />
- * {@link #querySummary} <p />
- * These queries aggregate network usage across the whole interval. Therefore there will be only one
- * bucket for a particular key, state, metered and roaming combination. In case of the user-wide
- * and device-wide summaries a single bucket containing the totalised network usage is returned.
- * <h3>
- * History queries
- * </h3>
- * {@link #queryDetailsForUid} <p />
- * {@link #queryDetails} <p />
- * These queries do not aggregate over time but do aggregate over state, metered and roaming.
- * Therefore there can be multiple buckets for a particular key. However, all Buckets will have
- * {@code state} {@link NetworkStats.Bucket#STATE_ALL},
- * {@code defaultNetwork} {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
- * {@code metered } {@link NetworkStats.Bucket#METERED_ALL},
- * {@code roaming} {@link NetworkStats.Bucket#ROAMING_ALL}.
- * <p />
- * <b>NOTE:</b> Calling {@link #querySummaryForDevice} or accessing stats for apps other than the
- * calling app requires the permission {@link android.Manifest.permission#PACKAGE_USAGE_STATS},
- * which is a system-level permission and will not be granted to third-party apps. However,
- * declaring the permission implies intention to use the API and the user of the device can grant
- * permission through the Settings application.
- * <p />
- * Profile owner apps are automatically granted permission to query data on the profile they manage
- * (that is, for any query except {@link #querySummaryForDevice}). Device owner apps and carrier-
- * privileged apps likewise get access to usage data for all users on the device.
- * <p />
- * In addition to tethering usage, usage by removed users and apps, and usage by the system
- * is also included in the results for callers with one of these higher levels of access.
- * <p />
- * <b>NOTE:</b> Prior to API level {@value android.os.Build.VERSION_CODES#N}, all calls to these APIs required
- * the above permission, even to access an app's own data usage, and carrier-privileged apps were
- * not included.
- */
-@SystemService(Context.NETWORK_STATS_SERVICE)
-public class NetworkStatsManager {
- private static final String TAG = "NetworkStatsManager";
- private static final boolean DBG = false;
-
- /** @hide */
- public static final int CALLBACK_LIMIT_REACHED = 0;
- /** @hide */
- public static final int CALLBACK_RELEASED = 1;
-
- /**
- * Minimum data usage threshold for registering usage callbacks.
- *
- * Requests registered with a threshold lower than this will only be triggered once this minimum
- * is reached.
- * @hide
- */
- public static final long MIN_THRESHOLD_BYTES = 2 * 1_048_576L; // 2MiB
-
- private final Context mContext;
- private final INetworkStatsService mService;
-
- /**
- * @deprecated Use {@link NetworkStatsDataMigrationUtils#PREFIX_XT}
- * instead.
- * @hide
- */
- @Deprecated
- public static final String PREFIX_DEV = "dev";
-
- /** @hide */
- public static final int FLAG_POLL_ON_OPEN = 1 << 0;
- /** @hide */
- public static final int FLAG_POLL_FORCE = 1 << 1;
- /** @hide */
- public static final int FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN = 1 << 2;
-
- /**
- * Virtual RAT type to represent 5G NSA (Non Stand Alone) mode, where the primary cell is
- * still LTE and network allocates a secondary 5G cell so telephony reports RAT = LTE along
- * with NR state as connected. This is a concept added by NetworkStats on top of the telephony
- * constants for backward compatibility of metrics so this should not be overlapped with any of
- * the {@code TelephonyManager.NETWORK_TYPE_*} constants.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int NETWORK_TYPE_5G_NSA = -2;
-
- private int mFlags;
-
- /** @hide */
- @VisibleForTesting
- public NetworkStatsManager(Context context, INetworkStatsService service) {
- mContext = context;
- mService = service;
- setPollOnOpen(true);
- setAugmentWithSubscriptionPlan(true);
- }
-
- /** @hide */
- public INetworkStatsService getBinder() {
- return mService;
- }
-
- /**
- * Set poll on open flag to indicate the poll is needed before service gets statistics
- * result. This is default enabled. However, for any non-privileged caller, the poll might
- * be omitted in case of rate limiting.
- *
- * @param pollOnOpen true if poll is needed.
- * @hide
- */
- // The system will ignore any non-default values for non-privileged
- // processes, so processes that don't hold the appropriate permissions
- // can make no use of this API.
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK})
- public void setPollOnOpen(boolean pollOnOpen) {
- if (pollOnOpen) {
- mFlags |= FLAG_POLL_ON_OPEN;
- } else {
- mFlags &= ~FLAG_POLL_ON_OPEN;
- }
- }
-
- /**
- * Set poll force flag to indicate that calling any subsequent query method will force a stats
- * poll.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @SystemApi(client = MODULE_LIBRARIES)
- public void setPollForce(boolean pollForce) {
- if (pollForce) {
- mFlags |= FLAG_POLL_FORCE;
- } else {
- mFlags &= ~FLAG_POLL_FORCE;
- }
- }
-
- /** @hide */
- public void setAugmentWithSubscriptionPlan(boolean augmentWithSubscriptionPlan) {
- if (augmentWithSubscriptionPlan) {
- mFlags |= FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
- } else {
- mFlags &= ~FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
- }
- }
-
- /**
- * Query network usage statistics summaries.
- *
- * Result is summarised data usage for the whole
- * device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and
- * roaming. This means the bucket's start and end timestamp will be the same as the
- * 'startTime' and 'endTime' arguments. State is going to be
- * {@link NetworkStats.Bucket#STATE_ALL}, uid {@link NetworkStats.Bucket#UID_ALL},
- * tag {@link NetworkStats.Bucket#TAG_NONE},
- * default network {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
- * metered {@link NetworkStats.Bucket#METERED_ALL},
- * and roaming {@link NetworkStats.Bucket#ROAMING_ALL}.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @param template Template used to match networks. See {@link NetworkTemplate}.
- * @param startTime Start of period, in milliseconds since the Unix epoch, see
- * {@link java.lang.System#currentTimeMillis}.
- * @param endTime End of period, in milliseconds since the Unix epoch, see
- * {@link java.lang.System#currentTimeMillis}.
- * @return Bucket Summarised data usage.
- *
- * @hide
- */
- @NonNull
- @WorkerThread
- @SystemApi(client = MODULE_LIBRARIES)
- public Bucket querySummaryForDevice(@NonNull NetworkTemplate template,
- long startTime, long endTime) {
- Objects.requireNonNull(template);
- try {
- NetworkStats stats =
- new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
- Bucket bucket = stats.getDeviceSummaryForNetwork();
- stats.close();
- return bucket;
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- return null; // To make the compiler happy.
- }
-
- /**
- * Query network usage statistics summaries. Result is summarised data usage for the whole
- * device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and
- * roaming. This means the bucket's start and end timestamp are going to be the same as the
- * 'startTime' and 'endTime' parameters. State is going to be
- * {@link NetworkStats.Bucket#STATE_ALL}, uid {@link NetworkStats.Bucket#UID_ALL},
- * tag {@link NetworkStats.Bucket#TAG_NONE},
- * default network {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
- * metered {@link NetworkStats.Bucket#METERED_ALL},
- * and roaming {@link NetworkStats.Bucket#ROAMING_ALL}.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @param networkType As defined in {@link ConnectivityManager}, e.g.
- * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
- * etc.
- * @param subscriberId If applicable, the subscriber id of the network interface.
- * <p>Starting with API level 29, the {@code subscriberId} is guarded by
- * additional restrictions. Calling apps that do not meet the new
- * requirements to access the {@code subscriberId} can provide a {@code
- * null} value when querying for the mobile network type to receive usage
- * for all mobile networks. For additional details see {@link
- * TelephonyManager#getSubscriberId()}.
- * <p>Starting with API level 31, calling apps can provide a
- * {@code subscriberId} with wifi network type to receive usage for
- * wifi networks which is under the given subscription if applicable.
- * Otherwise, pass {@code null} when querying all wifi networks.
- * @param startTime Start of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @param endTime End of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @return Bucket object or null if permissions are insufficient or error happened during
- * statistics collection.
- */
- @WorkerThread
- public Bucket querySummaryForDevice(int networkType, @Nullable String subscriberId,
- long startTime, long endTime) throws SecurityException, RemoteException {
- NetworkTemplate template;
- try {
- template = createTemplate(networkType, subscriberId);
- } catch (IllegalArgumentException e) {
- if (DBG) Log.e(TAG, "Cannot create template", e);
- return null;
- }
-
- return querySummaryForDevice(template, startTime, endTime);
- }
-
- /**
- * Query network usage statistics summaries. Result is summarised data usage for all uids
- * belonging to calling user. Result is a single Bucket aggregated over time, state and uid.
- * This means the bucket's start and end timestamp are going to be the same as the 'startTime'
- * and 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL},
- * uid {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE},
- * metered {@link NetworkStats.Bucket#METERED_ALL}, and roaming
- * {@link NetworkStats.Bucket#ROAMING_ALL}.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @param networkType As defined in {@link ConnectivityManager}, e.g.
- * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
- * etc.
- * @param subscriberId If applicable, the subscriber id of the network interface.
- * <p>Starting with API level 29, the {@code subscriberId} is guarded by
- * additional restrictions. Calling apps that do not meet the new
- * requirements to access the {@code subscriberId} can provide a {@code
- * null} value when querying for the mobile network type to receive usage
- * for all mobile networks. For additional details see {@link
- * TelephonyManager#getSubscriberId()}.
- * <p>Starting with API level 31, calling apps can provide a
- * {@code subscriberId} with wifi network type to receive usage for
- * wifi networks which is under the given subscription if applicable.
- * Otherwise, pass {@code null} when querying all wifi networks.
- * @param startTime Start of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @param endTime End of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @return Bucket object or null if permissions are insufficient or error happened during
- * statistics collection.
- */
- @WorkerThread
- public Bucket querySummaryForUser(int networkType, @Nullable String subscriberId,
- long startTime, long endTime) throws SecurityException, RemoteException {
- NetworkTemplate template;
- try {
- template = createTemplate(networkType, subscriberId);
- } catch (IllegalArgumentException e) {
- if (DBG) Log.e(TAG, "Cannot create template", e);
- return null;
- }
-
- NetworkStats stats;
- stats = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
- stats.startSummaryEnumeration();
-
- stats.close();
- return stats.getSummaryAggregate();
- }
-
- /**
- * Query network usage statistics summaries. Result filtered to include only uids belonging to
- * calling user. Result is aggregated over time, hence all buckets will have the same start and
- * end timestamps. Not aggregated over state, uid, default network, metered, or roaming. This
- * means buckets' start and end timestamps are going to be the same as the 'startTime' and
- * 'endTime' parameters. State, uid, metered, and roaming are going to vary, and tag is going to
- * be the same.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @param networkType As defined in {@link ConnectivityManager}, e.g.
- * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
- * etc.
- * @param subscriberId If applicable, the subscriber id of the network interface.
- * <p>Starting with API level 29, the {@code subscriberId} is guarded by
- * additional restrictions. Calling apps that do not meet the new
- * requirements to access the {@code subscriberId} can provide a {@code
- * null} value when querying for the mobile network type to receive usage
- * for all mobile networks. For additional details see {@link
- * TelephonyManager#getSubscriberId()}.
- * <p>Starting with API level 31, calling apps can provide a
- * {@code subscriberId} with wifi network type to receive usage for
- * wifi networks which is under the given subscription if applicable.
- * Otherwise, pass {@code null} when querying all wifi networks.
- * @param startTime Start of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @param endTime End of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @return Statistics object or null if permissions are insufficient or error happened during
- * statistics collection.
- */
- @WorkerThread
- public NetworkStats querySummary(int networkType, @Nullable String subscriberId, long startTime,
- long endTime) throws SecurityException, RemoteException {
- NetworkTemplate template;
- try {
- template = createTemplate(networkType, subscriberId);
- } catch (IllegalArgumentException e) {
- if (DBG) Log.e(TAG, "Cannot create template", e);
- return null;
- }
-
- return querySummary(template, startTime, endTime);
- }
-
- /**
- * Query network usage statistics summaries.
- *
- * The results will only include traffic made by UIDs belonging to the calling user profile.
- * The results are aggregated over time, so that all buckets will have the same start and
- * end timestamps as the passed arguments. Not aggregated over state, uid, default network,
- * metered, or roaming.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @param template Template used to match networks. See {@link NetworkTemplate}.
- * @param startTime Start of period, in milliseconds since the Unix epoch, see
- * {@link java.lang.System#currentTimeMillis}.
- * @param endTime End of period, in milliseconds since the Unix epoch, see
- * {@link java.lang.System#currentTimeMillis}.
- * @return Statistics which is described above.
- * @hide
- */
- @NonNull
- @SystemApi(client = MODULE_LIBRARIES)
- @WorkerThread
- public NetworkStats querySummary(@NonNull NetworkTemplate template, long startTime,
- long endTime) throws SecurityException {
- Objects.requireNonNull(template);
- try {
- NetworkStats result =
- new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
- result.startSummaryEnumeration();
- return result;
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- return null; // To make the compiler happy.
- }
-
- /**
- * Query tagged network usage statistics summaries.
- *
- * The results will only include tagged traffic made by UIDs belonging to the calling user
- * profile. The results are aggregated over time, so that all buckets will have the same
- * start and end timestamps as the passed arguments. Not aggregated over state, uid,
- * default network, metered, or roaming.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @param template Template used to match networks. See {@link NetworkTemplate}.
- * @param startTime Start of period, in milliseconds since the Unix epoch, see
- * {@link System#currentTimeMillis}.
- * @param endTime End of period, in milliseconds since the Unix epoch, see
- * {@link System#currentTimeMillis}.
- * @return Statistics which is described above.
- * @hide
- */
- @NonNull
- @SystemApi(client = MODULE_LIBRARIES)
- @WorkerThread
- public NetworkStats queryTaggedSummary(@NonNull NetworkTemplate template, long startTime,
- long endTime) throws SecurityException {
- Objects.requireNonNull(template);
- try {
- NetworkStats result =
- new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
- result.startTaggedSummaryEnumeration();
- return result;
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- return null; // To make the compiler happy.
- }
-
- /**
- * Query usage statistics details for networks matching a given {@link NetworkTemplate}.
- *
- * Result is not aggregated over time. This means buckets' start and
- * end timestamps will be between 'startTime' and 'endTime' parameters.
- * <p>Only includes buckets whose entire time period is included between
- * startTime and endTime. Doesn't interpolate or return partial buckets.
- * Since bucket length is in the order of hours, this
- * method cannot be used to measure data usage on a fine grained time scale.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @param template Template used to match networks. See {@link NetworkTemplate}.
- * @param startTime Start of period, in milliseconds since the Unix epoch, see
- * {@link java.lang.System#currentTimeMillis}.
- * @param endTime End of period, in milliseconds since the Unix epoch, see
- * {@link java.lang.System#currentTimeMillis}.
- * @return Statistics which is described above.
- * @hide
- */
- @NonNull
- @SystemApi(client = MODULE_LIBRARIES)
- @WorkerThread
- public NetworkStats queryDetailsForDevice(@NonNull NetworkTemplate template,
- long startTime, long endTime) {
- Objects.requireNonNull(template);
- try {
- final NetworkStats result =
- new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
- result.startHistoryDeviceEnumeration();
- return result;
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
-
- return null; // To make the compiler happy.
- }
-
- /**
- * Query network usage statistics details for a given uid.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @see #queryDetailsForUidTagState(int, String, long, long, int, int, int)
- */
- @NonNull
- @WorkerThread
- public NetworkStats queryDetailsForUid(int networkType, @Nullable String subscriberId,
- long startTime, long endTime, int uid) throws SecurityException {
- return queryDetailsForUidTagState(networkType, subscriberId, startTime, endTime, uid,
- NetworkStats.Bucket.TAG_NONE, NetworkStats.Bucket.STATE_ALL);
- }
-
- /** @hide */
- @NonNull
- public NetworkStats queryDetailsForUid(@NonNull NetworkTemplate template,
- long startTime, long endTime, int uid) throws SecurityException {
- return queryDetailsForUidTagState(template, startTime, endTime, uid,
- NetworkStats.Bucket.TAG_NONE, NetworkStats.Bucket.STATE_ALL);
- }
-
- /**
- * Query network usage statistics details for a given uid and tag.
- *
- * This may take a long time, and apps should avoid calling this on their main thread.
- * Only usable for uids belonging to calling user. Result is not aggregated over time.
- * This means buckets' start and end timestamps are going to be between 'startTime' and
- * 'endTime' parameters. The uid is going to be the same as the 'uid' parameter, the tag
- * the same as the 'tag' parameter, and the state the same as the 'state' parameter.
- * defaultNetwork is going to be {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
- * metered is going to be {@link NetworkStats.Bucket#METERED_ALL}, and
- * roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
- * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
- * interpolate across partial buckets. Since bucket length is in the order of hours, this
- * method cannot be used to measure data usage on a fine grained time scale.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @param networkType As defined in {@link ConnectivityManager}, e.g.
- * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
- * etc.
- * @param subscriberId If applicable, the subscriber id of the network interface.
- * <p>Starting with API level 29, the {@code subscriberId} is guarded by
- * additional restrictions. Calling apps that do not meet the new
- * requirements to access the {@code subscriberId} can provide a {@code
- * null} value when querying for the mobile network type to receive usage
- * for all mobile networks. For additional details see {@link
- * TelephonyManager#getSubscriberId()}.
- * <p>Starting with API level 31, calling apps can provide a
- * {@code subscriberId} with wifi network type to receive usage for
- * wifi networks which is under the given subscription if applicable.
- * Otherwise, pass {@code null} when querying all wifi networks.
- * @param startTime Start of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @param endTime End of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @param uid UID of app
- * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for aggregated data
- * across all the tags.
- * @return Statistics which is described above.
- * @throws SecurityException if permissions are insufficient to read network statistics.
- */
- @NonNull
- @WorkerThread
- public NetworkStats queryDetailsForUidTag(int networkType, @Nullable String subscriberId,
- long startTime, long endTime, int uid, int tag) throws SecurityException {
- return queryDetailsForUidTagState(networkType, subscriberId, startTime, endTime, uid,
- tag, NetworkStats.Bucket.STATE_ALL);
- }
-
- /**
- * Query network usage statistics details for a given uid, tag, and state.
- *
- * Only usable for uids belonging to calling user. Result is not aggregated over time.
- * This means buckets' start and end timestamps are going to be between 'startTime' and
- * 'endTime' parameters. The uid is going to be the same as the 'uid' parameter, the tag
- * the same as the 'tag' parameter, and the state the same as the 'state' parameter.
- * defaultNetwork is going to be {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
- * metered is going to be {@link NetworkStats.Bucket#METERED_ALL}, and
- * roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
- * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
- * interpolate across partial buckets. Since bucket length is in the order of hours, this
- * method cannot be used to measure data usage on a fine grained time scale.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @param networkType As defined in {@link ConnectivityManager}, e.g.
- * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
- * etc.
- * @param subscriberId If applicable, the subscriber id of the network interface.
- * <p>Starting with API level 29, the {@code subscriberId} is guarded by
- * additional restrictions. Calling apps that do not meet the new
- * requirements to access the {@code subscriberId} can provide a {@code
- * null} value when querying for the mobile network type to receive usage
- * for all mobile networks. For additional details see {@link
- * TelephonyManager#getSubscriberId()}.
- * <p>Starting with API level 31, calling apps can provide a
- * {@code subscriberId} with wifi network type to receive usage for
- * wifi networks which is under the given subscription if applicable.
- * Otherwise, pass {@code null} when querying all wifi networks.
- * @param startTime Start of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @param endTime End of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @param uid UID of app
- * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for aggregated data
- * across all the tags.
- * @param state state of interest. Use {@link NetworkStats.Bucket#STATE_ALL} to aggregate
- * traffic from all states.
- * @return Statistics which is described above.
- * @throws SecurityException if permissions are insufficient to read network statistics.
- */
- @NonNull
- @WorkerThread
- public NetworkStats queryDetailsForUidTagState(int networkType, @Nullable String subscriberId,
- long startTime, long endTime, int uid, int tag, int state) throws SecurityException {
- NetworkTemplate template;
- template = createTemplate(networkType, subscriberId);
-
- return queryDetailsForUidTagState(template, startTime, endTime, uid, tag, state);
- }
-
- /**
- * Query network usage statistics details for a given template, uid, tag, and state.
- *
- * Only usable for uids belonging to calling user. Result is not aggregated over time.
- * This means buckets' start and end timestamps are going to be between 'startTime' and
- * 'endTime' parameters. The uid is going to be the same as the 'uid' parameter, the tag
- * the same as the 'tag' parameter, and the state the same as the 'state' parameter.
- * defaultNetwork is going to be {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
- * metered is going to be {@link NetworkStats.Bucket#METERED_ALL}, and
- * roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
- * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
- * interpolate across partial buckets. Since bucket length is in the order of hours, this
- * method cannot be used to measure data usage on a fine grained time scale.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @param template Template used to match networks. See {@link NetworkTemplate}.
- * @param startTime Start of period, in milliseconds since the Unix epoch, see
- * {@link java.lang.System#currentTimeMillis}.
- * @param endTime End of period, in milliseconds since the Unix epoch, see
- * {@link java.lang.System#currentTimeMillis}.
- * @param uid UID of app
- * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for aggregated data
- * across all the tags.
- * @param state state of interest. Use {@link NetworkStats.Bucket#STATE_ALL} to aggregate
- * traffic from all states.
- * @return Statistics which is described above.
- * @hide
- */
- @NonNull
- @SystemApi(client = MODULE_LIBRARIES)
- @WorkerThread
- public NetworkStats queryDetailsForUidTagState(@NonNull NetworkTemplate template,
- long startTime, long endTime, int uid, int tag, int state) throws SecurityException {
- Objects.requireNonNull(template);
- try {
- final NetworkStats result = new NetworkStats(
- mContext, template, mFlags, startTime, endTime, mService);
- result.startHistoryUidEnumeration(uid, tag, state);
- return result;
- } catch (RemoteException e) {
- Log.e(TAG, "Error while querying stats for uid=" + uid + " tag=" + tag
- + " state=" + state, e);
- e.rethrowFromSystemServer();
- }
-
- return null; // To make the compiler happy.
- }
-
- /**
- * Query network usage statistics details. Result filtered to include only uids belonging to
- * calling user. Result is aggregated over state but not aggregated over time, uid, tag,
- * metered, nor roaming. This means buckets' start and end timestamps are going to be between
- * 'startTime' and 'endTime' parameters. State is going to be
- * {@link NetworkStats.Bucket#STATE_ALL}, uid will vary,
- * tag {@link NetworkStats.Bucket#TAG_NONE},
- * default network is going to be {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL},
- * metered is going to be {@link NetworkStats.Bucket#METERED_ALL},
- * and roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
- * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
- * interpolate across partial buckets. Since bucket length is in the order of hours, this
- * method cannot be used to measure data usage on a fine grained time scale.
- * This may take a long time, and apps should avoid calling this on their main thread.
- *
- * @param networkType As defined in {@link ConnectivityManager}, e.g.
- * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
- * etc.
- * @param subscriberId If applicable, the subscriber id of the network interface.
- * <p>Starting with API level 29, the {@code subscriberId} is guarded by
- * additional restrictions. Calling apps that do not meet the new
- * requirements to access the {@code subscriberId} can provide a {@code
- * null} value when querying for the mobile network type to receive usage
- * for all mobile networks. For additional details see {@link
- * TelephonyManager#getSubscriberId()}.
- * <p>Starting with API level 31, calling apps can provide a
- * {@code subscriberId} with wifi network type to receive usage for
- * wifi networks which is under the given subscription if applicable.
- * Otherwise, pass {@code null} when querying all wifi networks.
- * @param startTime Start of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @param endTime End of period. Defined in terms of "Unix time", see
- * {@link java.lang.System#currentTimeMillis}.
- * @return Statistics object or null if permissions are insufficient or error happened during
- * statistics collection.
- */
- @WorkerThread
- public NetworkStats queryDetails(int networkType, @Nullable String subscriberId, long startTime,
- long endTime) throws SecurityException, RemoteException {
- NetworkTemplate template;
- try {
- template = createTemplate(networkType, subscriberId);
- } catch (IllegalArgumentException e) {
- if (DBG) Log.e(TAG, "Cannot create template", e);
- return null;
- }
-
- NetworkStats result;
- result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService);
- result.startUserUidEnumeration();
- return result;
- }
-
- /**
- * Query realtime mobile network usage statistics.
- *
- * Return a snapshot of current UID network statistics, as it applies
- * to the mobile radios of the device. The snapshot will include any
- * tethering traffic, video calling data usage and count of
- * network operations set by {@link TrafficStats#incrementOperationCount}
- * made over a mobile radio.
- * The snapshot will not include any statistics that cannot be seen by
- * the kernel, e.g. statistics reported by {@link NetworkStatsProvider}s.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK})
- @NonNull public android.net.NetworkStats getMobileUidStats() {
- try {
- return mService.getUidStatsForTransport(TRANSPORT_CELLULAR);
- } catch (RemoteException e) {
- if (DBG) Log.d(TAG, "Remote exception when get Mobile uid stats");
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Query realtime Wi-Fi network usage statistics.
- *
- * Return a snapshot of current UID network statistics, as it applies
- * to the Wi-Fi radios of the device. The snapshot will include any
- * tethering traffic, video calling data usage and count of
- * network operations set by {@link TrafficStats#incrementOperationCount}
- * made over a Wi-Fi radio.
- * The snapshot will not include any statistics that cannot be seen by
- * the kernel, e.g. statistics reported by {@link NetworkStatsProvider}s.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK})
- @NonNull public android.net.NetworkStats getWifiUidStats() {
- try {
- return mService.getUidStatsForTransport(TRANSPORT_WIFI);
- } catch (RemoteException e) {
- if (DBG) Log.d(TAG, "Remote exception when get WiFi uid stats");
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Registers to receive notifications about data usage on specified networks.
- *
- * <p>The callbacks will continue to be called as long as the process is alive or
- * {@link #unregisterUsageCallback} is called.
- *
- * @param template Template used to match networks. See {@link NetworkTemplate}.
- * @param thresholdBytes Threshold in bytes to be notified on. Provided values lower than 2MiB
- * will be clamped for callers except callers with the NETWORK_STACK
- * permission.
- * @param executor The executor on which callback will be invoked. The provided {@link Executor}
- * must run callback sequentially, otherwise the order of callbacks cannot be
- * guaranteed.
- * @param callback The {@link UsageCallback} that the system will call when data usage
- * has exceeded the specified threshold.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK}, conditional = true)
- public void registerUsageCallback(@NonNull NetworkTemplate template, long thresholdBytes,
- @NonNull @CallbackExecutor Executor executor, @NonNull UsageCallback callback) {
- Objects.requireNonNull(template, "NetworkTemplate cannot be null");
- Objects.requireNonNull(callback, "UsageCallback cannot be null");
- Objects.requireNonNull(executor, "Executor cannot be null");
-
- final DataUsageRequest request = new DataUsageRequest(DataUsageRequest.REQUEST_ID_UNSET,
- template, thresholdBytes);
- try {
- final UsageCallbackWrapper callbackWrapper =
- new UsageCallbackWrapper(executor, callback);
- callback.request = mService.registerUsageCallback(
- mContext.getOpPackageName(), request, callbackWrapper);
- if (DBG) Log.d(TAG, "registerUsageCallback returned " + callback.request);
-
- if (callback.request == null) {
- Log.e(TAG, "Request from callback is null; should not happen");
- }
- } catch (RemoteException e) {
- if (DBG) Log.d(TAG, "Remote exception when registering callback");
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Registers to receive notifications about data usage on specified networks.
- *
- * <p>The callbacks will continue to be called as long as the process is live or
- * {@link #unregisterUsageCallback} is called.
- *
- * @param networkType Type of network to monitor. Either
- {@link ConnectivityManager#TYPE_MOBILE} or {@link ConnectivityManager#TYPE_WIFI}.
- * @param subscriberId If applicable, the subscriber id of the network interface.
- * <p>Starting with API level 29, the {@code subscriberId} is guarded by
- * additional restrictions. Calling apps that do not meet the new
- * requirements to access the {@code subscriberId} can provide a {@code
- * null} value when registering for the mobile network type to receive
- * notifications for all mobile networks. For additional details see {@link
- * TelephonyManager#getSubscriberId()}.
- * <p>Starting with API level 31, calling apps can provide a
- * {@code subscriberId} with wifi network type to receive usage for
- * wifi networks which is under the given subscription if applicable.
- * Otherwise, pass {@code null} when querying all wifi networks.
- * @param thresholdBytes Threshold in bytes to be notified on.
- * @param callback The {@link UsageCallback} that the system will call when data usage
- * has exceeded the specified threshold.
- */
- public void registerUsageCallback(int networkType, @Nullable String subscriberId,
- long thresholdBytes, @NonNull UsageCallback callback) {
- registerUsageCallback(networkType, subscriberId, thresholdBytes, callback,
- null /* handler */);
- }
-
- /**
- * Registers to receive notifications about data usage on specified networks.
- *
- * <p>The callbacks will continue to be called as long as the process is live or
- * {@link #unregisterUsageCallback} is called.
- *
- * @param networkType Type of network to monitor. Either
- {@link ConnectivityManager#TYPE_MOBILE} or {@link ConnectivityManager#TYPE_WIFI}.
- * @param subscriberId If applicable, the subscriber id of the network interface.
- * <p>Starting with API level 29, the {@code subscriberId} is guarded by
- * additional restrictions. Calling apps that do not meet the new
- * requirements to access the {@code subscriberId} can provide a {@code
- * null} value when registering for the mobile network type to receive
- * notifications for all mobile networks. For additional details see {@link
- * TelephonyManager#getSubscriberId()}.
- * <p>Starting with API level 31, calling apps can provide a
- * {@code subscriberId} with wifi network type to receive usage for
- * wifi networks which is under the given subscription if applicable.
- * Otherwise, pass {@code null} when querying all wifi networks.
- * @param thresholdBytes Threshold in bytes to be notified on.
- * @param callback The {@link UsageCallback} that the system will call when data usage
- * has exceeded the specified threshold.
- * @param handler to dispatch callback events through, otherwise if {@code null} it uses
- * the calling thread.
- */
- public void registerUsageCallback(int networkType, @Nullable String subscriberId,
- long thresholdBytes, @NonNull UsageCallback callback, @Nullable Handler handler) {
- NetworkTemplate template = createTemplate(networkType, subscriberId);
- if (DBG) {
- Log.d(TAG, "registerUsageCallback called with: {"
- + " networkType=" + networkType
- + " subscriberId=" + subscriberId
- + " thresholdBytes=" + thresholdBytes
- + " }");
- }
-
- final Executor executor = handler == null ? r -> r.run() : r -> handler.post(r);
-
- registerUsageCallback(template, thresholdBytes, executor, callback);
- }
-
- /**
- * Unregisters callbacks on data usage.
- *
- * @param callback The {@link UsageCallback} used when registering.
- */
- public void unregisterUsageCallback(@NonNull UsageCallback callback) {
- if (callback == null || callback.request == null
- || callback.request.requestId == DataUsageRequest.REQUEST_ID_UNSET) {
- throw new IllegalArgumentException("Invalid UsageCallback");
- }
- try {
- mService.unregisterUsageRequest(callback.request);
- } catch (RemoteException e) {
- if (DBG) Log.d(TAG, "Remote exception when unregistering callback");
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Base class for usage callbacks. Should be extended by applications wanting notifications.
- */
- public static abstract class UsageCallback {
- /**
- * Called when data usage has reached the given threshold.
- *
- * Called by {@code NetworkStatsService} when the registered threshold is reached.
- * If a caller implements {@link #onThresholdReached(NetworkTemplate)}, the system
- * will not call {@link #onThresholdReached(int, String)}.
- *
- * @param template The {@link NetworkTemplate} that associated with this callback.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public void onThresholdReached(@NonNull NetworkTemplate template) {
- // Backward compatibility for those who didn't override this function.
- final int networkType = networkTypeForTemplate(template);
- if (networkType != ConnectivityManager.TYPE_NONE) {
- final String subscriberId = template.getSubscriberIds().isEmpty() ? null
- : template.getSubscriberIds().iterator().next();
- onThresholdReached(networkType, subscriberId);
- }
- }
-
- /**
- * Called when data usage has reached the given threshold.
- */
- public abstract void onThresholdReached(int networkType, @Nullable String subscriberId);
-
- /**
- * @hide used for internal bookkeeping
- */
- private DataUsageRequest request;
-
- /**
- * Get network type from a template if feasible.
- *
- * @param template the target {@link NetworkTemplate}.
- * @return legacy network type, only supports for the types which is already supported in
- * {@link #registerUsageCallback(int, String, long, UsageCallback, Handler)}.
- * {@link ConnectivityManager#TYPE_NONE} for other types.
- */
- private static int networkTypeForTemplate(@NonNull NetworkTemplate template) {
- switch (template.getMatchRule()) {
- case NetworkTemplate.MATCH_MOBILE:
- return ConnectivityManager.TYPE_MOBILE;
- case NetworkTemplate.MATCH_WIFI:
- return ConnectivityManager.TYPE_WIFI;
- default:
- return ConnectivityManager.TYPE_NONE;
- }
- }
- }
-
- /**
- * Registers a custom provider of {@link android.net.NetworkStats} to provide network statistics
- * to the system. To unregister, invoke {@link #unregisterNetworkStatsProvider}.
- * Note that no de-duplication of statistics between providers is performed, so each provider
- * must only report network traffic that is not being reported by any other provider. Also note
- * that the provider cannot be re-registered after unregistering.
- *
- * @param tag a human readable identifier of the custom network stats provider. This is only
- * used for debugging.
- * @param provider the subclass of {@link NetworkStatsProvider} that needs to be
- * registered to the system.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_STATS_PROVIDER,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
- public void registerNetworkStatsProvider(
- @NonNull String tag,
- @NonNull NetworkStatsProvider provider) {
- try {
- if (provider.getProviderCallbackBinder() != null) {
- throw new IllegalArgumentException("provider is already registered");
- }
- final INetworkStatsProviderCallback cbBinder =
- mService.registerNetworkStatsProvider(tag, provider.getProviderBinder());
- provider.setProviderCallbackBinder(cbBinder);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Unregisters an instance of {@link NetworkStatsProvider}.
- *
- * @param provider the subclass of {@link NetworkStatsProvider} that needs to be
- * unregistered to the system.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_STATS_PROVIDER,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
- public void unregisterNetworkStatsProvider(@NonNull NetworkStatsProvider provider) {
- try {
- provider.getProviderCallbackBinderOrThrow().unregister();
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- private static NetworkTemplate createTemplate(int networkType, @Nullable String subscriberId) {
- final NetworkTemplate template;
- switch (networkType) {
- case ConnectivityManager.TYPE_MOBILE:
- template = subscriberId == null
- ? NetworkTemplate.buildTemplateMobileWildcard()
- : NetworkTemplate.buildTemplateMobileAll(subscriberId);
- break;
- case ConnectivityManager.TYPE_WIFI:
- template = TextUtils.isEmpty(subscriberId)
- ? NetworkTemplate.buildTemplateWifiWildcard()
- : NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- subscriberId);
- break;
- default:
- throw new IllegalArgumentException("Cannot create template for network type "
- + networkType + ", subscriberId '"
- + NetworkIdentityUtils.scrubSubscriberId(subscriberId) + "'.");
- }
- return template;
- }
-
- /**
- * Notify {@code NetworkStatsService} about network status changed.
- *
- * Notifies NetworkStatsService of network state changes for data usage accounting purposes.
- *
- * To avoid races that attribute data usage to wrong network, such as new network with
- * the same interface after SIM hot-swap, this function will not return until
- * {@code NetworkStatsService} finishes its work of retrieving traffic statistics from
- * all data sources.
- *
- * @param defaultNetworks the list of all networks that could be used by network traffic that
- * does not explicitly select a network.
- * @param networkStateSnapshots a list of {@link NetworkStateSnapshot}s, one for
- * each network that is currently connected.
- * @param activeIface the active (i.e., connected) default network interface for the calling
- * uid. Used to determine on which network future calls to
- * {@link android.net.TrafficStats#incrementOperationCount} applies to.
- * @param underlyingNetworkInfos the list of underlying network information for all
- * currently-connected VPNs.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK})
- public void notifyNetworkStatus(
- @NonNull List<Network> defaultNetworks,
- @NonNull List<NetworkStateSnapshot> networkStateSnapshots,
- @Nullable String activeIface,
- @NonNull List<UnderlyingNetworkInfo> underlyingNetworkInfos) {
- try {
- Objects.requireNonNull(defaultNetworks);
- Objects.requireNonNull(networkStateSnapshots);
- Objects.requireNonNull(underlyingNetworkInfos);
- mService.notifyNetworkStatus(defaultNetworks.toArray(new Network[0]),
- networkStateSnapshots.toArray(new NetworkStateSnapshot[0]), activeIface,
- underlyingNetworkInfos.toArray(new UnderlyingNetworkInfo[0]));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- private static class UsageCallbackWrapper extends IUsageCallback.Stub {
- // Null if unregistered.
- private volatile UsageCallback mCallback;
-
- private final Executor mExecutor;
-
- UsageCallbackWrapper(@NonNull Executor executor, @NonNull UsageCallback callback) {
- mCallback = callback;
- mExecutor = executor;
- }
-
- @Override
- public void onThresholdReached(DataUsageRequest request) {
- // Copy it to a local variable in case mCallback changed inside the if condition.
- final UsageCallback callback = mCallback;
- if (callback != null) {
- mExecutor.execute(() -> callback.onThresholdReached(request.template));
- } else {
- Log.e(TAG, "onThresholdReached with released callback for " + request);
- }
- }
-
- @Override
- public void onCallbackReleased(DataUsageRequest request) {
- if (DBG) Log.d(TAG, "callback released for " + request);
- mCallback = null;
- }
- }
-
- /**
- * Mark given UID as being in foreground for stats purposes.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK})
- public void noteUidForeground(int uid, boolean uidForeground) {
- try {
- mService.noteUidForeground(uid, uidForeground);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Set default value of global alert bytes, the value will be clamped to [128kB, 2MB].
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- Manifest.permission.NETWORK_STACK})
- public void setDefaultGlobalAlert(long alertBytes) {
- try {
- // TODO: Sync internal naming with the API surface.
- mService.advisePersistThreshold(alertBytes);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Force update of statistics.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK})
- public void forceUpdate() {
- try {
- mService.forceUpdate();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Set the warning and limit to all registered custom network stats providers.
- * Note that invocation of any interface will be sent to all providers.
- *
- * Asynchronicity notes : because traffic may be happening on the device at the same time, it
- * doesn't make sense to wait for the warning and limit to be set – a caller still wouldn't
- * know when exactly it was effective. All that can matter is that it's done quickly. Also,
- * this method can't fail, so there is no status to return. All providers will see the new
- * values soon.
- * As such, this method returns immediately and sends the warning and limit to all providers
- * as soon as possible through a one-way binder call.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK})
- public void setStatsProviderWarningAndLimitAsync(@NonNull String iface, long warning,
- long limit) {
- try {
- mService.setStatsProviderWarningAndLimitAsync(iface, warning, limit);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Get a RAT type representative of a group of RAT types for network statistics.
- *
- * Collapse the given Radio Access Technology (RAT) type into a bucket that
- * is representative of the original RAT type for network statistics. The
- * mapping mostly corresponds to {@code TelephonyManager#NETWORK_CLASS_BIT_MASK_*}
- * but with adaptations specific to the virtual types introduced by
- * networks stats.
- *
- * @param ratType An integer defined in {@code TelephonyManager#NETWORK_TYPE_*}.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static int getCollapsedRatType(int ratType) {
- switch (ratType) {
- case TelephonyManager.NETWORK_TYPE_GPRS:
- case TelephonyManager.NETWORK_TYPE_GSM:
- case TelephonyManager.NETWORK_TYPE_EDGE:
- case TelephonyManager.NETWORK_TYPE_IDEN:
- case TelephonyManager.NETWORK_TYPE_CDMA:
- case TelephonyManager.NETWORK_TYPE_1xRTT:
- return TelephonyManager.NETWORK_TYPE_GSM;
- case TelephonyManager.NETWORK_TYPE_EVDO_0:
- case TelephonyManager.NETWORK_TYPE_EVDO_A:
- case TelephonyManager.NETWORK_TYPE_EVDO_B:
- case TelephonyManager.NETWORK_TYPE_EHRPD:
- case TelephonyManager.NETWORK_TYPE_UMTS:
- case TelephonyManager.NETWORK_TYPE_HSDPA:
- case TelephonyManager.NETWORK_TYPE_HSUPA:
- case TelephonyManager.NETWORK_TYPE_HSPA:
- case TelephonyManager.NETWORK_TYPE_HSPAP:
- case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
- return TelephonyManager.NETWORK_TYPE_UMTS;
- case TelephonyManager.NETWORK_TYPE_LTE:
- case TelephonyManager.NETWORK_TYPE_IWLAN:
- return TelephonyManager.NETWORK_TYPE_LTE;
- case TelephonyManager.NETWORK_TYPE_NR:
- return TelephonyManager.NETWORK_TYPE_NR;
- // Virtual RAT type for 5G NSA mode, see
- // {@link NetworkStatsManager#NETWORK_TYPE_5G_NSA}.
- case NetworkStatsManager.NETWORK_TYPE_5G_NSA:
- return NetworkStatsManager.NETWORK_TYPE_5G_NSA;
- default:
- return TelephonyManager.NETWORK_TYPE_UNKNOWN;
- }
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java b/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
deleted file mode 100644
index 61b34d0..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.annotation.SystemApi;
-import android.app.SystemServiceRegistry;
-import android.app.usage.NetworkStatsManager;
-import android.content.Context;
-import android.net.nsd.INsdManager;
-import android.net.nsd.NsdManager;
-
-/**
- * Class for performing registration for Connectivity services which are exposed via updatable APIs
- * since Android T.
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class ConnectivityFrameworkInitializerTiramisu {
- private ConnectivityFrameworkInitializerTiramisu() {}
-
- /**
- * Called by {@link SystemServiceRegistry}'s static initializer and registers NetworkStats, nsd,
- * ipsec and ethernet services to {@link Context}, so that {@link Context#getSystemService} can
- * return them.
- *
- * @throws IllegalStateException if this is called anywhere besides
- * {@link SystemServiceRegistry}.
- */
- public static void registerServiceWrappers() {
- SystemServiceRegistry.registerContextAwareService(
- Context.NSD_SERVICE,
- NsdManager.class,
- (context, serviceBinder) -> {
- INsdManager service = INsdManager.Stub.asInterface(serviceBinder);
- return new NsdManager(context, service);
- }
- );
-
- SystemServiceRegistry.registerContextAwareService(
- Context.IPSEC_SERVICE,
- IpSecManager.class,
- (context, serviceBinder) -> {
- IIpSecService service = IIpSecService.Stub.asInterface(serviceBinder);
- return new IpSecManager(context, service);
- }
- );
-
- SystemServiceRegistry.registerContextAwareService(
- Context.NETWORK_STATS_SERVICE,
- NetworkStatsManager.class,
- (context, serviceBinder) -> {
- INetworkStatsService service =
- INetworkStatsService.Stub.asInterface(serviceBinder);
- return new NetworkStatsManager(context, service);
- }
- );
-
- SystemServiceRegistry.registerContextAwareService(
- Context.ETHERNET_SERVICE,
- EthernetManager.class,
- (context, serviceBinder) -> {
- IEthernetManager service = IEthernetManager.Stub.asInterface(serviceBinder);
- return new EthernetManager(context, service);
- }
- );
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/DataUsageRequest.aidl b/packages/ConnectivityT/framework-t/src/android/net/DataUsageRequest.aidl
deleted file mode 100644
index d1937c7..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/DataUsageRequest.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-parcelable DataUsageRequest;
diff --git a/packages/ConnectivityT/framework-t/src/android/net/DataUsageRequest.java b/packages/ConnectivityT/framework-t/src/android/net/DataUsageRequest.java
deleted file mode 100644
index f0ff465..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/DataUsageRequest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy
- * of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-
-package android.net;
-
-import android.annotation.Nullable;
-import android.net.NetworkTemplate;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * Defines a request to register a callbacks. Used to be notified on data usage via
- * {@link android.app.usage.NetworkStatsManager#registerDataUsageCallback}.
- * If no {@code uid}s are set, callbacks are restricted to device-owners,
- * carrier-privileged apps, or system apps.
- *
- * @hide
- */
-public final class DataUsageRequest implements Parcelable {
-
- public static final String PARCELABLE_KEY = "DataUsageRequest";
- public static final int REQUEST_ID_UNSET = 0;
-
- /**
- * Identifies the request. {@link DataUsageRequest}s should only be constructed by
- * the Framework and it is used internally to identify the request.
- */
- public final int requestId;
-
- /**
- * {@link NetworkTemplate} describing the network to monitor.
- */
- public final NetworkTemplate template;
-
- /**
- * Threshold in bytes to be notified on.
- */
- public final long thresholdInBytes;
-
- public DataUsageRequest(int requestId, NetworkTemplate template, long thresholdInBytes) {
- this.requestId = requestId;
- this.template = template;
- this.thresholdInBytes = thresholdInBytes;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(requestId);
- dest.writeParcelable(template, flags);
- dest.writeLong(thresholdInBytes);
- }
-
- public static final @android.annotation.NonNull Creator<DataUsageRequest> CREATOR =
- new Creator<DataUsageRequest>() {
- @Override
- public DataUsageRequest createFromParcel(Parcel in) {
- int requestId = in.readInt();
- NetworkTemplate template = in.readParcelable(null, android.net.NetworkTemplate.class);
- long thresholdInBytes = in.readLong();
- DataUsageRequest result = new DataUsageRequest(requestId, template,
- thresholdInBytes);
- return result;
- }
-
- @Override
- public DataUsageRequest[] newArray(int size) {
- return new DataUsageRequest[size];
- }
- };
-
- @Override
- public String toString() {
- return "DataUsageRequest [ requestId=" + requestId
- + ", networkTemplate=" + template
- + ", thresholdInBytes=" + thresholdInBytes + " ]";
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (obj instanceof DataUsageRequest == false) return false;
- DataUsageRequest that = (DataUsageRequest) obj;
- return that.requestId == this.requestId
- && Objects.equals(that.template, this.template)
- && that.thresholdInBytes == this.thresholdInBytes;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(requestId, template, thresholdInBytes);
- }
-
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java
deleted file mode 100644
index e02ea89..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * Copyright (C) 2014 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.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresFeature;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.OutcomeReceiver;
-import android.os.RemoteException;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.modules.utils.BackgroundThread;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.function.IntConsumer;
-
-/**
- * A class that manages and configures Ethernet interfaces.
- *
- * @hide
- */
-@SystemApi
-@SystemService(Context.ETHERNET_SERVICE)
-public class EthernetManager {
- private static final String TAG = "EthernetManager";
-
- private final IEthernetManager mService;
- @GuardedBy("mListenerLock")
- private final ArrayList<ListenerInfo<InterfaceStateListener>> mIfaceListeners =
- new ArrayList<>();
- @GuardedBy("mListenerLock")
- private final ArrayList<ListenerInfo<IntConsumer>> mEthernetStateListeners =
- new ArrayList<>();
- final Object mListenerLock = new Object();
- private final IEthernetServiceListener.Stub mServiceListener =
- new IEthernetServiceListener.Stub() {
- @Override
- public void onEthernetStateChanged(int state) {
- synchronized (mListenerLock) {
- for (ListenerInfo<IntConsumer> li : mEthernetStateListeners) {
- li.executor.execute(() -> {
- li.listener.accept(state);
- });
- }
- }
- }
-
- @Override
- public void onInterfaceStateChanged(String iface, int state, int role,
- IpConfiguration configuration) {
- synchronized (mListenerLock) {
- for (ListenerInfo<InterfaceStateListener> li : mIfaceListeners) {
- li.executor.execute(() ->
- li.listener.onInterfaceStateChanged(iface, state, role,
- configuration));
- }
- }
- }
- };
-
- /**
- * Indicates that Ethernet is disabled.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int ETHERNET_STATE_DISABLED = 0;
-
- /**
- * Indicates that Ethernet is enabled.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int ETHERNET_STATE_ENABLED = 1;
-
- private static class ListenerInfo<T> {
- @NonNull
- public final Executor executor;
- @NonNull
- public final T listener;
-
- private ListenerInfo(@NonNull Executor executor, @NonNull T listener) {
- this.executor = executor;
- this.listener = listener;
- }
- }
-
- /**
- * The interface is absent.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int STATE_ABSENT = 0;
-
- /**
- * The interface is present but link is down.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int STATE_LINK_DOWN = 1;
-
- /**
- * The interface is present and link is up.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int STATE_LINK_UP = 2;
-
- /** @hide */
- @IntDef(prefix = "STATE_", value = {STATE_ABSENT, STATE_LINK_DOWN, STATE_LINK_UP})
- @Retention(RetentionPolicy.SOURCE)
- public @interface InterfaceState {}
-
- /**
- * The interface currently does not have any specific role.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int ROLE_NONE = 0;
-
- /**
- * The interface is in client mode (e.g., connected to the Internet).
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int ROLE_CLIENT = 1;
-
- /**
- * Ethernet interface is in server mode (e.g., providing Internet access to tethered devices).
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int ROLE_SERVER = 2;
-
- /** @hide */
- @IntDef(prefix = "ROLE_", value = {ROLE_NONE, ROLE_CLIENT, ROLE_SERVER})
- @Retention(RetentionPolicy.SOURCE)
- public @interface Role {}
-
- /**
- * A listener that receives notifications about the state of Ethernet interfaces on the system.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public interface InterfaceStateListener {
- /**
- * Called when an Ethernet interface changes state.
- *
- * @param iface the name of the interface.
- * @param state the current state of the interface, or {@link #STATE_ABSENT} if the
- * interface was removed.
- * @param role whether the interface is in client mode or server mode.
- * @param configuration the current IP configuration of the interface.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- void onInterfaceStateChanged(@NonNull String iface, @InterfaceState int state,
- @Role int role, @Nullable IpConfiguration configuration);
- }
-
- /**
- * A listener interface to receive notification on changes in Ethernet.
- * This has never been a supported API. Use {@link InterfaceStateListener} instead.
- * @hide
- */
- public interface Listener extends InterfaceStateListener {
- /**
- * Called when Ethernet port's availability is changed.
- * @param iface Ethernet interface name
- * @param isAvailable {@code true} if Ethernet port exists.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- void onAvailabilityChanged(String iface, boolean isAvailable);
-
- /** Default implementation for backwards compatibility. Only calls the legacy listener. */
- default void onInterfaceStateChanged(@NonNull String iface, @InterfaceState int state,
- @Role int role, @Nullable IpConfiguration configuration) {
- onAvailabilityChanged(iface, (state >= STATE_LINK_UP));
- }
-
- }
-
- /**
- * Create a new EthernetManager instance.
- * Applications will almost always want to use
- * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
- * the standard {@link android.content.Context#ETHERNET_SERVICE Context.ETHERNET_SERVICE}.
- * @hide
- */
- public EthernetManager(Context context, IEthernetManager service) {
- mService = service;
- }
-
- /**
- * Get Ethernet configuration.
- * @return the Ethernet Configuration, contained in {@link IpConfiguration}.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public IpConfiguration getConfiguration(String iface) {
- try {
- return mService.getConfiguration(iface);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Set Ethernet configuration.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) {
- try {
- mService.setConfiguration(iface, config);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Indicates whether the system currently has one or more Ethernet interfaces.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public boolean isAvailable() {
- return getAvailableInterfaces().length > 0;
- }
-
- /**
- * Indicates whether the system has given interface.
- *
- * @param iface Ethernet interface name
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public boolean isAvailable(String iface) {
- try {
- return mService.isAvailable(iface);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Adds a listener.
- * This has never been a supported API. Use {@link #addInterfaceStateListener} instead.
- *
- * @param listener A {@link Listener} to add.
- * @throws IllegalArgumentException If the listener is null.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public void addListener(@NonNull Listener listener) {
- addListener(listener, BackgroundThread.getExecutor());
- }
-
- /**
- * Adds a listener.
- * This has never been a supported API. Use {@link #addInterfaceStateListener} instead.
- *
- * @param listener A {@link Listener} to add.
- * @param executor Executor to run callbacks on.
- * @throws IllegalArgumentException If the listener or executor is null.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public void addListener(@NonNull Listener listener, @NonNull Executor executor) {
- addInterfaceStateListener(executor, listener);
- }
-
- /**
- * Listen to changes in the state of Ethernet interfaces.
- *
- * Adds a listener to receive notification for any state change of all existing Ethernet
- * interfaces.
- * <p>{@link Listener#onInterfaceStateChanged} will be triggered immediately for all
- * existing interfaces upon adding a listener. The same method will be called on the
- * listener every time any of the interface changes state. In particular, if an
- * interface is removed, it will be called with state {@link #STATE_ABSENT}.
- * <p>Use {@link #removeInterfaceStateListener} with the same object to stop listening.
- *
- * @param executor Executor to run callbacks on.
- * @param listener A {@link Listener} to add.
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @SystemApi(client = MODULE_LIBRARIES)
- public void addInterfaceStateListener(@NonNull Executor executor,
- @NonNull InterfaceStateListener listener) {
- if (listener == null || executor == null) {
- throw new NullPointerException("listener and executor must not be null");
- }
- synchronized (mListenerLock) {
- maybeAddServiceListener();
- mIfaceListeners.add(new ListenerInfo<InterfaceStateListener>(executor, listener));
- }
- }
-
- @GuardedBy("mListenerLock")
- private void maybeAddServiceListener() {
- if (!mIfaceListeners.isEmpty() || !mEthernetStateListeners.isEmpty()) return;
-
- try {
- mService.addListener(mServiceListener);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
- }
-
- /**
- * Returns an array of available Ethernet interface names.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public String[] getAvailableInterfaces() {
- try {
- return mService.getAvailableInterfaces();
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Removes a listener.
- *
- * @param listener A {@link Listener} to remove.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) {
- Objects.requireNonNull(listener);
- synchronized (mListenerLock) {
- mIfaceListeners.removeIf(l -> l.listener == listener);
- maybeRemoveServiceListener();
- }
- }
-
- @GuardedBy("mListenerLock")
- private void maybeRemoveServiceListener() {
- if (!mIfaceListeners.isEmpty() || !mEthernetStateListeners.isEmpty()) return;
-
- try {
- mService.removeListener(mServiceListener);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Removes a listener.
- * This has never been a supported API. Use {@link #removeInterfaceStateListener} instead.
- * @param listener A {@link Listener} to remove.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public void removeListener(@NonNull Listener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("listener must not be null");
- }
- removeInterfaceStateListener(listener);
- }
-
- /**
- * Whether to treat interfaces created by {@link TestNetworkManager#createTapInterface}
- * as Ethernet interfaces. The effects of this method apply to any test interfaces that are
- * already present on the system.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public void setIncludeTestInterfaces(boolean include) {
- try {
- mService.setIncludeTestInterfaces(include);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * A request for a tethered interface.
- */
- public static class TetheredInterfaceRequest {
- private final IEthernetManager mService;
- private final ITetheredInterfaceCallback mCb;
-
- private TetheredInterfaceRequest(@NonNull IEthernetManager service,
- @NonNull ITetheredInterfaceCallback cb) {
- this.mService = service;
- this.mCb = cb;
- }
-
- /**
- * Release the request, causing the interface to revert back from tethering mode if there
- * is no other requestor.
- */
- public void release() {
- try {
- mService.releaseTetheredInterface(mCb);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- }
- }
-
- /**
- * Callback for {@link #requestTetheredInterface(TetheredInterfaceCallback)}.
- */
- public interface TetheredInterfaceCallback {
- /**
- * Called when the tethered interface is available.
- * @param iface The name of the interface.
- */
- void onAvailable(@NonNull String iface);
-
- /**
- * Called when the tethered interface is now unavailable.
- */
- void onUnavailable();
- }
-
- /**
- * Request a tethered interface in tethering mode.
- *
- * <p>When this method is called and there is at least one ethernet interface available, the
- * system will designate one to act as a tethered interface. If there is already a tethered
- * interface, the existing interface will be used.
- * @param callback A callback to be called once the request has been fulfilled.
- */
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_STACK,
- android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
- })
- @NonNull
- public TetheredInterfaceRequest requestTetheredInterface(@NonNull final Executor executor,
- @NonNull final TetheredInterfaceCallback callback) {
- Objects.requireNonNull(callback, "Callback must be non-null");
- Objects.requireNonNull(executor, "Executor must be non-null");
- final ITetheredInterfaceCallback cbInternal = new ITetheredInterfaceCallback.Stub() {
- @Override
- public void onAvailable(String iface) {
- executor.execute(() -> callback.onAvailable(iface));
- }
-
- @Override
- public void onUnavailable() {
- executor.execute(() -> callback.onUnavailable());
- }
- };
-
- try {
- mService.requestTetheredInterface(cbInternal);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- return new TetheredInterfaceRequest(mService, cbInternal);
- }
-
- private static final class NetworkInterfaceOutcomeReceiver
- extends INetworkInterfaceOutcomeReceiver.Stub {
- @NonNull
- private final Executor mExecutor;
- @NonNull
- private final OutcomeReceiver<String, EthernetNetworkManagementException> mCallback;
-
- NetworkInterfaceOutcomeReceiver(
- @NonNull final Executor executor,
- @NonNull final OutcomeReceiver<String, EthernetNetworkManagementException>
- callback) {
- Objects.requireNonNull(executor, "Pass a non-null executor");
- Objects.requireNonNull(callback, "Pass a non-null callback");
- mExecutor = executor;
- mCallback = callback;
- }
-
- @Override
- public void onResult(@NonNull String iface) {
- mExecutor.execute(() -> mCallback.onResult(iface));
- }
-
- @Override
- public void onError(@NonNull EthernetNetworkManagementException e) {
- mExecutor.execute(() -> mCallback.onError(e));
- }
- }
-
- private NetworkInterfaceOutcomeReceiver makeNetworkInterfaceOutcomeReceiver(
- @Nullable final Executor executor,
- @Nullable final OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
- if (null != callback) {
- Objects.requireNonNull(executor, "Pass a non-null executor, or a null callback");
- }
- final NetworkInterfaceOutcomeReceiver proxy;
- if (null == callback) {
- proxy = null;
- } else {
- proxy = new NetworkInterfaceOutcomeReceiver(executor, callback);
- }
- return proxy;
- }
-
- /**
- * Updates the configuration of an automotive device's ethernet network.
- *
- * The {@link EthernetNetworkUpdateRequest} {@code request} argument describes how to update the
- * configuration for this network.
- * Use {@link StaticIpConfiguration.Builder} to build a {@code StaticIpConfiguration} object for
- * this network to put inside the {@code request}.
- * Similarly, use {@link NetworkCapabilities.Builder} to build a {@code NetworkCapabilities}
- * object for this network to put inside the {@code request}.
- *
- * This function accepts an {@link OutcomeReceiver} that is called once the operation has
- * finished execution.
- *
- * @param iface the name of the interface to act upon.
- * @param request the {@link EthernetNetworkUpdateRequest} used to set an ethernet network's
- * {@link StaticIpConfiguration} and {@link NetworkCapabilities} values.
- * @param executor an {@link Executor} to execute the callback on. Optional if callback is null.
- * @param callback an optional {@link OutcomeReceiver} to listen for completion of the
- * operation. On success, {@link OutcomeReceiver#onResult} is called with the
- * interface name. On error, {@link OutcomeReceiver#onError} is called with more
- * information about the error.
- * @throws SecurityException if the process doesn't hold
- * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
- * @throws UnsupportedOperationException if called on a non-automotive device or on an
- * unsupported interface.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK,
- android.Manifest.permission.MANAGE_ETHERNET_NETWORKS})
- public void updateConfiguration(
- @NonNull String iface,
- @NonNull EthernetNetworkUpdateRequest request,
- @Nullable @CallbackExecutor Executor executor,
- @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
- Objects.requireNonNull(iface, "iface must be non-null");
- Objects.requireNonNull(request, "request must be non-null");
- final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
- executor, callback);
- try {
- mService.updateConfiguration(iface, request, proxy);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Enable a network interface.
- *
- * Enables a previously disabled network interface.
- * This function accepts an {@link OutcomeReceiver} that is called once the operation has
- * finished execution.
- *
- * @param iface the name of the interface to enable.
- * @param executor an {@link Executor} to execute the callback on. Optional if callback is null.
- * @param callback an optional {@link OutcomeReceiver} to listen for completion of the
- * operation. On success, {@link OutcomeReceiver#onResult} is called with the
- * interface name. On error, {@link OutcomeReceiver#onError} is called with more
- * information about the error.
- * @throws SecurityException if the process doesn't hold
- * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK,
- android.Manifest.permission.MANAGE_ETHERNET_NETWORKS})
- @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
- public void enableInterface(
- @NonNull String iface,
- @Nullable @CallbackExecutor Executor executor,
- @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
- Objects.requireNonNull(iface, "iface must be non-null");
- final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
- executor, callback);
- try {
- mService.connectNetwork(iface, proxy);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Disable a network interface.
- *
- * Disables the use of a network interface to fulfill network requests. If the interface
- * currently serves a request, the network will be torn down.
- * This function accepts an {@link OutcomeReceiver} that is called once the operation has
- * finished execution.
- *
- * @param iface the name of the interface to disable.
- * @param executor an {@link Executor} to execute the callback on. Optional if callback is null.
- * @param callback an optional {@link OutcomeReceiver} to listen for completion of the
- * operation. On success, {@link OutcomeReceiver#onResult} is called with the
- * interface name. On error, {@link OutcomeReceiver#onError} is called with more
- * information about the error.
- * @throws SecurityException if the process doesn't hold
- * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
- * @hide
- */
- @SystemApi
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK,
- android.Manifest.permission.MANAGE_ETHERNET_NETWORKS})
- @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
- public void disableInterface(
- @NonNull String iface,
- @Nullable @CallbackExecutor Executor executor,
- @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
- Objects.requireNonNull(iface, "iface must be non-null");
- final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
- executor, callback);
- try {
- mService.disconnectNetwork(iface, proxy);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Change ethernet setting.
- *
- * @param enabled enable or disable ethernet settings.
- *
- * @hide
- */
- @RequiresPermission(anyOf = {
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK,
- android.Manifest.permission.NETWORK_SETTINGS})
- @SystemApi(client = MODULE_LIBRARIES)
- public void setEthernetEnabled(boolean enabled) {
- try {
- mService.setEthernetEnabled(enabled);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Listen to changes in the state of ethernet.
- *
- * @param executor to run callbacks on.
- * @param listener to listen ethernet state changed.
- *
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @SystemApi(client = MODULE_LIBRARIES)
- public void addEthernetStateListener(@NonNull Executor executor,
- @NonNull IntConsumer listener) {
- Objects.requireNonNull(executor);
- Objects.requireNonNull(listener);
- synchronized (mListenerLock) {
- maybeAddServiceListener();
- mEthernetStateListeners.add(new ListenerInfo<IntConsumer>(executor, listener));
- }
- }
-
- /**
- * Removes a listener.
- *
- * @param listener to listen ethernet state changed.
- *
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @SystemApi(client = MODULE_LIBRARIES)
- public void removeEthernetStateListener(@NonNull IntConsumer listener) {
- Objects.requireNonNull(listener);
- synchronized (mListenerLock) {
- mEthernetStateListeners.removeIf(l -> l.listener == listener);
- maybeRemoveServiceListener();
- }
- }
-
- /**
- * Returns an array of existing Ethernet interface names regardless whether the interface
- * is available or not currently.
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @SystemApi(client = MODULE_LIBRARIES)
- @NonNull
- public List<String> getInterfaceList() {
- try {
- return mService.getInterfaceList();
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- }
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkManagementException.aidl b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkManagementException.aidl
deleted file mode 100644
index adf9e5a..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkManagementException.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- package android.net;
-
- parcelable EthernetNetworkManagementException;
\ No newline at end of file
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkManagementException.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkManagementException.java
deleted file mode 100644
index a69cc55..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkManagementException.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/** @hide */
-@SystemApi
-public final class EthernetNetworkManagementException
- extends RuntimeException implements Parcelable {
-
- /* @hide */
- public EthernetNetworkManagementException(@NonNull final String errorMessage) {
- super(errorMessage);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(getMessage());
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null || getClass() != obj.getClass()) return false;
- final EthernetNetworkManagementException that = (EthernetNetworkManagementException) obj;
-
- return Objects.equals(getMessage(), that.getMessage());
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString(getMessage());
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull
- public static final Parcelable.Creator<EthernetNetworkManagementException> CREATOR =
- new Parcelable.Creator<EthernetNetworkManagementException>() {
- @Override
- public EthernetNetworkManagementException[] newArray(int size) {
- return new EthernetNetworkManagementException[size];
- }
-
- @Override
- public EthernetNetworkManagementException createFromParcel(@NonNull Parcel source) {
- return new EthernetNetworkManagementException(source.readString());
- }
- };
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkSpecifier.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkSpecifier.java
deleted file mode 100644
index e4d6e24..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkSpecifier.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.util.Objects;
-
-/**
- * A {@link NetworkSpecifier} used to identify ethernet interfaces.
- *
- * @see EthernetManager
- */
-public final class EthernetNetworkSpecifier extends NetworkSpecifier implements Parcelable {
-
- /**
- * Name of the network interface.
- */
- @NonNull
- private final String mInterfaceName;
-
- /**
- * Create a new EthernetNetworkSpecifier.
- * @param interfaceName Name of the ethernet interface the specifier refers to.
- */
- public EthernetNetworkSpecifier(@NonNull String interfaceName) {
- if (TextUtils.isEmpty(interfaceName)) {
- throw new IllegalArgumentException();
- }
- mInterfaceName = interfaceName;
- }
-
- /**
- * Get the name of the ethernet interface the specifier refers to.
- */
- @Nullable
- public String getInterfaceName() {
- // This may be null in the future to support specifiers based on data other than the
- // interface name.
- return mInterfaceName;
- }
-
- /** @hide */
- @Override
- public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) {
- return equals(other);
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (!(o instanceof EthernetNetworkSpecifier)) return false;
- return TextUtils.equals(mInterfaceName, ((EthernetNetworkSpecifier) o).mInterfaceName);
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(mInterfaceName);
- }
-
- @Override
- public String toString() {
- return "EthernetNetworkSpecifier (" + mInterfaceName + ")";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString(mInterfaceName);
- }
-
- public static final @NonNull Parcelable.Creator<EthernetNetworkSpecifier> CREATOR =
- new Parcelable.Creator<EthernetNetworkSpecifier>() {
- public EthernetNetworkSpecifier createFromParcel(Parcel in) {
- return new EthernetNetworkSpecifier(in.readString());
- }
- public EthernetNetworkSpecifier[] newArray(int size) {
- return new EthernetNetworkSpecifier[size];
- }
- };
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.aidl b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.aidl
deleted file mode 100644
index debc348..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- package android.net;
-
- parcelable EthernetNetworkUpdateRequest;
\ No newline at end of file
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
deleted file mode 100644
index 1691942..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * Represents a request to update an existing Ethernet interface.
- *
- * @see EthernetManager#updateConfiguration
- *
- * @hide
- */
-@SystemApi
-public final class EthernetNetworkUpdateRequest implements Parcelable {
- @Nullable
- private final IpConfiguration mIpConfig;
- @Nullable
- private final NetworkCapabilities mNetworkCapabilities;
-
- /**
- * Setting the {@link IpConfiguration} is optional in {@link EthernetNetworkUpdateRequest}.
- * When set to null, the existing IpConfiguration is not updated.
- *
- * @return the new {@link IpConfiguration} or null.
- */
- @Nullable
- public IpConfiguration getIpConfiguration() {
- return mIpConfig == null ? null : new IpConfiguration(mIpConfig);
- }
-
- /**
- * Setting the {@link NetworkCapabilities} is optional in {@link EthernetNetworkUpdateRequest}.
- * When set to null, the existing NetworkCapabilities are not updated.
- *
- * @return the new {@link NetworkCapabilities} or null.
- */
- @Nullable
- public NetworkCapabilities getNetworkCapabilities() {
- return mNetworkCapabilities == null ? null : new NetworkCapabilities(mNetworkCapabilities);
- }
-
- private EthernetNetworkUpdateRequest(@Nullable final IpConfiguration ipConfig,
- @Nullable final NetworkCapabilities networkCapabilities) {
- mIpConfig = ipConfig;
- mNetworkCapabilities = networkCapabilities;
- }
-
- private EthernetNetworkUpdateRequest(@NonNull final Parcel source) {
- Objects.requireNonNull(source);
- mIpConfig = source.readParcelable(IpConfiguration.class.getClassLoader(),
- IpConfiguration.class);
- mNetworkCapabilities = source.readParcelable(NetworkCapabilities.class.getClassLoader(),
- NetworkCapabilities.class);
- }
-
- /**
- * Builder used to create {@link EthernetNetworkUpdateRequest} objects.
- */
- public static final class Builder {
- @Nullable
- private IpConfiguration mBuilderIpConfig;
- @Nullable
- private NetworkCapabilities mBuilderNetworkCapabilities;
-
- public Builder(){}
-
- /**
- * Constructor to populate the builder's values with an already built
- * {@link EthernetNetworkUpdateRequest}.
- * @param request the {@link EthernetNetworkUpdateRequest} to populate with.
- */
- public Builder(@NonNull final EthernetNetworkUpdateRequest request) {
- Objects.requireNonNull(request);
- mBuilderIpConfig = null == request.mIpConfig
- ? null : new IpConfiguration(request.mIpConfig);
- mBuilderNetworkCapabilities = null == request.mNetworkCapabilities
- ? null : new NetworkCapabilities(request.mNetworkCapabilities);
- }
-
- /**
- * Set the {@link IpConfiguration} to be used with the {@code Builder}.
- * @param ipConfig the {@link IpConfiguration} to set.
- * @return The builder to facilitate chaining.
- */
- @NonNull
- public Builder setIpConfiguration(@Nullable final IpConfiguration ipConfig) {
- mBuilderIpConfig = ipConfig == null ? null : new IpConfiguration(ipConfig);
- return this;
- }
-
- /**
- * Set the {@link NetworkCapabilities} to be used with the {@code Builder}.
- * @param nc the {@link NetworkCapabilities} to set.
- * @return The builder to facilitate chaining.
- */
- @NonNull
- public Builder setNetworkCapabilities(@Nullable final NetworkCapabilities nc) {
- mBuilderNetworkCapabilities = nc == null ? null : new NetworkCapabilities(nc);
- return this;
- }
-
- /**
- * Build {@link EthernetNetworkUpdateRequest} return the current update request.
- *
- * @throws IllegalStateException when both mBuilderNetworkCapabilities and mBuilderIpConfig
- * are null.
- */
- @NonNull
- public EthernetNetworkUpdateRequest build() {
- if (mBuilderIpConfig == null && mBuilderNetworkCapabilities == null) {
- throw new IllegalStateException(
- "Cannot construct an empty EthernetNetworkUpdateRequest");
- }
- return new EthernetNetworkUpdateRequest(mBuilderIpConfig, mBuilderNetworkCapabilities);
- }
- }
-
- @Override
- public String toString() {
- return "EthernetNetworkUpdateRequest{"
- + "mIpConfig=" + mIpConfig
- + ", mNetworkCapabilities=" + mNetworkCapabilities + '}';
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- EthernetNetworkUpdateRequest that = (EthernetNetworkUpdateRequest) o;
-
- return Objects.equals(that.getIpConfiguration(), mIpConfig)
- && Objects.equals(that.getNetworkCapabilities(), mNetworkCapabilities);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mIpConfig, mNetworkCapabilities);
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeParcelable(mIpConfig, flags);
- dest.writeParcelable(mNetworkCapabilities, flags);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull
- public static final Parcelable.Creator<EthernetNetworkUpdateRequest> CREATOR =
- new Parcelable.Creator<EthernetNetworkUpdateRequest>() {
- @Override
- public EthernetNetworkUpdateRequest[] newArray(int size) {
- return new EthernetNetworkUpdateRequest[size];
- }
-
- @Override
- public EthernetNetworkUpdateRequest createFromParcel(@NonNull Parcel source) {
- return new EthernetNetworkUpdateRequest(source);
- }
- };
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IEthernetManager.aidl b/packages/ConnectivityT/framework-t/src/android/net/IEthernetManager.aidl
deleted file mode 100644
index 42e4c1a..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IEthernetManager.aidl
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2014 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.net;
-
-import android.net.IpConfiguration;
-import android.net.IEthernetServiceListener;
-import android.net.EthernetNetworkManagementException;
-import android.net.EthernetNetworkUpdateRequest;
-import android.net.INetworkInterfaceOutcomeReceiver;
-import android.net.ITetheredInterfaceCallback;
-
-import java.util.List;
-
-/**
- * Interface that answers queries about, and allows changing
- * ethernet configuration.
- */
-/** {@hide} */
-interface IEthernetManager
-{
- String[] getAvailableInterfaces();
- IpConfiguration getConfiguration(String iface);
- void setConfiguration(String iface, in IpConfiguration config);
- boolean isAvailable(String iface);
- void addListener(in IEthernetServiceListener listener);
- void removeListener(in IEthernetServiceListener listener);
- void setIncludeTestInterfaces(boolean include);
- void requestTetheredInterface(in ITetheredInterfaceCallback callback);
- void releaseTetheredInterface(in ITetheredInterfaceCallback callback);
- void updateConfiguration(String iface, in EthernetNetworkUpdateRequest request,
- in INetworkInterfaceOutcomeReceiver listener);
- void connectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener);
- void disconnectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener);
- void setEthernetEnabled(boolean enabled);
- List<String> getInterfaceList();
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl b/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl
deleted file mode 100644
index 751605b..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2014 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.net;
-
-import android.net.IpConfiguration;
-
-/** @hide */
-oneway interface IEthernetServiceListener
-{
- void onEthernetStateChanged(int state);
- void onInterfaceStateChanged(String iface, int state, int role,
- in IpConfiguration configuration);
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IIpSecService.aidl b/packages/ConnectivityT/framework-t/src/android/net/IIpSecService.aidl
deleted file mode 100644
index 933256a..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IIpSecService.aidl
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-** Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.net;
-
-import android.net.LinkAddress;
-import android.net.Network;
-import android.net.IpSecConfig;
-import android.net.IpSecUdpEncapResponse;
-import android.net.IpSecSpiResponse;
-import android.net.IpSecTransformResponse;
-import android.net.IpSecTunnelInterfaceResponse;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-
-/**
- * @hide
- */
-interface IIpSecService
-{
- IpSecSpiResponse allocateSecurityParameterIndex(
- in String destinationAddress, int requestedSpi, in IBinder binder);
-
- void releaseSecurityParameterIndex(int resourceId);
-
- IpSecUdpEncapResponse openUdpEncapsulationSocket(int port, in IBinder binder);
-
- void closeUdpEncapsulationSocket(int resourceId);
-
- IpSecTunnelInterfaceResponse createTunnelInterface(
- in String localAddr,
- in String remoteAddr,
- in Network underlyingNetwork,
- in IBinder binder,
- in String callingPackage);
-
- void addAddressToTunnelInterface(
- int tunnelResourceId,
- in LinkAddress localAddr,
- in String callingPackage);
-
- void removeAddressFromTunnelInterface(
- int tunnelResourceId,
- in LinkAddress localAddr,
- in String callingPackage);
-
- void setNetworkForTunnelInterface(
- int tunnelResourceId, in Network underlyingNetwork, in String callingPackage);
-
- void deleteTunnelInterface(int resourceId, in String callingPackage);
-
- IpSecTransformResponse createTransform(
- in IpSecConfig c, in IBinder binder, in String callingPackage);
-
- void deleteTransform(int transformId);
-
- void applyTransportModeTransform(
- in ParcelFileDescriptor socket, int direction, int transformId);
-
- void applyTunnelModeTransform(
- int tunnelResourceId, int direction, int transformResourceId, in String callingPackage);
-
- void removeTransportModeTransforms(in ParcelFileDescriptor socket);
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/INetworkInterfaceOutcomeReceiver.aidl b/packages/ConnectivityT/framework-t/src/android/net/INetworkInterfaceOutcomeReceiver.aidl
deleted file mode 100644
index 85795ea..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/INetworkInterfaceOutcomeReceiver.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.net.EthernetNetworkManagementException;
-
-/** @hide */
-oneway interface INetworkInterfaceOutcomeReceiver {
- void onResult(in String iface);
- void onError(in EthernetNetworkManagementException e);
-}
\ No newline at end of file
diff --git a/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsService.aidl b/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsService.aidl
deleted file mode 100644
index c86f7fd..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsService.aidl
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2011 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.net;
-
-import android.net.DataUsageRequest;
-import android.net.INetworkStatsSession;
-import android.net.Network;
-import android.net.NetworkStateSnapshot;
-import android.net.NetworkStats;
-import android.net.NetworkStatsHistory;
-import android.net.NetworkTemplate;
-import android.net.UnderlyingNetworkInfo;
-import android.net.netstats.IUsageCallback;
-import android.net.netstats.provider.INetworkStatsProvider;
-import android.net.netstats.provider.INetworkStatsProviderCallback;
-import android.os.IBinder;
-import android.os.Messenger;
-
-/** {@hide} */
-interface INetworkStatsService {
-
- /** Start a statistics query session. */
- @UnsupportedAppUsage
- INetworkStatsSession openSession();
-
- /** Start a statistics query session. If calling package is profile or device owner then it is
- * granted automatic access if apiLevel is NetworkStatsManager.API_LEVEL_DPC_ALLOWED. If
- * apiLevel is at least NetworkStatsManager.API_LEVEL_REQUIRES_PACKAGE_USAGE_STATS then
- * PACKAGE_USAGE_STATS permission is always checked. If PACKAGE_USAGE_STATS is not granted
- * READ_NETWORK_USAGE_STATS is checked for.
- */
- @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage);
-
- /** Return data layer snapshot of UID network usage. */
- @UnsupportedAppUsage
- NetworkStats getDataLayerSnapshotForUid(int uid);
-
- /** Get the transport NetworkStats for all UIDs since boot. */
- NetworkStats getUidStatsForTransport(int transport);
-
- /** Return set of any ifaces associated with mobile networks since boot. */
- @UnsupportedAppUsage
- String[] getMobileIfaces();
-
- /** Increment data layer count of operations performed for UID and tag. */
- void incrementOperationCount(int uid, int tag, int operationCount);
-
- /** Notify {@code NetworkStatsService} about network status changed. */
- void notifyNetworkStatus(
- in Network[] defaultNetworks,
- in NetworkStateSnapshot[] snapshots,
- in String activeIface,
- in UnderlyingNetworkInfo[] underlyingNetworkInfos);
- /** Force update of statistics. */
- @UnsupportedAppUsage
- void forceUpdate();
-
- /** Registers a callback on data usage. */
- DataUsageRequest registerUsageCallback(String callingPackage,
- in DataUsageRequest request, in IUsageCallback callback);
-
- /** Unregisters a callback on data usage. */
- void unregisterUsageRequest(in DataUsageRequest request);
-
- /** Get the uid stats information since boot */
- long getUidStats(int uid, int type);
-
- /** Get the iface stats information since boot */
- long getIfaceStats(String iface, int type);
-
- /** Get the total network stats information since boot */
- long getTotalStats(int type);
-
- /** Registers a network stats provider */
- INetworkStatsProviderCallback registerNetworkStatsProvider(String tag,
- in INetworkStatsProvider provider);
-
- /** Mark given UID as being in foreground for stats purposes. */
- void noteUidForeground(int uid, boolean uidForeground);
-
- /** Advise persistence threshold; may be overridden internally. */
- void advisePersistThreshold(long thresholdBytes);
-
- /**
- * Set the warning and limit to all registered custom network stats providers.
- * Note that invocation of any interface will be sent to all providers.
- */
- void setStatsProviderWarningAndLimitAsync(String iface, long warning, long limit);
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsSession.aidl b/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsSession.aidl
deleted file mode 100644
index ab70be8..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/INetworkStatsSession.aidl
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2012 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.net;
-
-import android.net.NetworkStats;
-import android.net.NetworkStatsHistory;
-import android.net.NetworkTemplate;
-
-/** {@hide} */
-interface INetworkStatsSession {
-
- /** Return device aggregated network layer usage summary for traffic that matches template. */
- NetworkStats getDeviceSummaryForNetwork(in NetworkTemplate template, long start, long end);
-
- /** Return network layer usage summary for traffic that matches template. */
- @UnsupportedAppUsage
- NetworkStats getSummaryForNetwork(in NetworkTemplate template, long start, long end);
- /** Return historical network layer stats for traffic that matches template. */
- @UnsupportedAppUsage
- NetworkStatsHistory getHistoryForNetwork(in NetworkTemplate template, int fields);
- /**
- * Return historical network layer stats for traffic that matches template, start and end
- * timestamp.
- */
- NetworkStatsHistory getHistoryIntervalForNetwork(in NetworkTemplate template, int fields, long start, long end);
-
- /**
- * Return network layer usage summary per UID for traffic that matches template.
- *
- * <p>The resulting {@code NetworkStats#getElapsedRealtime()} contains time delta between
- * {@code start} and {@code end}.
- *
- * @param template - a predicate to filter netstats.
- * @param start - start of the range, timestamp in milliseconds since the epoch.
- * @param end - end of the range, timestamp in milliseconds since the epoch.
- * @param includeTags - includes data usage tags if true.
- */
- @UnsupportedAppUsage
- NetworkStats getSummaryForAllUid(in NetworkTemplate template, long start, long end, boolean includeTags);
-
- /** Return network layer usage summary per UID for tagged traffic that matches template. */
- NetworkStats getTaggedSummaryForAllUid(in NetworkTemplate template, long start, long end);
-
- /** Return historical network layer stats for specific UID traffic that matches template. */
- @UnsupportedAppUsage
- NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int set, int tag, int fields);
- /** Return historical network layer stats for specific UID traffic that matches template. */
- NetworkStatsHistory getHistoryIntervalForUid(in NetworkTemplate template, int uid, int set, int tag, int fields, long start, long end);
-
- /** Return array of uids that have stats and are accessible to the calling user */
- int[] getRelevantUids();
-
- @UnsupportedAppUsage
- void close();
-
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/ITetheredInterfaceCallback.aidl b/packages/ConnectivityT/framework-t/src/android/net/ITetheredInterfaceCallback.aidl
deleted file mode 100644
index 14aa023..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/ITetheredInterfaceCallback.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2020 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.net;
-
-/** @hide */
-oneway interface ITetheredInterfaceCallback {
- void onAvailable(in String iface);
- void onUnavailable();
-}
\ No newline at end of file
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java
deleted file mode 100644
index 10a22ac..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net;
-
-import android.annotation.NonNull;
-import android.annotation.StringDef;
-import android.content.res.Resources;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * This class represents a single algorithm that can be used by an {@link IpSecTransform}.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4301">RFC 4301, Security Architecture for the
- * Internet Protocol</a>
- */
-public final class IpSecAlgorithm implements Parcelable {
- private static final String TAG = "IpSecAlgorithm";
-
- /**
- * Null cipher.
- *
- * @hide
- */
- public static final String CRYPT_NULL = "ecb(cipher_null)";
-
- /**
- * AES-CBC Encryption/Ciphering Algorithm.
- *
- * <p>Valid lengths for this key are {128, 192, 256}.
- */
- public static final String CRYPT_AES_CBC = "cbc(aes)";
-
- /**
- * AES-CTR Encryption/Ciphering Algorithm.
- *
- * <p>Valid lengths for keying material are {160, 224, 288}.
- *
- * <p>As per <a href="https://tools.ietf.org/html/rfc3686#section-5.1">RFC3686 (Section
- * 5.1)</a>, keying material consists of a 128, 192, or 256 bit AES key followed by a 32-bit
- * nonce. RFC compliance requires that the nonce must be unique per security association.
- *
- * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
- * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
- * included in the returned algorithm set. The returned algorithm set will not change unless the
- * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
- * requested on an unsupported device.
- *
- * <p>@see {@link #getSupportedAlgorithms()}
- */
- // This algorithm may be available on devices released before Android 12, and is guaranteed
- // to be available on devices first shipped with Android 12 or later.
- public static final String CRYPT_AES_CTR = "rfc3686(ctr(aes))";
-
- /**
- * MD5 HMAC Authentication/Integrity Algorithm. <b>This algorithm is not recommended for use in
- * new applications and is provided for legacy compatibility with 3gpp infrastructure.</b>
- *
- * <p>Keys for this algorithm must be 128 bits in length.
- *
- * <p>Valid truncation lengths are multiples of 8 bits from 96 to 128.
- */
- public static final String AUTH_HMAC_MD5 = "hmac(md5)";
-
- /**
- * SHA1 HMAC Authentication/Integrity Algorithm. <b>This algorithm is not recommended for use in
- * new applications and is provided for legacy compatibility with 3gpp infrastructure.</b>
- *
- * <p>Keys for this algorithm must be 160 bits in length.
- *
- * <p>Valid truncation lengths are multiples of 8 bits from 96 to 160.
- */
- public static final String AUTH_HMAC_SHA1 = "hmac(sha1)";
-
- /**
- * SHA256 HMAC Authentication/Integrity Algorithm.
- *
- * <p>Keys for this algorithm must be 256 bits in length.
- *
- * <p>Valid truncation lengths are multiples of 8 bits from 96 to 256.
- */
- public static final String AUTH_HMAC_SHA256 = "hmac(sha256)";
-
- /**
- * SHA384 HMAC Authentication/Integrity Algorithm.
- *
- * <p>Keys for this algorithm must be 384 bits in length.
- *
- * <p>Valid truncation lengths are multiples of 8 bits from 192 to 384.
- */
- public static final String AUTH_HMAC_SHA384 = "hmac(sha384)";
-
- /**
- * SHA512 HMAC Authentication/Integrity Algorithm.
- *
- * <p>Keys for this algorithm must be 512 bits in length.
- *
- * <p>Valid truncation lengths are multiples of 8 bits from 256 to 512.
- */
- public static final String AUTH_HMAC_SHA512 = "hmac(sha512)";
-
- /**
- * AES-XCBC Authentication/Integrity Algorithm.
- *
- * <p>Keys for this algorithm must be 128 bits in length.
- *
- * <p>The only valid truncation length is 96 bits.
- *
- * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
- * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
- * included in the returned algorithm set. The returned algorithm set will not change unless the
- * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
- * requested on an unsupported device.
- *
- * <p>@see {@link #getSupportedAlgorithms()}
- */
- // This algorithm may be available on devices released before Android 12, and is guaranteed
- // to be available on devices first shipped with Android 12 or later.
- public static final String AUTH_AES_XCBC = "xcbc(aes)";
-
- /**
- * AES-CMAC Authentication/Integrity Algorithm.
- *
- * <p>Keys for this algorithm must be 128 bits in length.
- *
- * <p>The only valid truncation length is 96 bits.
- *
- * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
- * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
- * included in the returned algorithm set. The returned algorithm set will not change unless the
- * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
- * requested on an unsupported device.
- *
- * <p>@see {@link #getSupportedAlgorithms()}
- */
- // This algorithm may be available on devices released before Android 12, and is guaranteed
- // to be available on devices first shipped with Android 12 or later.
- public static final String AUTH_AES_CMAC = "cmac(aes)";
-
- /**
- * AES-GCM Authentication/Integrity + Encryption/Ciphering Algorithm.
- *
- * <p>Valid lengths for keying material are {160, 224, 288}.
- *
- * <p>As per <a href="https://tools.ietf.org/html/rfc4106#section-8.1">RFC4106 (Section
- * 8.1)</a>, keying material consists of a 128, 192, or 256 bit AES key followed by a 32-bit
- * salt. RFC compliance requires that the salt must be unique per invocation with the same key.
- *
- * <p>Valid ICV (truncation) lengths are {64, 96, 128}.
- */
- public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
-
- /**
- * ChaCha20-Poly1305 Authentication/Integrity + Encryption/Ciphering Algorithm.
- *
- * <p>Keys for this algorithm must be 288 bits in length.
- *
- * <p>As per <a href="https://tools.ietf.org/html/rfc7634#section-2">RFC7634 (Section 2)</a>,
- * keying material consists of a 256 bit key followed by a 32-bit salt. The salt is fixed per
- * security association.
- *
- * <p>The only valid ICV (truncation) length is 128 bits.
- *
- * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
- * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
- * included in the returned algorithm set. The returned algorithm set will not change unless the
- * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
- * requested on an unsupported device.
- *
- * <p>@see {@link #getSupportedAlgorithms()}
- */
- // This algorithm may be available on devices released before Android 12, and is guaranteed
- // to be available on devices first shipped with Android 12 or later.
- public static final String AUTH_CRYPT_CHACHA20_POLY1305 = "rfc7539esp(chacha20,poly1305)";
-
- /** @hide */
- @StringDef({
- CRYPT_AES_CBC,
- CRYPT_AES_CTR,
- AUTH_HMAC_MD5,
- AUTH_HMAC_SHA1,
- AUTH_HMAC_SHA256,
- AUTH_HMAC_SHA384,
- AUTH_HMAC_SHA512,
- AUTH_AES_XCBC,
- AUTH_AES_CMAC,
- AUTH_CRYPT_AES_GCM,
- AUTH_CRYPT_CHACHA20_POLY1305
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface AlgorithmName {}
-
- /** @hide */
- @VisibleForTesting
- public static final Map<String, Integer> ALGO_TO_REQUIRED_FIRST_SDK = new HashMap<>();
-
- private static final int SDK_VERSION_ZERO = 0;
-
- static {
- ALGO_TO_REQUIRED_FIRST_SDK.put(CRYPT_AES_CBC, SDK_VERSION_ZERO);
- ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_MD5, SDK_VERSION_ZERO);
- ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA1, SDK_VERSION_ZERO);
- ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA256, SDK_VERSION_ZERO);
- ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA384, SDK_VERSION_ZERO);
- ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_HMAC_SHA512, SDK_VERSION_ZERO);
- ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_CRYPT_AES_GCM, SDK_VERSION_ZERO);
-
- ALGO_TO_REQUIRED_FIRST_SDK.put(CRYPT_AES_CTR, Build.VERSION_CODES.S);
- ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_AES_XCBC, Build.VERSION_CODES.S);
- ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_AES_CMAC, Build.VERSION_CODES.S);
- ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_CRYPT_CHACHA20_POLY1305, Build.VERSION_CODES.S);
- }
-
- private static final Set<String> ENABLED_ALGOS =
- Collections.unmodifiableSet(loadAlgos(Resources.getSystem()));
-
- private final String mName;
- private final byte[] mKey;
- private final int mTruncLenBits;
-
- /**
- * Creates an IpSecAlgorithm of one of the supported types. Supported algorithm names are
- * defined as constants in this class.
- *
- * <p>For algorithms that produce an integrity check value, the truncation length is a required
- * parameter. See {@link #IpSecAlgorithm(String algorithm, byte[] key, int truncLenBits)}
- *
- * @param algorithm name of the algorithm.
- * @param key key padded to a multiple of 8 bits.
- * @throws IllegalArgumentException if algorithm or key length is invalid.
- */
- public IpSecAlgorithm(@NonNull @AlgorithmName String algorithm, @NonNull byte[] key) {
- this(algorithm, key, 0);
- }
-
- /**
- * Creates an IpSecAlgorithm of one of the supported types. Supported algorithm names are
- * defined as constants in this class.
- *
- * <p>This constructor only supports algorithms that use a truncation length. i.e.
- * Authentication and Authenticated Encryption algorithms.
- *
- * @param algorithm name of the algorithm.
- * @param key key padded to a multiple of 8 bits.
- * @param truncLenBits number of bits of output hash to use.
- * @throws IllegalArgumentException if algorithm, key length or truncation length is invalid.
- */
- public IpSecAlgorithm(
- @NonNull @AlgorithmName String algorithm, @NonNull byte[] key, int truncLenBits) {
- mName = algorithm;
- mKey = key.clone();
- mTruncLenBits = truncLenBits;
- checkValidOrThrow(mName, mKey.length * 8, mTruncLenBits);
- }
-
- /** Get the algorithm name */
- @NonNull
- public String getName() {
- return mName;
- }
-
- /** Get the key for this algorithm */
- @NonNull
- public byte[] getKey() {
- return mKey.clone();
- }
-
- /** Get the truncation length of this algorithm, in bits */
- public int getTruncationLengthBits() {
- return mTruncLenBits;
- }
-
- /** Parcelable Implementation */
- public int describeContents() {
- return 0;
- }
-
- /** Write to parcel */
- public void writeToParcel(Parcel out, int flags) {
- out.writeString(mName);
- out.writeByteArray(mKey);
- out.writeInt(mTruncLenBits);
- }
-
- /** Parcelable Creator */
- public static final @android.annotation.NonNull Parcelable.Creator<IpSecAlgorithm> CREATOR =
- new Parcelable.Creator<IpSecAlgorithm>() {
- public IpSecAlgorithm createFromParcel(Parcel in) {
- final String name = in.readString();
- final byte[] key = in.createByteArray();
- final int truncLenBits = in.readInt();
-
- return new IpSecAlgorithm(name, key, truncLenBits);
- }
-
- public IpSecAlgorithm[] newArray(int size) {
- return new IpSecAlgorithm[size];
- }
- };
-
- /**
- * Returns supported IPsec algorithms for the current device.
- *
- * <p>Some algorithms may not be supported on old devices. Callers MUST check if an algorithm is
- * supported before using it.
- */
- @NonNull
- public static Set<String> getSupportedAlgorithms() {
- return ENABLED_ALGOS;
- }
-
- /** @hide */
- @VisibleForTesting
- public static Set<String> loadAlgos(Resources systemResources) {
- final Set<String> enabledAlgos = new HashSet<>();
-
- // Load and validate the optional algorithm resource. Undefined or duplicate algorithms in
- // the resource are not allowed.
- final String[] resourceAlgos = systemResources.getStringArray(
- android.R.array.config_optionalIpSecAlgorithms);
- for (String str : resourceAlgos) {
- if (!ALGO_TO_REQUIRED_FIRST_SDK.containsKey(str) || !enabledAlgos.add(str)) {
- // This error should be caught by CTS and never be thrown to API callers
- throw new IllegalArgumentException("Invalid or repeated algorithm " + str);
- }
- }
-
- for (Entry<String, Integer> entry : ALGO_TO_REQUIRED_FIRST_SDK.entrySet()) {
- if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= entry.getValue()) {
- enabledAlgos.add(entry.getKey());
- }
- }
-
- return enabledAlgos;
- }
-
- private static void checkValidOrThrow(String name, int keyLen, int truncLen) {
- final boolean isValidLen;
- final boolean isValidTruncLen;
-
- if (!getSupportedAlgorithms().contains(name)) {
- throw new IllegalArgumentException("Unsupported algorithm: " + name);
- }
-
- switch (name) {
- case CRYPT_AES_CBC:
- isValidLen = keyLen == 128 || keyLen == 192 || keyLen == 256;
- isValidTruncLen = true;
- break;
- case CRYPT_AES_CTR:
- // The keying material for AES-CTR is a key plus a 32-bit salt
- isValidLen = keyLen == 128 + 32 || keyLen == 192 + 32 || keyLen == 256 + 32;
- isValidTruncLen = true;
- break;
- case AUTH_HMAC_MD5:
- isValidLen = keyLen == 128;
- isValidTruncLen = truncLen >= 96 && truncLen <= 128;
- break;
- case AUTH_HMAC_SHA1:
- isValidLen = keyLen == 160;
- isValidTruncLen = truncLen >= 96 && truncLen <= 160;
- break;
- case AUTH_HMAC_SHA256:
- isValidLen = keyLen == 256;
- isValidTruncLen = truncLen >= 96 && truncLen <= 256;
- break;
- case AUTH_HMAC_SHA384:
- isValidLen = keyLen == 384;
- isValidTruncLen = truncLen >= 192 && truncLen <= 384;
- break;
- case AUTH_HMAC_SHA512:
- isValidLen = keyLen == 512;
- isValidTruncLen = truncLen >= 256 && truncLen <= 512;
- break;
- case AUTH_AES_XCBC:
- isValidLen = keyLen == 128;
- isValidTruncLen = truncLen == 96;
- break;
- case AUTH_AES_CMAC:
- isValidLen = keyLen == 128;
- isValidTruncLen = truncLen == 96;
- break;
- case AUTH_CRYPT_AES_GCM:
- // The keying material for GCM is a key plus a 32-bit salt
- isValidLen = keyLen == 128 + 32 || keyLen == 192 + 32 || keyLen == 256 + 32;
- isValidTruncLen = truncLen == 64 || truncLen == 96 || truncLen == 128;
- break;
- case AUTH_CRYPT_CHACHA20_POLY1305:
- // The keying material for ChaCha20Poly1305 is a key plus a 32-bit salt
- isValidLen = keyLen == 256 + 32;
- isValidTruncLen = truncLen == 128;
- break;
- default:
- // Should never hit here.
- throw new IllegalArgumentException("Couldn't find an algorithm: " + name);
- }
-
- if (!isValidLen) {
- throw new IllegalArgumentException("Invalid key material keyLength: " + keyLen);
- }
- if (!isValidTruncLen) {
- throw new IllegalArgumentException("Invalid truncation keyLength: " + truncLen);
- }
- }
-
- /** @hide */
- public boolean isAuthentication() {
- switch (getName()) {
- // Fallthrough
- case AUTH_HMAC_MD5:
- case AUTH_HMAC_SHA1:
- case AUTH_HMAC_SHA256:
- case AUTH_HMAC_SHA384:
- case AUTH_HMAC_SHA512:
- case AUTH_AES_XCBC:
- case AUTH_AES_CMAC:
- return true;
- default:
- return false;
- }
- }
-
- /** @hide */
- public boolean isEncryption() {
- switch (getName()) {
- case CRYPT_AES_CBC: // fallthrough
- case CRYPT_AES_CTR:
- return true;
- default:
- return false;
- }
- }
-
- /** @hide */
- public boolean isAead() {
- switch (getName()) {
- case AUTH_CRYPT_AES_GCM: // fallthrough
- case AUTH_CRYPT_CHACHA20_POLY1305:
- return true;
- default:
- return false;
- }
- }
-
- @Override
- @NonNull
- public String toString() {
- return new StringBuilder()
- .append("{mName=")
- .append(mName)
- .append(", mTruncLenBits=")
- .append(mTruncLenBits)
- .append("}")
- .toString();
- }
-
- /** @hide */
- @VisibleForTesting
- public static boolean equals(IpSecAlgorithm lhs, IpSecAlgorithm rhs) {
- if (lhs == null || rhs == null) return (lhs == rhs);
- return (lhs.mName.equals(rhs.mName)
- && Arrays.equals(lhs.mKey, rhs.mKey)
- && lhs.mTruncLenBits == rhs.mTruncLenBits);
- }
-};
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecConfig.aidl b/packages/ConnectivityT/framework-t/src/android/net/IpSecConfig.aidl
deleted file mode 100644
index eaefca7..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecConfig.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-/** @hide */
-parcelable IpSecConfig;
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecConfig.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecConfig.java
deleted file mode 100644
index 03bb187..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecConfig.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * This class encapsulates all the configuration parameters needed to create IPsec transforms and
- * policies.
- *
- * @hide
- */
-public final class IpSecConfig implements Parcelable {
- private static final String TAG = "IpSecConfig";
-
- // MODE_TRANSPORT or MODE_TUNNEL
- private int mMode = IpSecTransform.MODE_TRANSPORT;
-
- // Preventing this from being null simplifies Java->Native binder
- private String mSourceAddress = "";
-
- // Preventing this from being null simplifies Java->Native binder
- private String mDestinationAddress = "";
-
- // The underlying Network that represents the "gateway" Network
- // for outbound packets. It may also be used to select packets.
- private Network mNetwork;
-
- // Minimum requirements for identifying a transform
- // SPI identifying the IPsec SA in packet processing
- // and a destination IP address
- private int mSpiResourceId = IpSecManager.INVALID_RESOURCE_ID;
-
- // Encryption Algorithm
- private IpSecAlgorithm mEncryption;
-
- // Authentication Algorithm
- private IpSecAlgorithm mAuthentication;
-
- // Authenticated Encryption Algorithm
- private IpSecAlgorithm mAuthenticatedEncryption;
-
- // For tunnel mode IPv4 UDP Encapsulation
- // IpSecTransform#ENCAP_ESP_*, such as ENCAP_ESP_OVER_UDP_IKE
- private int mEncapType = IpSecTransform.ENCAP_NONE;
- private int mEncapSocketResourceId = IpSecManager.INVALID_RESOURCE_ID;
- private int mEncapRemotePort;
-
- // An interval, in seconds between the NattKeepalive packets
- private int mNattKeepaliveInterval;
-
- // XFRM mark and mask; defaults to 0 (no mark/mask)
- private int mMarkValue;
- private int mMarkMask;
-
- // XFRM interface id
- private int mXfrmInterfaceId;
-
- /** Set the mode for this IPsec transform */
- public void setMode(int mode) {
- mMode = mode;
- }
-
- /** Set the source IP addres for this IPsec transform */
- public void setSourceAddress(String sourceAddress) {
- mSourceAddress = sourceAddress;
- }
-
- /** Set the destination IP address for this IPsec transform */
- public void setDestinationAddress(String destinationAddress) {
- mDestinationAddress = destinationAddress;
- }
-
- /** Set the SPI by resource ID */
- public void setSpiResourceId(int resourceId) {
- mSpiResourceId = resourceId;
- }
-
- /** Set the encryption algorithm */
- public void setEncryption(IpSecAlgorithm encryption) {
- mEncryption = encryption;
- }
-
- /** Set the authentication algorithm */
- public void setAuthentication(IpSecAlgorithm authentication) {
- mAuthentication = authentication;
- }
-
- /** Set the authenticated encryption algorithm */
- public void setAuthenticatedEncryption(IpSecAlgorithm authenticatedEncryption) {
- mAuthenticatedEncryption = authenticatedEncryption;
- }
-
- /** Set the underlying network that will carry traffic for this transform */
- public void setNetwork(Network network) {
- mNetwork = network;
- }
-
- public void setEncapType(int encapType) {
- mEncapType = encapType;
- }
-
- public void setEncapSocketResourceId(int resourceId) {
- mEncapSocketResourceId = resourceId;
- }
-
- public void setEncapRemotePort(int port) {
- mEncapRemotePort = port;
- }
-
- public void setNattKeepaliveInterval(int interval) {
- mNattKeepaliveInterval = interval;
- }
-
- /**
- * Sets the mark value
- *
- * <p>Internal (System server) use only. Marks passed in by users will be overwritten or
- * ignored.
- */
- public void setMarkValue(int mark) {
- mMarkValue = mark;
- }
-
- /**
- * Sets the mark mask
- *
- * <p>Internal (System server) use only. Marks passed in by users will be overwritten or
- * ignored.
- */
- public void setMarkMask(int mask) {
- mMarkMask = mask;
- }
-
- public void setXfrmInterfaceId(int xfrmInterfaceId) {
- mXfrmInterfaceId = xfrmInterfaceId;
- }
-
- // Transport or Tunnel
- public int getMode() {
- return mMode;
- }
-
- public String getSourceAddress() {
- return mSourceAddress;
- }
-
- public int getSpiResourceId() {
- return mSpiResourceId;
- }
-
- public String getDestinationAddress() {
- return mDestinationAddress;
- }
-
- public IpSecAlgorithm getEncryption() {
- return mEncryption;
- }
-
- public IpSecAlgorithm getAuthentication() {
- return mAuthentication;
- }
-
- public IpSecAlgorithm getAuthenticatedEncryption() {
- return mAuthenticatedEncryption;
- }
-
- public Network getNetwork() {
- return mNetwork;
- }
-
- public int getEncapType() {
- return mEncapType;
- }
-
- public int getEncapSocketResourceId() {
- return mEncapSocketResourceId;
- }
-
- public int getEncapRemotePort() {
- return mEncapRemotePort;
- }
-
- public int getNattKeepaliveInterval() {
- return mNattKeepaliveInterval;
- }
-
- public int getMarkValue() {
- return mMarkValue;
- }
-
- public int getMarkMask() {
- return mMarkMask;
- }
-
- public int getXfrmInterfaceId() {
- return mXfrmInterfaceId;
- }
-
- // Parcelable Methods
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(mMode);
- out.writeString(mSourceAddress);
- out.writeString(mDestinationAddress);
- out.writeParcelable(mNetwork, flags);
- out.writeInt(mSpiResourceId);
- out.writeParcelable(mEncryption, flags);
- out.writeParcelable(mAuthentication, flags);
- out.writeParcelable(mAuthenticatedEncryption, flags);
- out.writeInt(mEncapType);
- out.writeInt(mEncapSocketResourceId);
- out.writeInt(mEncapRemotePort);
- out.writeInt(mNattKeepaliveInterval);
- out.writeInt(mMarkValue);
- out.writeInt(mMarkMask);
- out.writeInt(mXfrmInterfaceId);
- }
-
- @VisibleForTesting
- public IpSecConfig() {}
-
- /** Copy constructor */
- @VisibleForTesting
- public IpSecConfig(IpSecConfig c) {
- mMode = c.mMode;
- mSourceAddress = c.mSourceAddress;
- mDestinationAddress = c.mDestinationAddress;
- mNetwork = c.mNetwork;
- mSpiResourceId = c.mSpiResourceId;
- mEncryption = c.mEncryption;
- mAuthentication = c.mAuthentication;
- mAuthenticatedEncryption = c.mAuthenticatedEncryption;
- mEncapType = c.mEncapType;
- mEncapSocketResourceId = c.mEncapSocketResourceId;
- mEncapRemotePort = c.mEncapRemotePort;
- mNattKeepaliveInterval = c.mNattKeepaliveInterval;
- mMarkValue = c.mMarkValue;
- mMarkMask = c.mMarkMask;
- mXfrmInterfaceId = c.mXfrmInterfaceId;
- }
-
- private IpSecConfig(Parcel in) {
- mMode = in.readInt();
- mSourceAddress = in.readString();
- mDestinationAddress = in.readString();
- mNetwork = (Network) in.readParcelable(Network.class.getClassLoader(), android.net.Network.class);
- mSpiResourceId = in.readInt();
- mEncryption =
- (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader(), android.net.IpSecAlgorithm.class);
- mAuthentication =
- (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader(), android.net.IpSecAlgorithm.class);
- mAuthenticatedEncryption =
- (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader(), android.net.IpSecAlgorithm.class);
- mEncapType = in.readInt();
- mEncapSocketResourceId = in.readInt();
- mEncapRemotePort = in.readInt();
- mNattKeepaliveInterval = in.readInt();
- mMarkValue = in.readInt();
- mMarkMask = in.readInt();
- mXfrmInterfaceId = in.readInt();
- }
-
- @Override
- public String toString() {
- StringBuilder strBuilder = new StringBuilder();
- strBuilder
- .append("{mMode=")
- .append(mMode == IpSecTransform.MODE_TUNNEL ? "TUNNEL" : "TRANSPORT")
- .append(", mSourceAddress=")
- .append(mSourceAddress)
- .append(", mDestinationAddress=")
- .append(mDestinationAddress)
- .append(", mNetwork=")
- .append(mNetwork)
- .append(", mEncapType=")
- .append(mEncapType)
- .append(", mEncapSocketResourceId=")
- .append(mEncapSocketResourceId)
- .append(", mEncapRemotePort=")
- .append(mEncapRemotePort)
- .append(", mNattKeepaliveInterval=")
- .append(mNattKeepaliveInterval)
- .append("{mSpiResourceId=")
- .append(mSpiResourceId)
- .append(", mEncryption=")
- .append(mEncryption)
- .append(", mAuthentication=")
- .append(mAuthentication)
- .append(", mAuthenticatedEncryption=")
- .append(mAuthenticatedEncryption)
- .append(", mMarkValue=")
- .append(mMarkValue)
- .append(", mMarkMask=")
- .append(mMarkMask)
- .append(", mXfrmInterfaceId=")
- .append(mXfrmInterfaceId)
- .append("}");
-
- return strBuilder.toString();
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<IpSecConfig> CREATOR =
- new Parcelable.Creator<IpSecConfig>() {
- public IpSecConfig createFromParcel(Parcel in) {
- return new IpSecConfig(in);
- }
-
- public IpSecConfig[] newArray(int size) {
- return new IpSecConfig[size];
- }
- };
-
- @Override
- public boolean equals(@Nullable Object other) {
- if (!(other instanceof IpSecConfig)) return false;
- final IpSecConfig rhs = (IpSecConfig) other;
- return (mMode == rhs.mMode
- && mSourceAddress.equals(rhs.mSourceAddress)
- && mDestinationAddress.equals(rhs.mDestinationAddress)
- && ((mNetwork != null && mNetwork.equals(rhs.mNetwork))
- || (mNetwork == rhs.mNetwork))
- && mEncapType == rhs.mEncapType
- && mEncapSocketResourceId == rhs.mEncapSocketResourceId
- && mEncapRemotePort == rhs.mEncapRemotePort
- && mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
- && mSpiResourceId == rhs.mSpiResourceId
- && IpSecAlgorithm.equals(mEncryption, rhs.mEncryption)
- && IpSecAlgorithm.equals(mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
- && IpSecAlgorithm.equals(mAuthentication, rhs.mAuthentication)
- && mMarkValue == rhs.mMarkValue
- && mMarkMask == rhs.mMarkMask
- && mXfrmInterfaceId == rhs.mXfrmInterfaceId);
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java
deleted file mode 100644
index 9cb0947..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java
+++ /dev/null
@@ -1,1065 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.RequiresFeature;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.annotation.TestApi;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.system.ErrnoException;
-import android.system.OsConstants;
-import android.util.AndroidException;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import dalvik.system.CloseGuard;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.util.Objects;
-
-/**
- * This class contains methods for managing IPsec sessions. Once configured, the kernel will apply
- * confidentiality (encryption) and integrity (authentication) to IP traffic.
- *
- * <p>Note that not all aspects of IPsec are permitted by this API. Applications may create
- * transport mode security associations and apply them to individual sockets. Applications looking
- * to create an IPsec VPN should use {@link VpnManager} and {@link Ikev2VpnProfile}.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4301">RFC 4301, Security Architecture for the
- * Internet Protocol</a>
- */
-@SystemService(Context.IPSEC_SERVICE)
-public class IpSecManager {
- private static final String TAG = "IpSecManager";
-
- /**
- * Used when applying a transform to direct traffic through an {@link IpSecTransform}
- * towards the host.
- *
- * <p>See {@link #applyTransportModeTransform(Socket, int, IpSecTransform)}.
- */
- public static final int DIRECTION_IN = 0;
-
- /**
- * Used when applying a transform to direct traffic through an {@link IpSecTransform}
- * away from the host.
- *
- * <p>See {@link #applyTransportModeTransform(Socket, int, IpSecTransform)}.
- */
- public static final int DIRECTION_OUT = 1;
-
- /**
- * Used when applying a transform to direct traffic through an {@link IpSecTransform} for
- * forwarding between interfaces.
- *
- * <p>See {@link #applyTransportModeTransform(Socket, int, IpSecTransform)}.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static final int DIRECTION_FWD = 2;
-
- /** @hide */
- @IntDef(value = {DIRECTION_IN, DIRECTION_OUT})
- @Retention(RetentionPolicy.SOURCE)
- public @interface PolicyDirection {}
-
- /**
- * The Security Parameter Index (SPI) 0 indicates an unknown or invalid index.
- *
- * <p>No IPsec packet may contain an SPI of 0.
- *
- * @hide
- */
- @TestApi public static final int INVALID_SECURITY_PARAMETER_INDEX = 0;
-
- /** @hide */
- public interface Status {
- int OK = 0;
- int RESOURCE_UNAVAILABLE = 1;
- int SPI_UNAVAILABLE = 2;
- }
-
- /** @hide */
- public static final int INVALID_RESOURCE_ID = -1;
-
- /**
- * Thrown to indicate that a requested SPI is in use.
- *
- * <p>The combination of remote {@code InetAddress} and SPI must be unique across all apps on
- * one device. If this error is encountered, a new SPI is required before a transform may be
- * created. This error can be avoided by calling {@link
- * IpSecManager#allocateSecurityParameterIndex}.
- */
- public static final class SpiUnavailableException extends AndroidException {
- private final int mSpi;
-
- /**
- * Construct an exception indicating that a transform with the given SPI is already in use
- * or otherwise unavailable.
- *
- * @param msg description indicating the colliding SPI
- * @param spi the SPI that could not be used due to a collision
- */
- SpiUnavailableException(String msg, int spi) {
- super(msg + " (spi: " + spi + ")");
- mSpi = spi;
- }
-
- /** Get the SPI that caused a collision. */
- public int getSpi() {
- return mSpi;
- }
- }
-
- /**
- * Thrown to indicate that an IPsec resource is unavailable.
- *
- * <p>This could apply to resources such as sockets, {@link SecurityParameterIndex}, {@link
- * IpSecTransform}, or other system resources. If this exception is thrown, users should release
- * allocated objects of the type requested.
- */
- public static final class ResourceUnavailableException extends AndroidException {
-
- ResourceUnavailableException(String msg) {
- super(msg);
- }
- }
-
- private final Context mContext;
- private final IIpSecService mService;
-
- /**
- * This class represents a reserved SPI.
- *
- * <p>Objects of this type are used to track reserved security parameter indices. They can be
- * obtained by calling {@link IpSecManager#allocateSecurityParameterIndex} and must be released
- * by calling {@link #close()} when they are no longer needed.
- */
- public static final class SecurityParameterIndex implements AutoCloseable {
- private final IIpSecService mService;
- private final InetAddress mDestinationAddress;
- private final CloseGuard mCloseGuard = CloseGuard.get();
- private int mSpi = INVALID_SECURITY_PARAMETER_INDEX;
- private int mResourceId = INVALID_RESOURCE_ID;
-
- /** Get the underlying SPI held by this object. */
- public int getSpi() {
- return mSpi;
- }
-
- /**
- * Release an SPI that was previously reserved.
- *
- * <p>Release an SPI for use by other users in the system. If a SecurityParameterIndex is
- * applied to an IpSecTransform, it will become unusable for future transforms but should
- * still be closed to ensure system resources are released.
- */
- @Override
- public void close() {
- try {
- mService.releaseSecurityParameterIndex(mResourceId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- } catch (Exception e) {
- // On close we swallow all random exceptions since failure to close is not
- // actionable by the user.
- Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
- } finally {
- mResourceId = INVALID_RESOURCE_ID;
- mCloseGuard.close();
- }
- }
-
- /** Check that the SPI was closed properly. */
- @Override
- protected void finalize() throws Throwable {
- if (mCloseGuard != null) {
- mCloseGuard.warnIfOpen();
- }
-
- close();
- }
-
- private SecurityParameterIndex(
- @NonNull IIpSecService service, InetAddress destinationAddress, int spi)
- throws ResourceUnavailableException, SpiUnavailableException {
- mService = service;
- mDestinationAddress = destinationAddress;
- try {
- IpSecSpiResponse result =
- mService.allocateSecurityParameterIndex(
- destinationAddress.getHostAddress(), spi, new Binder());
-
- if (result == null) {
- throw new NullPointerException("Received null response from IpSecService");
- }
-
- int status = result.status;
- switch (status) {
- case Status.OK:
- break;
- case Status.RESOURCE_UNAVAILABLE:
- throw new ResourceUnavailableException(
- "No more SPIs may be allocated by this requester.");
- case Status.SPI_UNAVAILABLE:
- throw new SpiUnavailableException("Requested SPI is unavailable", spi);
- default:
- throw new RuntimeException(
- "Unknown status returned by IpSecService: " + status);
- }
- mSpi = result.spi;
- mResourceId = result.resourceId;
-
- if (mSpi == INVALID_SECURITY_PARAMETER_INDEX) {
- throw new RuntimeException("Invalid SPI returned by IpSecService: " + status);
- }
-
- if (mResourceId == INVALID_RESOURCE_ID) {
- throw new RuntimeException(
- "Invalid Resource ID returned by IpSecService: " + status);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- mCloseGuard.open("open");
- }
-
- /** @hide */
- @VisibleForTesting
- public int getResourceId() {
- return mResourceId;
- }
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("SecurityParameterIndex{spi=")
- .append(mSpi)
- .append(",resourceId=")
- .append(mResourceId)
- .append("}")
- .toString();
- }
- }
-
- /**
- * Reserve a random SPI for traffic bound to or from the specified destination address.
- *
- * <p>If successful, this SPI is guaranteed available until released by a call to {@link
- * SecurityParameterIndex#close()}.
- *
- * @param destinationAddress the destination address for traffic bearing the requested SPI.
- * For inbound traffic, the destination should be an address currently assigned on-device.
- * @return the reserved SecurityParameterIndex
- * @throws ResourceUnavailableException indicating that too many SPIs are
- * currently allocated for this user
- */
- @NonNull
- public SecurityParameterIndex allocateSecurityParameterIndex(
- @NonNull InetAddress destinationAddress) throws ResourceUnavailableException {
- try {
- return new SecurityParameterIndex(
- mService,
- destinationAddress,
- IpSecManager.INVALID_SECURITY_PARAMETER_INDEX);
- } catch (ServiceSpecificException e) {
- throw rethrowUncheckedExceptionFromServiceSpecificException(e);
- } catch (SpiUnavailableException unlikely) {
- // Because this function allocates a totally random SPI, it really shouldn't ever
- // fail to allocate an SPI; we simply need this because the exception is checked.
- throw new ResourceUnavailableException("No SPIs available");
- }
- }
-
- /**
- * Reserve the requested SPI for traffic bound to or from the specified destination address.
- *
- * <p>If successful, this SPI is guaranteed available until released by a call to {@link
- * SecurityParameterIndex#close()}.
- *
- * @param destinationAddress the destination address for traffic bearing the requested SPI.
- * For inbound traffic, the destination should be an address currently assigned on-device.
- * @param requestedSpi the requested SPI. The range 1-255 is reserved and may not be used. See
- * RFC 4303 Section 2.1.
- * @return the reserved SecurityParameterIndex
- * @throws ResourceUnavailableException indicating that too many SPIs are
- * currently allocated for this user
- * @throws SpiUnavailableException indicating that the requested SPI could not be
- * reserved
- */
- @NonNull
- public SecurityParameterIndex allocateSecurityParameterIndex(
- @NonNull InetAddress destinationAddress, int requestedSpi)
- throws SpiUnavailableException, ResourceUnavailableException {
- if (requestedSpi == IpSecManager.INVALID_SECURITY_PARAMETER_INDEX) {
- throw new IllegalArgumentException("Requested SPI must be a valid (non-zero) SPI");
- }
- try {
- return new SecurityParameterIndex(mService, destinationAddress, requestedSpi);
- } catch (ServiceSpecificException e) {
- throw rethrowUncheckedExceptionFromServiceSpecificException(e);
- }
- }
-
- /**
- * Apply an IPsec transform to a stream socket.
- *
- * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the
- * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When
- * the transform is removed from the socket by calling {@link #removeTransportModeTransforms},
- * unprotected traffic can resume on that socket.
- *
- * <p>For security reasons, the destination address of any traffic on the socket must match the
- * remote {@code InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any
- * other IP address will result in an IOException. In addition, reads and writes on the socket
- * will throw IOException if the user deactivates the transform (by calling {@link
- * IpSecTransform#close()}) without calling {@link #removeTransportModeTransforms}.
- *
- * <p>Note that when applied to TCP sockets, calling {@link IpSecTransform#close()} on an
- * applied transform before completion of graceful shutdown may result in the shutdown sequence
- * failing to complete. As such, applications requiring graceful shutdown MUST close the socket
- * prior to deactivating the applied transform. Socket closure may be performed asynchronously
- * (in batches), so the returning of a close function does not guarantee shutdown of a socket.
- * Setting an SO_LINGER timeout results in socket closure being performed synchronously, and is
- * sufficient to ensure shutdown.
- *
- * Specifically, if the transform is deactivated (by calling {@link IpSecTransform#close()}),
- * prior to the socket being closed, the standard [FIN - FIN/ACK - ACK], or the reset [RST]
- * packets are dropped due to the lack of a valid Transform. Similarly, if a socket without the
- * SO_LINGER option set is closed, the delayed/batched FIN packets may be dropped.
- *
- * <h4>Rekey Procedure</h4>
- *
- * <p>When applying a new tranform to a socket in the outbound direction, the previous transform
- * will be removed and the new transform will take effect immediately, sending all traffic on
- * the new transform; however, when applying a transform in the inbound direction, traffic
- * on the old transform will continue to be decrypted and delivered until that transform is
- * deallocated by calling {@link IpSecTransform#close()}. This overlap allows lossless rekey
- * procedures where both transforms are valid until both endpoints are using the new transform
- * and all in-flight packets have been received.
- *
- * @param socket a stream socket
- * @param direction the direction in which the transform should be applied
- * @param transform a transport mode {@code IpSecTransform}
- * @throws IOException indicating that the transform could not be applied
- */
- public void applyTransportModeTransform(@NonNull Socket socket,
- @PolicyDirection int direction, @NonNull IpSecTransform transform) throws IOException {
- // Ensure creation of FD. See b/77548890 for more details.
- socket.getSoLinger();
-
- applyTransportModeTransform(socket.getFileDescriptor$(), direction, transform);
- }
-
- /**
- * Apply an IPsec transform to a datagram socket.
- *
- * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the
- * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When
- * the transform is removed from the socket by calling {@link #removeTransportModeTransforms},
- * unprotected traffic can resume on that socket.
- *
- * <p>For security reasons, the destination address of any traffic on the socket must match the
- * remote {@code InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any
- * other IP address will result in an IOException. In addition, reads and writes on the socket
- * will throw IOException if the user deactivates the transform (by calling {@link
- * IpSecTransform#close()}) without calling {@link #removeTransportModeTransforms}.
- *
- * <h4>Rekey Procedure</h4>
- *
- * <p>When applying a new tranform to a socket in the outbound direction, the previous transform
- * will be removed and the new transform will take effect immediately, sending all traffic on
- * the new transform; however, when applying a transform in the inbound direction, traffic
- * on the old transform will continue to be decrypted and delivered until that transform is
- * deallocated by calling {@link IpSecTransform#close()}. This overlap allows lossless rekey
- * procedures where both transforms are valid until both endpoints are using the new transform
- * and all in-flight packets have been received.
- *
- * @param socket a datagram socket
- * @param direction the direction in which the transform should be applied
- * @param transform a transport mode {@code IpSecTransform}
- * @throws IOException indicating that the transform could not be applied
- */
- public void applyTransportModeTransform(@NonNull DatagramSocket socket,
- @PolicyDirection int direction, @NonNull IpSecTransform transform) throws IOException {
- applyTransportModeTransform(socket.getFileDescriptor$(), direction, transform);
- }
-
- /**
- * Apply an IPsec transform to a socket.
- *
- * <p>This applies transport mode encapsulation to the given socket. Once applied, I/O on the
- * socket will be encapsulated according to the parameters of the {@code IpSecTransform}. When
- * the transform is removed from the socket by calling {@link #removeTransportModeTransforms},
- * unprotected traffic can resume on that socket.
- *
- * <p>For security reasons, the destination address of any traffic on the socket must match the
- * remote {@code InetAddress} of the {@code IpSecTransform}. Attempts to send traffic to any
- * other IP address will result in an IOException. In addition, reads and writes on the socket
- * will throw IOException if the user deactivates the transform (by calling {@link
- * IpSecTransform#close()}) without calling {@link #removeTransportModeTransforms}.
- *
- * <p>Note that when applied to TCP sockets, calling {@link IpSecTransform#close()} on an
- * applied transform before completion of graceful shutdown may result in the shutdown sequence
- * failing to complete. As such, applications requiring graceful shutdown MUST close the socket
- * prior to deactivating the applied transform. Socket closure may be performed asynchronously
- * (in batches), so the returning of a close function does not guarantee shutdown of a socket.
- * Setting an SO_LINGER timeout results in socket closure being performed synchronously, and is
- * sufficient to ensure shutdown.
- *
- * Specifically, if the transform is deactivated (by calling {@link IpSecTransform#close()}),
- * prior to the socket being closed, the standard [FIN - FIN/ACK - ACK], or the reset [RST]
- * packets are dropped due to the lack of a valid Transform. Similarly, if a socket without the
- * SO_LINGER option set is closed, the delayed/batched FIN packets may be dropped.
- *
- * <h4>Rekey Procedure</h4>
- *
- * <p>When applying a new tranform to a socket in the outbound direction, the previous transform
- * will be removed and the new transform will take effect immediately, sending all traffic on
- * the new transform; however, when applying a transform in the inbound direction, traffic
- * on the old transform will continue to be decrypted and delivered until that transform is
- * deallocated by calling {@link IpSecTransform#close()}. This overlap allows lossless rekey
- * procedures where both transforms are valid until both endpoints are using the new transform
- * and all in-flight packets have been received.
- *
- * @param socket a socket file descriptor
- * @param direction the direction in which the transform should be applied
- * @param transform a transport mode {@code IpSecTransform}
- * @throws IOException indicating that the transform could not be applied
- */
- public void applyTransportModeTransform(@NonNull FileDescriptor socket,
- @PolicyDirection int direction, @NonNull IpSecTransform transform) throws IOException {
- // We dup() the FileDescriptor here because if we don't, then the ParcelFileDescriptor()
- // constructor takes control and closes the user's FD when we exit the method.
- try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(socket)) {
- mService.applyTransportModeTransform(pfd, direction, transform.getResourceId());
- } catch (ServiceSpecificException e) {
- throw rethrowCheckedExceptionFromServiceSpecificException(e);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Remove an IPsec transform from a stream socket.
- *
- * <p>Once removed, traffic on the socket will not be encrypted. Removing transforms from a
- * socket allows the socket to be reused for communication in the clear.
- *
- * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling
- * {@link IpSecTransform#close()}, then communication on the socket will fail until this method
- * is called.
- *
- * @param socket a socket that previously had a transform applied to it
- * @throws IOException indicating that the transform could not be removed from the socket
- */
- public void removeTransportModeTransforms(@NonNull Socket socket) throws IOException {
- // Ensure creation of FD. See b/77548890 for more details.
- socket.getSoLinger();
-
- removeTransportModeTransforms(socket.getFileDescriptor$());
- }
-
- /**
- * Remove an IPsec transform from a datagram socket.
- *
- * <p>Once removed, traffic on the socket will not be encrypted. Removing transforms from a
- * socket allows the socket to be reused for communication in the clear.
- *
- * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling
- * {@link IpSecTransform#close()}, then communication on the socket will fail until this method
- * is called.
- *
- * @param socket a socket that previously had a transform applied to it
- * @throws IOException indicating that the transform could not be removed from the socket
- */
- public void removeTransportModeTransforms(@NonNull DatagramSocket socket) throws IOException {
- removeTransportModeTransforms(socket.getFileDescriptor$());
- }
-
- /**
- * Remove an IPsec transform from a socket.
- *
- * <p>Once removed, traffic on the socket will not be encrypted. Removing transforms from a
- * socket allows the socket to be reused for communication in the clear.
- *
- * <p>If an {@code IpSecTransform} object applied to this socket was deallocated by calling
- * {@link IpSecTransform#close()}, then communication on the socket will fail until this method
- * is called.
- *
- * @param socket a socket that previously had a transform applied to it
- * @throws IOException indicating that the transform could not be removed from the socket
- */
- public void removeTransportModeTransforms(@NonNull FileDescriptor socket) throws IOException {
- try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(socket)) {
- mService.removeTransportModeTransforms(pfd);
- } catch (ServiceSpecificException e) {
- throw rethrowCheckedExceptionFromServiceSpecificException(e);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Remove a Tunnel Mode IPsec Transform from a {@link Network}. This must be used as part of
- * cleanup if a tunneled Network experiences a change in default route. The Network will drop
- * all traffic that cannot be routed to the Tunnel's outbound interface. If that interface is
- * lost, all traffic will drop.
- *
- * <p>TODO: Update javadoc for tunnel mode APIs at the same time the APIs are re-worked.
- *
- * @param net a network that currently has transform applied to it.
- * @param transform a Tunnel Mode IPsec Transform that has been previously applied to the given
- * network
- * @hide
- */
- public void removeTunnelModeTransform(Network net, IpSecTransform transform) {}
-
- /**
- * This class provides access to a UDP encapsulation Socket.
- *
- * <p>{@code UdpEncapsulationSocket} wraps a system-provided datagram socket intended for IKEv2
- * signalling and UDP encapsulated IPsec traffic. Instances can be obtained by calling {@link
- * IpSecManager#openUdpEncapsulationSocket}. The provided socket cannot be re-bound by the
- * caller. The caller should not close the {@code FileDescriptor} returned by {@link
- * #getFileDescriptor}, but should use {@link #close} instead.
- *
- * <p>Allowing the user to close or unbind a UDP encapsulation socket could impact the traffic
- * of the next user who binds to that port. To prevent this scenario, these sockets are held
- * open by the system so that they may only be closed by calling {@link #close} or when the user
- * process exits.
- */
- public static final class UdpEncapsulationSocket implements AutoCloseable {
- private final ParcelFileDescriptor mPfd;
- private final IIpSecService mService;
- private int mResourceId = INVALID_RESOURCE_ID;
- private final int mPort;
- private final CloseGuard mCloseGuard = CloseGuard.get();
-
- private UdpEncapsulationSocket(@NonNull IIpSecService service, int port)
- throws ResourceUnavailableException, IOException {
- mService = service;
- try {
- IpSecUdpEncapResponse result =
- mService.openUdpEncapsulationSocket(port, new Binder());
- switch (result.status) {
- case Status.OK:
- break;
- case Status.RESOURCE_UNAVAILABLE:
- throw new ResourceUnavailableException(
- "No more Sockets may be allocated by this requester.");
- default:
- throw new RuntimeException(
- "Unknown status returned by IpSecService: " + result.status);
- }
- mResourceId = result.resourceId;
- mPort = result.port;
- mPfd = result.fileDescriptor;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- mCloseGuard.open("constructor");
- }
-
- /** Get the encapsulation socket's file descriptor. */
- public FileDescriptor getFileDescriptor() {
- if (mPfd == null) {
- return null;
- }
- return mPfd.getFileDescriptor();
- }
-
- /** Get the bound port of the wrapped socket. */
- public int getPort() {
- return mPort;
- }
-
- /**
- * Close this socket.
- *
- * <p>This closes the wrapped socket. Open encapsulation sockets count against a user's
- * resource limits, and forgetting to close them eventually will result in {@link
- * ResourceUnavailableException} being thrown.
- */
- @Override
- public void close() throws IOException {
- try {
- mService.closeUdpEncapsulationSocket(mResourceId);
- mResourceId = INVALID_RESOURCE_ID;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- } catch (Exception e) {
- // On close we swallow all random exceptions since failure to close is not
- // actionable by the user.
- Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
- } finally {
- mResourceId = INVALID_RESOURCE_ID;
- mCloseGuard.close();
- }
-
- try {
- mPfd.close();
- } catch (IOException e) {
- Log.e(TAG, "Failed to close UDP Encapsulation Socket with Port= " + mPort);
- throw e;
- }
- }
-
- /** Check that the socket was closed properly. */
- @Override
- protected void finalize() throws Throwable {
- if (mCloseGuard != null) {
- mCloseGuard.warnIfOpen();
- }
- close();
- }
-
- /** @hide */
- @SystemApi(client = MODULE_LIBRARIES)
- public int getResourceId() {
- return mResourceId;
- }
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("UdpEncapsulationSocket{port=")
- .append(mPort)
- .append(",resourceId=")
- .append(mResourceId)
- .append("}")
- .toString();
- }
- };
-
- /**
- * Open a socket for UDP encapsulation and bind to the given port.
- *
- * <p>See {@link UdpEncapsulationSocket} for the proper way to close the returned socket.
- *
- * @param port a local UDP port
- * @return a socket that is bound to the given port
- * @throws IOException indicating that the socket could not be opened or bound
- * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open
- */
- // Returning a socket in this fashion that has been created and bound by the system
- // is the only safe way to ensure that a socket is both accessible to the user and
- // safely usable for Encapsulation without allowing a user to possibly unbind from/close
- // the port, which could potentially impact the traffic of the next user who binds to that
- // socket.
- @NonNull
- public UdpEncapsulationSocket openUdpEncapsulationSocket(int port)
- throws IOException, ResourceUnavailableException {
- /*
- * Most range checking is done in the service, but this version of the constructor expects
- * a valid port number, and zero cannot be checked after being passed to the service.
- */
- if (port == 0) {
- throw new IllegalArgumentException("Specified port must be a valid port number!");
- }
- try {
- return new UdpEncapsulationSocket(mService, port);
- } catch (ServiceSpecificException e) {
- throw rethrowCheckedExceptionFromServiceSpecificException(e);
- }
- }
-
- /**
- * Open a socket for UDP encapsulation.
- *
- * <p>See {@link UdpEncapsulationSocket} for the proper way to close the returned socket.
- *
- * <p>The local port of the returned socket can be obtained by calling {@link
- * UdpEncapsulationSocket#getPort()}.
- *
- * @return a socket that is bound to a local port
- * @throws IOException indicating that the socket could not be opened or bound
- * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open
- */
- // Returning a socket in this fashion that has been created and bound by the system
- // is the only safe way to ensure that a socket is both accessible to the user and
- // safely usable for Encapsulation without allowing a user to possibly unbind from/close
- // the port, which could potentially impact the traffic of the next user who binds to that
- // socket.
- @NonNull
- public UdpEncapsulationSocket openUdpEncapsulationSocket()
- throws IOException, ResourceUnavailableException {
- try {
- return new UdpEncapsulationSocket(mService, 0);
- } catch (ServiceSpecificException e) {
- throw rethrowCheckedExceptionFromServiceSpecificException(e);
- }
- }
-
- /**
- * This class represents an IpSecTunnelInterface
- *
- * <p>IpSecTunnelInterface objects track tunnel interfaces that serve as
- * local endpoints for IPsec tunnels.
- *
- * <p>Creating an IpSecTunnelInterface creates a device to which IpSecTransforms may be
- * applied to provide IPsec security to packets sent through the tunnel. While a tunnel
- * cannot be used in standalone mode within Android, the higher layers may use the tunnel
- * to create Network objects which are accessible to the Android system.
- * @hide
- */
- @SystemApi
- public static final class IpSecTunnelInterface implements AutoCloseable {
- private final String mOpPackageName;
- private final IIpSecService mService;
- private final InetAddress mRemoteAddress;
- private final InetAddress mLocalAddress;
- private final Network mUnderlyingNetwork;
- private final CloseGuard mCloseGuard = CloseGuard.get();
- private String mInterfaceName;
- private int mResourceId = INVALID_RESOURCE_ID;
-
- /** Get the underlying SPI held by this object. */
- @NonNull
- public String getInterfaceName() {
- return mInterfaceName;
- }
-
- /**
- * Add an address to the IpSecTunnelInterface
- *
- * <p>Add an address which may be used as the local inner address for
- * tunneled traffic.
- *
- * @param address the local address for traffic inside the tunnel
- * @param prefixLen length of the InetAddress prefix
- * @hide
- */
- @SystemApi
- @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
- @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
- public void addAddress(@NonNull InetAddress address, int prefixLen) throws IOException {
- try {
- mService.addAddressToTunnelInterface(
- mResourceId, new LinkAddress(address, prefixLen), mOpPackageName);
- } catch (ServiceSpecificException e) {
- throw rethrowCheckedExceptionFromServiceSpecificException(e);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Remove an address from the IpSecTunnelInterface
- *
- * <p>Remove an address which was previously added to the IpSecTunnelInterface
- *
- * @param address to be removed
- * @param prefixLen length of the InetAddress prefix
- * @hide
- */
- @SystemApi
- @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
- @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
- public void removeAddress(@NonNull InetAddress address, int prefixLen) throws IOException {
- try {
- mService.removeAddressFromTunnelInterface(
- mResourceId, new LinkAddress(address, prefixLen), mOpPackageName);
- } catch (ServiceSpecificException e) {
- throw rethrowCheckedExceptionFromServiceSpecificException(e);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Update the underlying network for this IpSecTunnelInterface.
- *
- * <p>This new underlying network will be used for all transforms applied AFTER this call is
- * complete. Before new {@link IpSecTransform}(s) with matching addresses are applied to
- * this tunnel interface, traffic will still use the old SA, and be routed on the old
- * underlying network.
- *
- * <p>To migrate IPsec tunnel mode traffic, a caller should:
- *
- * <ol>
- * <li>Update the IpSecTunnelInterface’s underlying network.
- * <li>Apply {@link IpSecTransform}(s) with matching addresses to this
- * IpSecTunnelInterface.
- * </ol>
- *
- * @param underlyingNetwork the new {@link Network} that will carry traffic for this tunnel.
- * This network MUST never be the network exposing this IpSecTunnelInterface, otherwise
- * this method will throw an {@link IllegalArgumentException}. If the
- * IpSecTunnelInterface is later added to this network, all outbound traffic will be
- * blackholed.
- */
- // TODO: b/169171001 Update the documentation when transform migration is supported.
- // The purpose of making updating network and applying transforms separate is to leave open
- // the possibility to support lossless migration procedures. To do that, Android platform
- // will need to support multiple inbound tunnel mode transforms, just like it can support
- // multiple transport mode transforms.
- @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
- @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
- public void setUnderlyingNetwork(@NonNull Network underlyingNetwork) throws IOException {
- try {
- mService.setNetworkForTunnelInterface(
- mResourceId, underlyingNetwork, mOpPackageName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- private IpSecTunnelInterface(@NonNull Context ctx, @NonNull IIpSecService service,
- @NonNull InetAddress localAddress, @NonNull InetAddress remoteAddress,
- @NonNull Network underlyingNetwork)
- throws ResourceUnavailableException, IOException {
- mOpPackageName = ctx.getOpPackageName();
- mService = service;
- mLocalAddress = localAddress;
- mRemoteAddress = remoteAddress;
- mUnderlyingNetwork = underlyingNetwork;
-
- try {
- IpSecTunnelInterfaceResponse result =
- mService.createTunnelInterface(
- localAddress.getHostAddress(),
- remoteAddress.getHostAddress(),
- underlyingNetwork,
- new Binder(),
- mOpPackageName);
- switch (result.status) {
- case Status.OK:
- break;
- case Status.RESOURCE_UNAVAILABLE:
- throw new ResourceUnavailableException(
- "No more tunnel interfaces may be allocated by this requester.");
- default:
- throw new RuntimeException(
- "Unknown status returned by IpSecService: " + result.status);
- }
- mResourceId = result.resourceId;
- mInterfaceName = result.interfaceName;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- mCloseGuard.open("constructor");
- }
-
- /**
- * Delete an IpSecTunnelInterface
- *
- * <p>Calling close will deallocate the IpSecTunnelInterface and all of its system
- * resources. Any packets bound for this interface either inbound or outbound will
- * all be lost.
- */
- @Override
- public void close() {
- try {
- mService.deleteTunnelInterface(mResourceId, mOpPackageName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- } catch (Exception e) {
- // On close we swallow all random exceptions since failure to close is not
- // actionable by the user.
- Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
- } finally {
- mResourceId = INVALID_RESOURCE_ID;
- mCloseGuard.close();
- }
- }
-
- /** Check that the Interface was closed properly. */
- @Override
- protected void finalize() throws Throwable {
- if (mCloseGuard != null) {
- mCloseGuard.warnIfOpen();
- }
- close();
- }
-
- /** @hide */
- @VisibleForTesting
- public int getResourceId() {
- return mResourceId;
- }
-
- @NonNull
- @Override
- public String toString() {
- return new StringBuilder()
- .append("IpSecTunnelInterface{ifname=")
- .append(mInterfaceName)
- .append(",resourceId=")
- .append(mResourceId)
- .append("}")
- .toString();
- }
- }
-
- /**
- * Create a new IpSecTunnelInterface as a local endpoint for tunneled IPsec traffic.
- *
- * <p>An application that creates tunnels is responsible for cleaning up the tunnel when the
- * underlying network goes away, and the onLost() callback is received.
- *
- * @param localAddress The local addres of the tunnel
- * @param remoteAddress The local addres of the tunnel
- * @param underlyingNetwork the {@link Network} that will carry traffic for this tunnel.
- * This network should almost certainly be a network such as WiFi with an L2 address.
- * @return a new {@link IpSecManager#IpSecTunnelInterface} with the specified properties
- * @throws IOException indicating that the socket could not be opened or bound
- * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open
- * @hide
- */
- @SystemApi
- @NonNull
- @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
- @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
- public IpSecTunnelInterface createIpSecTunnelInterface(@NonNull InetAddress localAddress,
- @NonNull InetAddress remoteAddress, @NonNull Network underlyingNetwork)
- throws ResourceUnavailableException, IOException {
- try {
- return new IpSecTunnelInterface(
- mContext, mService, localAddress, remoteAddress, underlyingNetwork);
- } catch (ServiceSpecificException e) {
- throw rethrowCheckedExceptionFromServiceSpecificException(e);
- }
- }
-
- /**
- * Apply an active Tunnel Mode IPsec Transform to a {@link IpSecTunnelInterface}, which will
- * tunnel all traffic for the given direction through the underlying network's interface with
- * IPsec (applies an outer IP header and IPsec Header to all traffic, and expects an additional
- * IP header and IPsec Header on all inbound traffic).
- * <p>Applications should probably not use this API directly.
- *
- *
- * @param tunnel The {@link IpSecManager#IpSecTunnelInterface} that will use the supplied
- * transform.
- * @param direction the direction, {@link DIRECTION_OUT} or {@link #DIRECTION_IN} in which
- * the transform will be used.
- * @param transform an {@link IpSecTransform} created in tunnel mode
- * @throws IOException indicating that the transform could not be applied due to a lower
- * layer failure.
- * @hide
- */
- @SystemApi
- @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
- @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
- public void applyTunnelModeTransform(@NonNull IpSecTunnelInterface tunnel,
- @PolicyDirection int direction, @NonNull IpSecTransform transform) throws IOException {
- try {
- mService.applyTunnelModeTransform(
- tunnel.getResourceId(), direction,
- transform.getResourceId(), mContext.getOpPackageName());
- } catch (ServiceSpecificException e) {
- throw rethrowCheckedExceptionFromServiceSpecificException(e);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * @hide
- */
- public IpSecTransformResponse createTransform(IpSecConfig config, IBinder binder,
- String callingPackage) {
- try {
- return mService.createTransform(config, binder, callingPackage);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * @hide
- */
- public void deleteTransform(int resourceId) {
- try {
- mService.deleteTransform(resourceId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Construct an instance of IpSecManager within an application context.
- *
- * @param context the application context for this manager
- * @hide
- */
- public IpSecManager(Context ctx, IIpSecService service) {
- mContext = ctx;
- mService = Objects.requireNonNull(service, "missing service");
- }
-
- private static void maybeHandleServiceSpecificException(ServiceSpecificException sse) {
- // OsConstants are late binding, so switch statements can't be used.
- if (sse.errorCode == OsConstants.EINVAL) {
- throw new IllegalArgumentException(sse);
- } else if (sse.errorCode == OsConstants.EAGAIN) {
- throw new IllegalStateException(sse);
- } else if (sse.errorCode == OsConstants.EOPNOTSUPP
- || sse.errorCode == OsConstants.EPROTONOSUPPORT) {
- throw new UnsupportedOperationException(sse);
- }
- }
-
- /**
- * Convert an Errno SSE to the correct Unchecked exception type.
- *
- * This method never actually returns.
- */
- // package
- static RuntimeException
- rethrowUncheckedExceptionFromServiceSpecificException(ServiceSpecificException sse) {
- maybeHandleServiceSpecificException(sse);
- throw new RuntimeException(sse);
- }
-
- /**
- * Convert an Errno SSE to the correct Checked or Unchecked exception type.
- *
- * This method may throw IOException, or it may throw an unchecked exception; it will never
- * actually return.
- */
- // package
- static IOException rethrowCheckedExceptionFromServiceSpecificException(
- ServiceSpecificException sse) throws IOException {
- // First see if this is an unchecked exception of a type we know.
- // If so, then we prefer the unchecked (specific) type of exception.
- maybeHandleServiceSpecificException(sse);
- // If not, then all we can do is provide the SSE in the form of an IOException.
- throw new ErrnoException(
- "IpSec encountered errno=" + sse.errorCode, sse.errorCode).rethrowAsIOException();
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecSpiResponse.aidl b/packages/ConnectivityT/framework-t/src/android/net/IpSecSpiResponse.aidl
deleted file mode 100644
index 6484a00..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecSpiResponse.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-/** @hide */
-parcelable IpSecSpiResponse;
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecSpiResponse.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecSpiResponse.java
deleted file mode 100644
index f99e570..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecSpiResponse.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * This class is used to return an SPI and corresponding status from the IpSecService to an
- * IpSecManager.SecurityParameterIndex.
- *
- * @hide
- */
-public final class IpSecSpiResponse implements Parcelable {
- private static final String TAG = "IpSecSpiResponse";
-
- public final int resourceId;
- public final int status;
- public final int spi;
- // Parcelable Methods
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(status);
- out.writeInt(resourceId);
- out.writeInt(spi);
- }
-
- public IpSecSpiResponse(int inStatus, int inResourceId, int inSpi) {
- status = inStatus;
- resourceId = inResourceId;
- spi = inSpi;
- }
-
- public IpSecSpiResponse(int inStatus) {
- if (inStatus == IpSecManager.Status.OK) {
- throw new IllegalArgumentException("Valid status implies other args must be provided");
- }
- status = inStatus;
- resourceId = IpSecManager.INVALID_RESOURCE_ID;
- spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
- }
-
- private IpSecSpiResponse(Parcel in) {
- status = in.readInt();
- resourceId = in.readInt();
- spi = in.readInt();
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<IpSecSpiResponse> CREATOR =
- new Parcelable.Creator<IpSecSpiResponse>() {
- public IpSecSpiResponse createFromParcel(Parcel in) {
- return new IpSecSpiResponse(in);
- }
-
- public IpSecSpiResponse[] newArray(int size) {
- return new IpSecSpiResponse[size];
- }
- };
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecTransform.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecTransform.java
deleted file mode 100644
index 68ae5de..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecTransform.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net;
-
-import static android.net.IpSecManager.INVALID_RESOURCE_ID;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresFeature;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.os.ServiceSpecificException;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import dalvik.system.CloseGuard;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.InetAddress;
-import java.util.Objects;
-
-/**
- * This class represents a transform, which roughly corresponds to an IPsec Security Association.
- *
- * <p>Transforms are created using {@link IpSecTransform.Builder}. Each {@code IpSecTransform}
- * object encapsulates the properties and state of an IPsec security association. That includes,
- * but is not limited to, algorithm choice, key material, and allocated system resources.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4301">RFC 4301, Security Architecture for the
- * Internet Protocol</a>
- */
-public final class IpSecTransform implements AutoCloseable {
- private static final String TAG = "IpSecTransform";
-
- /** @hide */
- public static final int MODE_TRANSPORT = 0;
-
- /** @hide */
- public static final int MODE_TUNNEL = 1;
-
- /** @hide */
- public static final int ENCAP_NONE = 0;
-
- /**
- * IPsec traffic will be encapsulated within UDP, but with 8 zero-value bytes between the UDP
- * header and payload. This prevents traffic from being interpreted as ESP or IKEv2.
- *
- * @hide
- */
- public static final int ENCAP_ESPINUDP_NON_IKE = 1;
-
- /**
- * IPsec traffic will be encapsulated within UDP as per
- * <a href="https://tools.ietf.org/html/rfc3948">RFC 3498</a>.
- *
- * @hide
- */
- public static final int ENCAP_ESPINUDP = 2;
-
- /** @hide */
- @IntDef(value = {ENCAP_NONE, ENCAP_ESPINUDP, ENCAP_ESPINUDP_NON_IKE})
- @Retention(RetentionPolicy.SOURCE)
- public @interface EncapType {}
-
- /** @hide */
- @VisibleForTesting
- public IpSecTransform(Context context, IpSecConfig config) {
- mContext = context;
- mConfig = new IpSecConfig(config);
- mResourceId = INVALID_RESOURCE_ID;
- }
-
- private IpSecManager getIpSecManager(Context context) {
- return context.getSystemService(IpSecManager.class);
- }
- /**
- * Checks the result status and throws an appropriate exception if the status is not Status.OK.
- */
- private void checkResultStatus(int status)
- throws IOException, IpSecManager.ResourceUnavailableException,
- IpSecManager.SpiUnavailableException {
- switch (status) {
- case IpSecManager.Status.OK:
- return;
- // TODO: Pass Error string back from bundle so that errors can be more specific
- case IpSecManager.Status.RESOURCE_UNAVAILABLE:
- throw new IpSecManager.ResourceUnavailableException(
- "Failed to allocate a new IpSecTransform");
- case IpSecManager.Status.SPI_UNAVAILABLE:
- Log.wtf(TAG, "Attempting to use an SPI that was somehow not reserved");
- // Fall through
- default:
- throw new IllegalStateException(
- "Failed to Create a Transform with status code " + status);
- }
- }
-
- private IpSecTransform activate()
- throws IOException, IpSecManager.ResourceUnavailableException,
- IpSecManager.SpiUnavailableException {
- synchronized (this) {
- try {
- IpSecTransformResponse result = getIpSecManager(mContext).createTransform(
- mConfig, new Binder(), mContext.getOpPackageName());
- int status = result.status;
- checkResultStatus(status);
- mResourceId = result.resourceId;
- Log.d(TAG, "Added Transform with Id " + mResourceId);
- mCloseGuard.open("build");
- } catch (ServiceSpecificException e) {
- throw IpSecManager.rethrowUncheckedExceptionFromServiceSpecificException(e);
- }
- }
-
- return this;
- }
-
- /**
- * Standard equals.
- */
- public boolean equals(@Nullable Object other) {
- if (this == other) return true;
- if (!(other instanceof IpSecTransform)) return false;
- final IpSecTransform rhs = (IpSecTransform) other;
- return getConfig().equals(rhs.getConfig()) && mResourceId == rhs.mResourceId;
- }
-
- /**
- * Deactivate this {@code IpSecTransform} and free allocated resources.
- *
- * <p>Deactivating a transform while it is still applied to a socket will result in errors on
- * that socket. Make sure to remove transforms by calling {@link
- * IpSecManager#removeTransportModeTransforms}. Note, removing an {@code IpSecTransform} from a
- * socket will not deactivate it (because one transform may be applied to multiple sockets).
- *
- * <p>It is safe to call this method on a transform that has already been deactivated.
- */
- public void close() {
- Log.d(TAG, "Removing Transform with Id " + mResourceId);
-
- // Always safe to attempt cleanup
- if (mResourceId == INVALID_RESOURCE_ID) {
- mCloseGuard.close();
- return;
- }
- try {
- getIpSecManager(mContext).deleteTransform(mResourceId);
- } catch (Exception e) {
- // On close we swallow all random exceptions since failure to close is not
- // actionable by the user.
- Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
- } finally {
- mResourceId = INVALID_RESOURCE_ID;
- mCloseGuard.close();
- }
- }
-
- /** Check that the transform was closed properly. */
- @Override
- protected void finalize() throws Throwable {
- if (mCloseGuard != null) {
- mCloseGuard.warnIfOpen();
- }
- close();
- }
-
- /* Package */
- IpSecConfig getConfig() {
- return mConfig;
- }
-
- private final IpSecConfig mConfig;
- private int mResourceId;
- private final Context mContext;
- private final CloseGuard mCloseGuard = CloseGuard.get();
-
- /** @hide */
- @VisibleForTesting
- public int getResourceId() {
- return mResourceId;
- }
-
- /**
- * A callback class to provide status information regarding a NAT-T keepalive session
- *
- * <p>Use this callback to receive status information regarding a NAT-T keepalive session
- * by registering it when calling {@link #startNattKeepalive}.
- *
- * @hide
- */
- public static class NattKeepaliveCallback {
- /** The specified {@code Network} is not connected. */
- public static final int ERROR_INVALID_NETWORK = 1;
- /** The hardware does not support this request. */
- public static final int ERROR_HARDWARE_UNSUPPORTED = 2;
- /** The hardware returned an error. */
- public static final int ERROR_HARDWARE_ERROR = 3;
-
- /** The requested keepalive was successfully started. */
- public void onStarted() {}
- /** The keepalive was successfully stopped. */
- public void onStopped() {}
- /** An error occurred. */
- public void onError(int error) {}
- }
-
- /** This class is used to build {@link IpSecTransform} objects. */
- public static class Builder {
- private Context mContext;
- private IpSecConfig mConfig;
-
- /**
- * Set the encryption algorithm.
- *
- * <p>Encryption is mutually exclusive with authenticated encryption.
- *
- * @param algo {@link IpSecAlgorithm} specifying the encryption to be applied.
- */
- @NonNull
- public IpSecTransform.Builder setEncryption(@NonNull IpSecAlgorithm algo) {
- // TODO: throw IllegalArgumentException if algo is not an encryption algorithm.
- Objects.requireNonNull(algo);
- mConfig.setEncryption(algo);
- return this;
- }
-
- /**
- * Set the authentication (integrity) algorithm.
- *
- * <p>Authentication is mutually exclusive with authenticated encryption.
- *
- * @param algo {@link IpSecAlgorithm} specifying the authentication to be applied.
- */
- @NonNull
- public IpSecTransform.Builder setAuthentication(@NonNull IpSecAlgorithm algo) {
- // TODO: throw IllegalArgumentException if algo is not an authentication algorithm.
- Objects.requireNonNull(algo);
- mConfig.setAuthentication(algo);
- return this;
- }
-
- /**
- * Set the authenticated encryption algorithm.
- *
- * <p>The Authenticated Encryption (AE) class of algorithms are also known as
- * Authenticated Encryption with Associated Data (AEAD) algorithms, or Combined mode
- * algorithms (as referred to in
- * <a href="https://tools.ietf.org/html/rfc4301">RFC 4301</a>).
- *
- * <p>Authenticated encryption is mutually exclusive with encryption and authentication.
- *
- * @param algo {@link IpSecAlgorithm} specifying the authenticated encryption algorithm to
- * be applied.
- */
- @NonNull
- public IpSecTransform.Builder setAuthenticatedEncryption(@NonNull IpSecAlgorithm algo) {
- Objects.requireNonNull(algo);
- mConfig.setAuthenticatedEncryption(algo);
- return this;
- }
-
- /**
- * Add UDP encapsulation to an IPv4 transform.
- *
- * <p>This allows IPsec traffic to pass through a NAT.
- *
- * @see <a href="https://tools.ietf.org/html/rfc3948">RFC 3948, UDP Encapsulation of IPsec
- * ESP Packets</a>
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.23">RFC 7296 section 2.23,
- * NAT Traversal of IKEv2</a>
- * @param localSocket a socket for sending and receiving encapsulated traffic
- * @param remotePort the UDP port number of the remote host that will send and receive
- * encapsulated traffic. In the case of IKEv2, this should be port 4500.
- */
- @NonNull
- public IpSecTransform.Builder setIpv4Encapsulation(
- @NonNull IpSecManager.UdpEncapsulationSocket localSocket, int remotePort) {
- Objects.requireNonNull(localSocket);
- mConfig.setEncapType(ENCAP_ESPINUDP);
- if (localSocket.getResourceId() == INVALID_RESOURCE_ID) {
- throw new IllegalArgumentException("Invalid UdpEncapsulationSocket");
- }
- mConfig.setEncapSocketResourceId(localSocket.getResourceId());
- mConfig.setEncapRemotePort(remotePort);
- return this;
- }
-
- /**
- * Build a transport mode {@link IpSecTransform}.
- *
- * <p>This builds and activates a transport mode transform. Note that an active transform
- * will not affect any network traffic until it has been applied to one or more sockets.
- *
- * @see IpSecManager#applyTransportModeTransform
- * @param sourceAddress the source {@code InetAddress} of traffic on sockets that will use
- * this transform; this address must belong to the Network used by all sockets that
- * utilize this transform; if provided, then only traffic originating from the
- * specified source address will be processed.
- * @param spi a unique {@link IpSecManager.SecurityParameterIndex} to identify transformed
- * traffic
- * @throws IllegalArgumentException indicating that a particular combination of transform
- * properties is invalid
- * @throws IpSecManager.ResourceUnavailableException indicating that too many transforms
- * are active
- * @throws IpSecManager.SpiUnavailableException indicating the rare case where an SPI
- * collides with an existing transform
- * @throws IOException indicating other errors
- */
- @NonNull
- public IpSecTransform buildTransportModeTransform(
- @NonNull InetAddress sourceAddress,
- @NonNull IpSecManager.SecurityParameterIndex spi)
- throws IpSecManager.ResourceUnavailableException,
- IpSecManager.SpiUnavailableException, IOException {
- Objects.requireNonNull(sourceAddress);
- Objects.requireNonNull(spi);
- if (spi.getResourceId() == INVALID_RESOURCE_ID) {
- throw new IllegalArgumentException("Invalid SecurityParameterIndex");
- }
- mConfig.setMode(MODE_TRANSPORT);
- mConfig.setSourceAddress(sourceAddress.getHostAddress());
- mConfig.setSpiResourceId(spi.getResourceId());
- // FIXME: modifying a builder after calling build can change the built transform.
- return new IpSecTransform(mContext, mConfig).activate();
- }
-
- /**
- * Build and return an {@link IpSecTransform} object as a Tunnel Mode Transform. Some
- * parameters have interdependencies that are checked at build time.
- *
- * @param sourceAddress the {@link InetAddress} that provides the source address for this
- * IPsec tunnel. This is almost certainly an address belonging to the {@link Network}
- * that will originate the traffic, which is set as the {@link #setUnderlyingNetwork}.
- * @param spi a unique {@link IpSecManager.SecurityParameterIndex} to identify transformed
- * traffic
- * @throws IllegalArgumentException indicating that a particular combination of transform
- * properties is invalid.
- * @throws IpSecManager.ResourceUnavailableException indicating that too many transforms
- * are active
- * @throws IpSecManager.SpiUnavailableException indicating the rare case where an SPI
- * collides with an existing transform
- * @throws IOException indicating other errors
- * @hide
- */
- @SystemApi
- @NonNull
- @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
- @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
- public IpSecTransform buildTunnelModeTransform(
- @NonNull InetAddress sourceAddress,
- @NonNull IpSecManager.SecurityParameterIndex spi)
- throws IpSecManager.ResourceUnavailableException,
- IpSecManager.SpiUnavailableException, IOException {
- Objects.requireNonNull(sourceAddress);
- Objects.requireNonNull(spi);
- if (spi.getResourceId() == INVALID_RESOURCE_ID) {
- throw new IllegalArgumentException("Invalid SecurityParameterIndex");
- }
- mConfig.setMode(MODE_TUNNEL);
- mConfig.setSourceAddress(sourceAddress.getHostAddress());
- mConfig.setSpiResourceId(spi.getResourceId());
- return new IpSecTransform(mContext, mConfig).activate();
- }
-
- /**
- * Create a new IpSecTransform.Builder.
- *
- * @param context current context
- */
- public Builder(@NonNull Context context) {
- Objects.requireNonNull(context);
- mContext = context;
- mConfig = new IpSecConfig();
- }
- }
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("IpSecTransform{resourceId=")
- .append(mResourceId)
- .append("}")
- .toString();
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecTransformResponse.aidl b/packages/ConnectivityT/framework-t/src/android/net/IpSecTransformResponse.aidl
deleted file mode 100644
index 546230d..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecTransformResponse.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-/** @hide */
-parcelable IpSecTransformResponse;
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecTransformResponse.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecTransformResponse.java
deleted file mode 100644
index 363f316..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecTransformResponse.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * This class is used to return an IpSecTransform resource Id and and corresponding status from the
- * IpSecService to an IpSecTransform object.
- *
- * @hide
- */
-public final class IpSecTransformResponse implements Parcelable {
- private static final String TAG = "IpSecTransformResponse";
-
- public final int resourceId;
- public final int status;
- // Parcelable Methods
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(status);
- out.writeInt(resourceId);
- }
-
- public IpSecTransformResponse(int inStatus) {
- if (inStatus == IpSecManager.Status.OK) {
- throw new IllegalArgumentException("Valid status implies other args must be provided");
- }
- status = inStatus;
- resourceId = IpSecManager.INVALID_RESOURCE_ID;
- }
-
- public IpSecTransformResponse(int inStatus, int inResourceId) {
- status = inStatus;
- resourceId = inResourceId;
- }
-
- private IpSecTransformResponse(Parcel in) {
- status = in.readInt();
- resourceId = in.readInt();
- }
-
- @android.annotation.NonNull
- public static final Parcelable.Creator<IpSecTransformResponse> CREATOR =
- new Parcelable.Creator<IpSecTransformResponse>() {
- public IpSecTransformResponse createFromParcel(Parcel in) {
- return new IpSecTransformResponse(in);
- }
-
- public IpSecTransformResponse[] newArray(int size) {
- return new IpSecTransformResponse[size];
- }
- };
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecTunnelInterfaceResponse.aidl b/packages/ConnectivityT/framework-t/src/android/net/IpSecTunnelInterfaceResponse.aidl
deleted file mode 100644
index 7239221..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecTunnelInterfaceResponse.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2018 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.net;
-
-/** @hide */
-parcelable IpSecTunnelInterfaceResponse;
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecTunnelInterfaceResponse.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecTunnelInterfaceResponse.java
deleted file mode 100644
index 127e30a..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecTunnelInterfaceResponse.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2018 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.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * This class is used to return an IpSecTunnelInterface resource Id and and corresponding status
- * from the IpSecService to an IpSecTunnelInterface object.
- *
- * @hide
- */
-public final class IpSecTunnelInterfaceResponse implements Parcelable {
- private static final String TAG = "IpSecTunnelInterfaceResponse";
-
- public final int resourceId;
- public final String interfaceName;
- public final int status;
- // Parcelable Methods
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(status);
- out.writeInt(resourceId);
- out.writeString(interfaceName);
- }
-
- public IpSecTunnelInterfaceResponse(int inStatus) {
- if (inStatus == IpSecManager.Status.OK) {
- throw new IllegalArgumentException("Valid status implies other args must be provided");
- }
- status = inStatus;
- resourceId = IpSecManager.INVALID_RESOURCE_ID;
- interfaceName = "";
- }
-
- public IpSecTunnelInterfaceResponse(int inStatus, int inResourceId, String inInterfaceName) {
- status = inStatus;
- resourceId = inResourceId;
- interfaceName = inInterfaceName;
- }
-
- private IpSecTunnelInterfaceResponse(Parcel in) {
- status = in.readInt();
- resourceId = in.readInt();
- interfaceName = in.readString();
- }
-
- @android.annotation.NonNull
- public static final Parcelable.Creator<IpSecTunnelInterfaceResponse> CREATOR =
- new Parcelable.Creator<IpSecTunnelInterfaceResponse>() {
- public IpSecTunnelInterfaceResponse createFromParcel(Parcel in) {
- return new IpSecTunnelInterfaceResponse(in);
- }
-
- public IpSecTunnelInterfaceResponse[] newArray(int size) {
- return new IpSecTunnelInterfaceResponse[size];
- }
- };
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.aidl b/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.aidl
deleted file mode 100644
index 5e451f3..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-/** @hide */
-parcelable IpSecUdpEncapResponse;
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java
deleted file mode 100644
index 390af82..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net;
-
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-/**
- * This class is used to return a UDP Socket and corresponding status from the IpSecService to an
- * IpSecManager.UdpEncapsulationSocket.
- *
- * @hide
- */
-public final class IpSecUdpEncapResponse implements Parcelable {
- private static final String TAG = "IpSecUdpEncapResponse";
-
- public final int resourceId;
- public final int port;
- public final int status;
- // There is a weird asymmetry with FileDescriptor: you can write a FileDescriptor
- // but you read a ParcelFileDescriptor. To circumvent this, when we receive a FD
- // from the user, we immediately create a ParcelFileDescriptor DUP, which we invalidate
- // on writeParcel() by setting the flag to do close-on-write.
- // TODO: tests to ensure this doesn't leak
- public final ParcelFileDescriptor fileDescriptor;
-
- // Parcelable Methods
-
- @Override
- public int describeContents() {
- return (fileDescriptor != null) ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(status);
- out.writeInt(resourceId);
- out.writeInt(port);
- out.writeParcelable(fileDescriptor, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- }
-
- public IpSecUdpEncapResponse(int inStatus) {
- if (inStatus == IpSecManager.Status.OK) {
- throw new IllegalArgumentException("Valid status implies other args must be provided");
- }
- status = inStatus;
- resourceId = IpSecManager.INVALID_RESOURCE_ID;
- port = -1;
- fileDescriptor = null; // yes I know it's redundant, but readability
- }
-
- public IpSecUdpEncapResponse(int inStatus, int inResourceId, int inPort, FileDescriptor inFd)
- throws IOException {
- if (inStatus == IpSecManager.Status.OK && inFd == null) {
- throw new IllegalArgumentException("Valid status implies FD must be non-null");
- }
- status = inStatus;
- resourceId = inResourceId;
- port = inPort;
- fileDescriptor = (status == IpSecManager.Status.OK) ? ParcelFileDescriptor.dup(inFd) : null;
- }
-
- private IpSecUdpEncapResponse(Parcel in) {
- status = in.readInt();
- resourceId = in.readInt();
- port = in.readInt();
- fileDescriptor = in.readParcelable(ParcelFileDescriptor.class.getClassLoader(), android.os.ParcelFileDescriptor.class);
- }
-
- @android.annotation.NonNull
- public static final Parcelable.Creator<IpSecUdpEncapResponse> CREATOR =
- new Parcelable.Creator<IpSecUdpEncapResponse>() {
- public IpSecUdpEncapResponse createFromParcel(Parcel in) {
- return new IpSecUdpEncapResponse(in);
- }
-
- public IpSecUdpEncapResponse[] newArray(int size) {
- return new IpSecUdpEncapResponse[size];
- }
- };
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
deleted file mode 100644
index da5f88d..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
+++ /dev/null
@@ -1,594 +0,0 @@
-/*
- * Copyright (C) 2011 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.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.app.usage.NetworkStatsManager;
-import android.content.Context;
-import android.net.wifi.WifiInfo;
-import android.service.NetworkIdentityProto;
-import android.telephony.TelephonyManager;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.net.module.util.CollectionUtils;
-import com.android.net.module.util.NetworkCapabilitiesUtils;
-import com.android.net.module.util.NetworkIdentityUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Objects;
-
-/**
- * Network definition that includes strong identity. Analogous to combining
- * {@link NetworkCapabilities} and an IMSI.
- *
- * @hide
- */
-@SystemApi(client = MODULE_LIBRARIES)
-public class NetworkIdentity {
- private static final String TAG = "NetworkIdentity";
-
- /** @hide */
- // TODO: Remove this after migrating all callers to use
- // {@link NetworkTemplate#NETWORK_TYPE_ALL} instead.
- public static final int SUBTYPE_COMBINED = -1;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "OEM_MANAGED_" }, flag = true, value = {
- NetworkTemplate.OEM_MANAGED_NO,
- NetworkTemplate.OEM_MANAGED_PAID,
- NetworkTemplate.OEM_MANAGED_PRIVATE
- })
- public @interface OemManaged{}
-
- /**
- * Network has no {@code NetworkCapabilities#NET_CAPABILITY_OEM_*}.
- * @hide
- */
- public static final int OEM_NONE = 0x0;
- /**
- * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}.
- * @hide
- */
- public static final int OEM_PAID = 1 << 0;
- /**
- * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}.
- * @hide
- */
- public static final int OEM_PRIVATE = 1 << 1;
-
- private static final long SUPPORTED_OEM_MANAGED_TYPES = OEM_PAID | OEM_PRIVATE;
-
- final int mType;
- final int mRatType;
- final int mSubId;
- final String mSubscriberId;
- final String mWifiNetworkKey;
- final boolean mRoaming;
- final boolean mMetered;
- final boolean mDefaultNetwork;
- final int mOemManaged;
-
- /** @hide */
- public NetworkIdentity(
- int type, int ratType, @Nullable String subscriberId, @Nullable String wifiNetworkKey,
- boolean roaming, boolean metered, boolean defaultNetwork, int oemManaged, int subId) {
- mType = type;
- mRatType = ratType;
- mSubscriberId = subscriberId;
- mWifiNetworkKey = wifiNetworkKey;
- mRoaming = roaming;
- mMetered = metered;
- mDefaultNetwork = defaultNetwork;
- mOemManaged = oemManaged;
- mSubId = subId;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mType, mRatType, mSubscriberId, mWifiNetworkKey, mRoaming, mMetered,
- mDefaultNetwork, mOemManaged, mSubId);
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (obj instanceof NetworkIdentity) {
- final NetworkIdentity ident = (NetworkIdentity) obj;
- return mType == ident.mType && mRatType == ident.mRatType && mRoaming == ident.mRoaming
- && Objects.equals(mSubscriberId, ident.mSubscriberId)
- && Objects.equals(mWifiNetworkKey, ident.mWifiNetworkKey)
- && mMetered == ident.mMetered
- && mDefaultNetwork == ident.mDefaultNetwork
- && mOemManaged == ident.mOemManaged
- && mSubId == ident.mSubId;
- }
- return false;
- }
-
- @Override
- public String toString() {
- final StringBuilder builder = new StringBuilder("{");
- builder.append("type=").append(mType);
- builder.append(", ratType=");
- if (mRatType == NETWORK_TYPE_ALL) {
- builder.append("COMBINED");
- } else {
- builder.append(mRatType);
- }
- if (mSubscriberId != null) {
- builder.append(", subscriberId=")
- .append(NetworkIdentityUtils.scrubSubscriberId(mSubscriberId));
- }
- if (mWifiNetworkKey != null) {
- builder.append(", wifiNetworkKey=").append(mWifiNetworkKey);
- }
- if (mRoaming) {
- builder.append(", ROAMING");
- }
- builder.append(", metered=").append(mMetered);
- builder.append(", defaultNetwork=").append(mDefaultNetwork);
- builder.append(", oemManaged=").append(getOemManagedNames(mOemManaged));
- builder.append(", subId=").append(mSubId);
- return builder.append("}").toString();
- }
-
- /**
- * Get the human readable representation of a bitfield representing the OEM managed state of a
- * network.
- */
- static String getOemManagedNames(int oemManaged) {
- if (oemManaged == OEM_NONE) {
- return "OEM_NONE";
- }
- final int[] bitPositions = NetworkCapabilitiesUtils.unpackBits(oemManaged);
- final ArrayList<String> oemManagedNames = new ArrayList<String>();
- for (int position : bitPositions) {
- oemManagedNames.add(nameOfOemManaged(1 << position));
- }
- return String.join(",", oemManagedNames);
- }
-
- private static String nameOfOemManaged(int oemManagedBit) {
- switch (oemManagedBit) {
- case OEM_PAID:
- return "OEM_PAID";
- case OEM_PRIVATE:
- return "OEM_PRIVATE";
- default:
- return "Invalid(" + oemManagedBit + ")";
- }
- }
-
- /** @hide */
- public void dumpDebug(ProtoOutputStream proto, long tag) {
- final long start = proto.start(tag);
-
- proto.write(NetworkIdentityProto.TYPE, mType);
-
- // TODO: dump mRatType as well.
-
- proto.write(NetworkIdentityProto.ROAMING, mRoaming);
- proto.write(NetworkIdentityProto.METERED, mMetered);
- proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork);
- proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged);
-
- proto.end(start);
- }
-
- /** Get the network type of this instance. */
- public int getType() {
- return mType;
- }
-
- /** Get the Radio Access Technology(RAT) type of this instance. */
- public int getRatType() {
- return mRatType;
- }
-
- /** Get the Subscriber Id of this instance. */
- @Nullable
- public String getSubscriberId() {
- return mSubscriberId;
- }
-
- /** Get the Wifi Network Key of this instance. See {@link WifiInfo#getNetworkKey()}. */
- @Nullable
- public String getWifiNetworkKey() {
- return mWifiNetworkKey;
- }
-
- /** @hide */
- // TODO: Remove this function after all callers are removed.
- public boolean getRoaming() {
- return mRoaming;
- }
-
- /** Return whether this network is roaming. */
- public boolean isRoaming() {
- return mRoaming;
- }
-
- /** @hide */
- // TODO: Remove this function after all callers are removed.
- public boolean getMetered() {
- return mMetered;
- }
-
- /** Return whether this network is metered. */
- public boolean isMetered() {
- return mMetered;
- }
-
- /** @hide */
- // TODO: Remove this function after all callers are removed.
- public boolean getDefaultNetwork() {
- return mDefaultNetwork;
- }
-
- /** Return whether this network is the default network. */
- public boolean isDefaultNetwork() {
- return mDefaultNetwork;
- }
-
- /** Get the OEM managed type of this instance. */
- public int getOemManaged() {
- return mOemManaged;
- }
-
- /** Get the SubId of this instance. */
- public int getSubId() {
- return mSubId;
- }
-
- /**
- * Assemble a {@link NetworkIdentity} from the passed arguments.
- *
- * This methods builds an identity based on the capabilities of the network in the
- * snapshot and other passed arguments. The identity is used as a key to record data usage.
- *
- * @param snapshot the snapshot of network state. See {@link NetworkStateSnapshot}.
- * @param defaultNetwork whether the network is a default network.
- * @param ratType the Radio Access Technology(RAT) type of the network. Or
- * {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if not applicable.
- * See {@code TelephonyManager.NETWORK_TYPE_*}.
- * @hide
- * @deprecated See {@link NetworkIdentity.Builder}.
- */
- // TODO: Remove this after all callers are migrated to use new Api.
- @Deprecated
- @NonNull
- public static NetworkIdentity buildNetworkIdentity(Context context,
- @NonNull NetworkStateSnapshot snapshot, boolean defaultNetwork, int ratType) {
- final NetworkIdentity.Builder builder = new NetworkIdentity.Builder()
- .setNetworkStateSnapshot(snapshot).setDefaultNetwork(defaultNetwork)
- .setSubId(snapshot.getSubId());
- if (snapshot.getLegacyType() == TYPE_MOBILE && ratType != NETWORK_TYPE_ALL) {
- builder.setRatType(ratType);
- }
- return builder.build();
- }
-
- /**
- * Builds a bitfield of {@code NetworkIdentity.OEM_*} based on {@link NetworkCapabilities}.
- * @hide
- */
- public static int getOemBitfield(@NonNull NetworkCapabilities nc) {
- int oemManaged = OEM_NONE;
-
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)) {
- oemManaged |= OEM_PAID;
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)) {
- oemManaged |= OEM_PRIVATE;
- }
-
- return oemManaged;
- }
-
- /** @hide */
- public static int compare(@NonNull NetworkIdentity left, @NonNull NetworkIdentity right) {
- Objects.requireNonNull(right);
- int res = Integer.compare(left.mType, right.mType);
- if (res == 0) {
- res = Integer.compare(left.mRatType, right.mRatType);
- }
- if (res == 0 && left.mSubscriberId != null && right.mSubscriberId != null) {
- res = left.mSubscriberId.compareTo(right.mSubscriberId);
- }
- if (res == 0 && left.mWifiNetworkKey != null && right.mWifiNetworkKey != null) {
- res = left.mWifiNetworkKey.compareTo(right.mWifiNetworkKey);
- }
- if (res == 0) {
- res = Boolean.compare(left.mRoaming, right.mRoaming);
- }
- if (res == 0) {
- res = Boolean.compare(left.mMetered, right.mMetered);
- }
- if (res == 0) {
- res = Boolean.compare(left.mDefaultNetwork, right.mDefaultNetwork);
- }
- if (res == 0) {
- res = Integer.compare(left.mOemManaged, right.mOemManaged);
- }
- if (res == 0) {
- res = Integer.compare(left.mSubId, right.mSubId);
- }
- return res;
- }
-
- /**
- * Builder class for {@link NetworkIdentity}.
- */
- public static final class Builder {
- // Need to be synchronized with ConnectivityManager.
- // TODO: Use {@link ConnectivityManager#MAX_NETWORK_TYPE} when this file is in the module.
- private static final int MAX_NETWORK_TYPE = 18; // TYPE_TEST
- private static final int MIN_NETWORK_TYPE = TYPE_MOBILE;
-
- private int mType;
- private int mRatType;
- private String mSubscriberId;
- private String mWifiNetworkKey;
- private boolean mRoaming;
- private boolean mMetered;
- private boolean mDefaultNetwork;
- private int mOemManaged;
- private int mSubId;
-
- /**
- * Creates a new Builder.
- */
- public Builder() {
- // Initialize with default values. Will be overwritten by setters.
- mType = ConnectivityManager.TYPE_NONE;
- mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
- mSubscriberId = null;
- mWifiNetworkKey = null;
- mRoaming = false;
- mMetered = false;
- mDefaultNetwork = false;
- mOemManaged = NetworkTemplate.OEM_MANAGED_NO;
- mSubId = INVALID_SUBSCRIPTION_ID;
- }
-
- /**
- * Add an {@link NetworkStateSnapshot} into the {@link NetworkIdentity} instance.
- * This is a useful shorthand that will read from the snapshot and set the
- * following fields, if they are set in the snapshot :
- * - type
- * - subscriberId
- * - roaming
- * - metered
- * - oemManaged
- * - wifiNetworkKey
- *
- * @param snapshot The target {@link NetworkStateSnapshot} object.
- * @return The builder object.
- */
- @SuppressLint("MissingGetterMatchingBuilder")
- @NonNull
- public Builder setNetworkStateSnapshot(@NonNull NetworkStateSnapshot snapshot) {
- setType(snapshot.getLegacyType());
-
- setSubscriberId(snapshot.getSubscriberId());
- setRoaming(!snapshot.getNetworkCapabilities().hasCapability(
- NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING));
- setMetered(!(snapshot.getNetworkCapabilities().hasCapability(
- NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
- || snapshot.getNetworkCapabilities().hasCapability(
- NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)));
-
- setOemManaged(getOemBitfield(snapshot.getNetworkCapabilities()));
-
- if (mType == TYPE_WIFI) {
- final TransportInfo transportInfo = snapshot.getNetworkCapabilities()
- .getTransportInfo();
- if (transportInfo instanceof WifiInfo) {
- final WifiInfo info = (WifiInfo) transportInfo;
- setWifiNetworkKey(info.getNetworkKey());
- }
- }
- return this;
- }
-
- /**
- * Set the network type of the network.
- *
- * @param type the network type. See {@link ConnectivityManager#TYPE_*}.
- *
- * @return this builder.
- */
- @NonNull
- public Builder setType(int type) {
- // Include TYPE_NONE for compatibility, type field might not be filled by some
- // networks such as test networks.
- if ((type < MIN_NETWORK_TYPE || MAX_NETWORK_TYPE < type)
- && type != ConnectivityManager.TYPE_NONE) {
- throw new IllegalArgumentException("Invalid network type: " + type);
- }
- mType = type;
- return this;
- }
-
- /**
- * Set the Radio Access Technology(RAT) type of the network.
- *
- * No RAT type is specified by default. Call clearRatType to reset.
- *
- * @param ratType the Radio Access Technology(RAT) type if applicable. See
- * {@code TelephonyManager.NETWORK_TYPE_*}.
- *
- * @return this builder.
- */
- @NonNull
- public Builder setRatType(int ratType) {
- if (!CollectionUtils.contains(TelephonyManager.getAllNetworkTypes(), ratType)
- && ratType != TelephonyManager.NETWORK_TYPE_UNKNOWN
- && ratType != NetworkStatsManager.NETWORK_TYPE_5G_NSA) {
- throw new IllegalArgumentException("Invalid ratType " + ratType);
- }
- mRatType = ratType;
- return this;
- }
-
- /**
- * Clear the Radio Access Technology(RAT) type of the network.
- *
- * @return this builder.
- */
- @NonNull
- public Builder clearRatType() {
- mRatType = NetworkTemplate.NETWORK_TYPE_ALL;
- return this;
- }
-
- /**
- * Set the Subscriber Id.
- *
- * @param subscriberId the Subscriber Id of the network. Or null if not applicable.
- * @return this builder.
- */
- @NonNull
- public Builder setSubscriberId(@Nullable String subscriberId) {
- mSubscriberId = subscriberId;
- return this;
- }
-
- /**
- * Set the Wifi Network Key.
- *
- * @param wifiNetworkKey Wifi Network Key of the network,
- * see {@link WifiInfo#getNetworkKey()}.
- * Or null if not applicable.
- * @return this builder.
- */
- @NonNull
- public Builder setWifiNetworkKey(@Nullable String wifiNetworkKey) {
- mWifiNetworkKey = wifiNetworkKey;
- return this;
- }
-
- /**
- * Set whether this network is roaming.
- *
- * This field is false by default. Call with false to reset.
- *
- * @param roaming the roaming status of the network.
- * @return this builder.
- */
- @NonNull
- public Builder setRoaming(boolean roaming) {
- mRoaming = roaming;
- return this;
- }
-
- /**
- * Set whether this network is metered.
- *
- * This field is false by default. Call with false to reset.
- *
- * @param metered the meteredness of the network.
- * @return this builder.
- */
- @NonNull
- public Builder setMetered(boolean metered) {
- mMetered = metered;
- return this;
- }
-
- /**
- * Set whether this network is the default network.
- *
- * This field is false by default. Call with false to reset.
- *
- * @param defaultNetwork the default network status of the network.
- * @return this builder.
- */
- @NonNull
- public Builder setDefaultNetwork(boolean defaultNetwork) {
- mDefaultNetwork = defaultNetwork;
- return this;
- }
-
- /**
- * Set the OEM managed type.
- *
- * @param oemManaged Type of OEM managed network or unmanaged networks.
- * See {@code NetworkTemplate#OEM_MANAGED_*}.
- * @return this builder.
- */
- @NonNull
- public Builder setOemManaged(@OemManaged int oemManaged) {
- // Assert input does not contain illegal oemManage bits.
- if ((~SUPPORTED_OEM_MANAGED_TYPES & oemManaged) != 0) {
- throw new IllegalArgumentException("Invalid value for OemManaged : " + oemManaged);
- }
- mOemManaged = oemManaged;
- return this;
- }
-
- /**
- * Set the Subscription Id.
- *
- * @param subId the Subscription Id of the network. Or INVALID_SUBSCRIPTION_ID if not
- * applicable.
- * @return this builder.
- */
- @NonNull
- public Builder setSubId(int subId) {
- mSubId = subId;
- return this;
- }
-
- private void ensureValidParameters() {
- // Assert non-mobile network cannot have a ratType.
- if (mType != TYPE_MOBILE && mRatType != NetworkTemplate.NETWORK_TYPE_ALL) {
- throw new IllegalArgumentException(
- "Invalid ratType " + mRatType + " for type " + mType);
- }
-
- // Assert non-wifi network cannot have a wifi network key.
- if (mType != TYPE_WIFI && mWifiNetworkKey != null) {
- throw new IllegalArgumentException("Invalid wifi network key for type " + mType);
- }
- }
-
- /**
- * Builds the instance of the {@link NetworkIdentity}.
- *
- * @return the built instance of {@link NetworkIdentity}.
- */
- @NonNull
- public NetworkIdentity build() {
- ensureValidParameters();
- return new NetworkIdentity(mType, mRatType, mSubscriberId, mWifiNetworkKey,
- mRoaming, mMetered, mDefaultNetwork, mOemManaged, mSubId);
- }
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
deleted file mode 100644
index ad3a958..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2011 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.net;
-
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-import android.annotation.NonNull;
-import android.service.NetworkIdentitySetProto;
-import android.util.proto.ProtoOutputStream;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Identity of a {@code iface}, defined by the set of {@link NetworkIdentity}
- * active on that interface.
- *
- * @hide
- */
-public class NetworkIdentitySet extends HashSet<NetworkIdentity> {
- private static final int VERSION_INIT = 1;
- private static final int VERSION_ADD_ROAMING = 2;
- private static final int VERSION_ADD_NETWORK_ID = 3;
- private static final int VERSION_ADD_METERED = 4;
- private static final int VERSION_ADD_DEFAULT_NETWORK = 5;
- private static final int VERSION_ADD_OEM_MANAGED_NETWORK = 6;
- private static final int VERSION_ADD_SUB_ID = 7;
-
- /**
- * Construct a {@link NetworkIdentitySet} object.
- */
- public NetworkIdentitySet() {
- super();
- }
-
- /** @hide */
- public NetworkIdentitySet(@NonNull Set<NetworkIdentity> ident) {
- super(ident);
- }
-
- /** @hide */
- public NetworkIdentitySet(DataInput in) throws IOException {
- final int version = in.readInt();
- final int size = in.readInt();
- for (int i = 0; i < size; i++) {
- if (version <= VERSION_INIT) {
- final int ignored = in.readInt();
- }
- final int type = in.readInt();
- final int ratType = in.readInt();
- final String subscriberId = readOptionalString(in);
- final String networkId;
- if (version >= VERSION_ADD_NETWORK_ID) {
- networkId = readOptionalString(in);
- } else {
- networkId = null;
- }
- final boolean roaming;
- if (version >= VERSION_ADD_ROAMING) {
- roaming = in.readBoolean();
- } else {
- roaming = false;
- }
-
- final boolean metered;
- if (version >= VERSION_ADD_METERED) {
- metered = in.readBoolean();
- } else {
- // If this is the old data and the type is mobile, treat it as metered. (Note that
- // if this is a mobile network, TYPE_MOBILE is the only possible type that could be
- // used.)
- metered = (type == TYPE_MOBILE);
- }
-
- final boolean defaultNetwork;
- if (version >= VERSION_ADD_DEFAULT_NETWORK) {
- defaultNetwork = in.readBoolean();
- } else {
- defaultNetwork = true;
- }
-
- final int oemNetCapabilities;
- if (version >= VERSION_ADD_OEM_MANAGED_NETWORK) {
- oemNetCapabilities = in.readInt();
- } else {
- oemNetCapabilities = NetworkIdentity.OEM_NONE;
- }
-
- final int subId;
- if (version >= VERSION_ADD_SUB_ID) {
- subId = in.readInt();
- } else {
- subId = INVALID_SUBSCRIPTION_ID;
- }
-
- add(new NetworkIdentity(type, ratType, subscriberId, networkId, roaming, metered,
- defaultNetwork, oemNetCapabilities, subId));
- }
- }
-
- /**
- * Method to serialize this object into a {@code DataOutput}.
- * @hide
- */
- public void writeToStream(DataOutput out) throws IOException {
- out.writeInt(VERSION_ADD_SUB_ID);
- out.writeInt(size());
- for (NetworkIdentity ident : this) {
- out.writeInt(ident.getType());
- out.writeInt(ident.getRatType());
- writeOptionalString(out, ident.getSubscriberId());
- writeOptionalString(out, ident.getWifiNetworkKey());
- out.writeBoolean(ident.isRoaming());
- out.writeBoolean(ident.isMetered());
- out.writeBoolean(ident.isDefaultNetwork());
- out.writeInt(ident.getOemManaged());
- out.writeInt(ident.getSubId());
- }
- }
-
- /**
- * @return whether any {@link NetworkIdentity} in this set is considered metered.
- * @hide
- */
- public boolean isAnyMemberMetered() {
- if (isEmpty()) {
- return false;
- }
- for (NetworkIdentity ident : this) {
- if (ident.isMetered()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * @return whether any {@link NetworkIdentity} in this set is considered roaming.
- * @hide
- */
- public boolean isAnyMemberRoaming() {
- if (isEmpty()) {
- return false;
- }
- for (NetworkIdentity ident : this) {
- if (ident.isRoaming()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * @return whether any {@link NetworkIdentity} in this set is considered on the default
- * network.
- * @hide
- */
- public boolean areAllMembersOnDefaultNetwork() {
- if (isEmpty()) {
- return true;
- }
- for (NetworkIdentity ident : this) {
- if (!ident.isDefaultNetwork()) {
- return false;
- }
- }
- return true;
- }
-
- private static void writeOptionalString(DataOutput out, String value) throws IOException {
- if (value != null) {
- out.writeByte(1);
- out.writeUTF(value);
- } else {
- out.writeByte(0);
- }
- }
-
- private static String readOptionalString(DataInput in) throws IOException {
- if (in.readByte() != 0) {
- return in.readUTF();
- } else {
- return null;
- }
- }
-
- public static int compare(@NonNull NetworkIdentitySet left, @NonNull NetworkIdentitySet right) {
- Objects.requireNonNull(left);
- Objects.requireNonNull(right);
- if (left.isEmpty()) return -1;
- if (right.isEmpty()) return 1;
-
- final NetworkIdentity leftIdent = left.iterator().next();
- final NetworkIdentity rightIdent = right.iterator().next();
- return NetworkIdentity.compare(leftIdent, rightIdent);
- }
-
- /**
- * Method to dump this object into proto debug file.
- * @hide
- */
- public void dumpDebug(ProtoOutputStream proto, long tag) {
- final long start = proto.start(tag);
-
- for (NetworkIdentity ident : this) {
- ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES);
- }
-
- proto.end(start);
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.java
deleted file mode 100644
index c018e91..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.net.module.util.NetworkIdentityUtils;
-
-import java.util.Objects;
-
-/**
- * Snapshot of network state.
- *
- * @hide
- */
-@SystemApi(client = MODULE_LIBRARIES)
-public final class NetworkStateSnapshot implements Parcelable {
- /** The network associated with this snapshot. */
- @NonNull
- private final Network mNetwork;
-
- /** The {@link NetworkCapabilities} of the network associated with this snapshot. */
- @NonNull
- private final NetworkCapabilities mNetworkCapabilities;
-
- /** The {@link LinkProperties} of the network associated with this snapshot. */
- @NonNull
- private final LinkProperties mLinkProperties;
-
- /**
- * The Subscriber Id of the network associated with this snapshot. See
- * {@link android.telephony.TelephonyManager#getSubscriberId()}.
- */
- @Nullable
- private final String mSubscriberId;
-
- /**
- * The legacy type of the network associated with this snapshot. See
- * {@code ConnectivityManager#TYPE_*}.
- */
- private final int mLegacyType;
-
- public NetworkStateSnapshot(@NonNull Network network,
- @NonNull NetworkCapabilities networkCapabilities,
- @NonNull LinkProperties linkProperties,
- @Nullable String subscriberId, int legacyType) {
- mNetwork = Objects.requireNonNull(network);
- mNetworkCapabilities = Objects.requireNonNull(networkCapabilities);
- mLinkProperties = Objects.requireNonNull(linkProperties);
- mSubscriberId = subscriberId;
- mLegacyType = legacyType;
- }
-
- /** @hide */
- public NetworkStateSnapshot(@NonNull Parcel in) {
- mNetwork = in.readParcelable(null, android.net.Network.class);
- mNetworkCapabilities = in.readParcelable(null, android.net.NetworkCapabilities.class);
- mLinkProperties = in.readParcelable(null, android.net.LinkProperties.class);
- mSubscriberId = in.readString();
- mLegacyType = in.readInt();
- }
-
- /** Get the network associated with this snapshot */
- @NonNull
- public Network getNetwork() {
- return mNetwork;
- }
-
- /** Get {@link NetworkCapabilities} of the network associated with this snapshot. */
- @NonNull
- public NetworkCapabilities getNetworkCapabilities() {
- return mNetworkCapabilities;
- }
-
- /** Get the {@link LinkProperties} of the network associated with this snapshot. */
- @NonNull
- public LinkProperties getLinkProperties() {
- return mLinkProperties;
- }
-
- /**
- * Get the Subscriber Id of the network associated with this snapshot.
- * @deprecated Please use #getSubId, which doesn't return personally identifiable
- * information.
- */
- @Deprecated
- @Nullable
- public String getSubscriberId() {
- return mSubscriberId;
- }
-
- /** Get the subId of the network associated with this snapshot. */
- public int getSubId() {
- if (mNetworkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
- final NetworkSpecifier spec = mNetworkCapabilities.getNetworkSpecifier();
- if (spec instanceof TelephonyNetworkSpecifier) {
- return ((TelephonyNetworkSpecifier) spec).getSubscriptionId();
- }
- }
- return INVALID_SUBSCRIPTION_ID;
- }
-
-
- /**
- * Get the legacy type of the network associated with this snapshot.
- * @return the legacy network type. See {@code ConnectivityManager#TYPE_*}.
- */
- public int getLegacyType() {
- return mLegacyType;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel out, int flags) {
- out.writeParcelable(mNetwork, flags);
- out.writeParcelable(mNetworkCapabilities, flags);
- out.writeParcelable(mLinkProperties, flags);
- out.writeString(mSubscriberId);
- out.writeInt(mLegacyType);
- }
-
- @NonNull
- public static final Creator<NetworkStateSnapshot> CREATOR =
- new Creator<NetworkStateSnapshot>() {
- @NonNull
- @Override
- public NetworkStateSnapshot createFromParcel(@NonNull Parcel in) {
- return new NetworkStateSnapshot(in);
- }
-
- @NonNull
- @Override
- public NetworkStateSnapshot[] newArray(int size) {
- return new NetworkStateSnapshot[size];
- }
- };
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof NetworkStateSnapshot)) return false;
- NetworkStateSnapshot that = (NetworkStateSnapshot) o;
- return mLegacyType == that.mLegacyType
- && Objects.equals(mNetwork, that.mNetwork)
- && Objects.equals(mNetworkCapabilities, that.mNetworkCapabilities)
- && Objects.equals(mLinkProperties, that.mLinkProperties)
- && Objects.equals(mSubscriberId, that.mSubscriberId);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mNetwork,
- mNetworkCapabilities, mLinkProperties, mSubscriberId, mLegacyType);
- }
-
- @Override
- public String toString() {
- return "NetworkStateSnapshot{"
- + "network=" + mNetwork
- + ", networkCapabilities=" + mNetworkCapabilities
- + ", linkProperties=" + mLinkProperties
- + ", subscriberId='" + NetworkIdentityUtils.scrubSubscriberId(mSubscriberId) + '\''
- + ", legacyType=" + mLegacyType
- + '}';
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java
deleted file mode 100644
index bcfeab9..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java
+++ /dev/null
@@ -1,1860 +0,0 @@
-/*
- * Copyright (C) 2011 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.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-
-import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.Process;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.SparseBooleanArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.net.module.util.CollectionUtils;
-
-import libcore.util.EmptyArray;
-
-import java.io.CharArrayWriter;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Predicate;
-
-/**
- * Collection of active network statistics. Can contain summary details across
- * all interfaces, or details with per-UID granularity. Internally stores data
- * as a large table, closely matching {@code /proc/} data format. This structure
- * optimizes for rapid in-memory comparison, but consider using
- * {@link NetworkStatsHistory} when persisting.
- *
- * @hide
- */
-// @NotThreadSafe
-@SystemApi
-public final class NetworkStats implements Parcelable, Iterable<NetworkStats.Entry> {
- private static final String TAG = "NetworkStats";
-
- /**
- * {@link #iface} value when interface details unavailable.
- * @hide
- */
- @Nullable public static final String IFACE_ALL = null;
-
- /**
- * Virtual network interface for video telephony. This is for VT data usage counting
- * purpose.
- */
- public static final String IFACE_VT = "vt_data0";
-
- /** {@link #uid} value when UID details unavailable. */
- public static final int UID_ALL = -1;
- /** Special UID value for data usage by tethering. */
- public static final int UID_TETHERING = -5;
-
- /**
- * {@link #tag} value matching any tag.
- * @hide
- */
- // TODO: Rename TAG_ALL to TAG_ANY.
- public static final int TAG_ALL = -1;
- /** {@link #set} value for all sets combined, not including debug sets. */
- public static final int SET_ALL = -1;
- /** {@link #set} value where background data is accounted. */
- public static final int SET_DEFAULT = 0;
- /** {@link #set} value where foreground data is accounted. */
- public static final int SET_FOREGROUND = 1;
- /**
- * All {@link #set} value greater than SET_DEBUG_START are debug {@link #set} values.
- * @hide
- */
- public static final int SET_DEBUG_START = 1000;
- /**
- * Debug {@link #set} value when the VPN stats are moved in.
- * @hide
- */
- public static final int SET_DBG_VPN_IN = 1001;
- /**
- * Debug {@link #set} value when the VPN stats are moved out of a vpn UID.
- * @hide
- */
- public static final int SET_DBG_VPN_OUT = 1002;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "SET_" }, value = {
- SET_ALL,
- SET_DEFAULT,
- SET_FOREGROUND,
- })
- public @interface State {
- }
-
- /**
- * Include all interfaces when filtering
- * @hide
- */
- public @Nullable static final String[] INTERFACES_ALL = null;
-
- /** {@link #tag} value for total data across all tags. */
- public static final int TAG_NONE = 0;
-
- /** {@link #metered} value to account for all metered states. */
- public static final int METERED_ALL = -1;
- /** {@link #metered} value where native, unmetered data is accounted. */
- public static final int METERED_NO = 0;
- /** {@link #metered} value where metered data is accounted. */
- public static final int METERED_YES = 1;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "METERED_" }, value = {
- METERED_ALL,
- METERED_NO,
- METERED_YES
- })
- public @interface Meteredness {
- }
-
-
- /** {@link #roaming} value to account for all roaming states. */
- public static final int ROAMING_ALL = -1;
- /** {@link #roaming} value where native, non-roaming data is accounted. */
- public static final int ROAMING_NO = 0;
- /** {@link #roaming} value where roaming data is accounted. */
- public static final int ROAMING_YES = 1;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "ROAMING_" }, value = {
- ROAMING_ALL,
- ROAMING_NO,
- ROAMING_YES
- })
- public @interface Roaming {
- }
-
- /** {@link #onDefaultNetwork} value to account for all default network states. */
- public static final int DEFAULT_NETWORK_ALL = -1;
- /** {@link #onDefaultNetwork} value to account for usage while not the default network. */
- public static final int DEFAULT_NETWORK_NO = 0;
- /** {@link #onDefaultNetwork} value to account for usage while the default network. */
- public static final int DEFAULT_NETWORK_YES = 1;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "DEFAULT_NETWORK_" }, value = {
- DEFAULT_NETWORK_ALL,
- DEFAULT_NETWORK_NO,
- DEFAULT_NETWORK_YES
- })
- public @interface DefaultNetwork {
- }
-
- /**
- * Denotes a request for stats at the interface level.
- * @hide
- */
- public static final int STATS_PER_IFACE = 0;
- /**
- * Denotes a request for stats at the interface and UID level.
- * @hide
- */
- public static final int STATS_PER_UID = 1;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "STATS_PER_" }, value = {
- STATS_PER_IFACE,
- STATS_PER_UID
- })
- public @interface StatsType {
- }
-
- private static final String CLATD_INTERFACE_PREFIX = "v4-";
- // Delta between IPv4 header (20b) and IPv6 header (40b).
- // Used for correct stats accounting on clatd interfaces.
- private static final int IPV4V6_HEADER_DELTA = 20;
-
- // TODO: move fields to "mVariable" notation
-
- /**
- * {@link SystemClock#elapsedRealtime()} timestamp in milliseconds when this data was
- * generated.
- * It's a timestamps delta when {@link #subtract()},
- * {@code INetworkStatsSession#getSummaryForAllUid()} methods are used.
- */
- private long elapsedRealtime;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private int size;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private int capacity;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private String[] iface;
- @UnsupportedAppUsage
- private int[] uid;
- @UnsupportedAppUsage
- private int[] set;
- @UnsupportedAppUsage
- private int[] tag;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private int[] metered;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private int[] roaming;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private int[] defaultNetwork;
- @UnsupportedAppUsage
- private long[] rxBytes;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private long[] rxPackets;
- @UnsupportedAppUsage
- private long[] txBytes;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private long[] txPackets;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private long[] operations;
-
- /**
- * Basic element of network statistics. Contains the number of packets and number of bytes
- * transferred on both directions in a given set of conditions. See
- * {@link Entry#Entry(String, int, int, int, int, int, int, long, long, long, long, long)}.
- *
- * @hide
- */
- @SystemApi
- public static class Entry {
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public String iface;
- /** @hide */
- @UnsupportedAppUsage
- public int uid;
- /** @hide */
- @UnsupportedAppUsage
- public int set;
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public int tag;
- /**
- * Note that this is only populated w/ the default value when read from /proc or written
- * to disk. We merge in the correct value when reporting this value to clients of
- * getSummary().
- * @hide
- */
- public int metered;
- /**
- * Note that this is only populated w/ the default value when read from /proc or written
- * to disk. We merge in the correct value when reporting this value to clients of
- * getSummary().
- * @hide
- */
- public int roaming;
- /**
- * Note that this is only populated w/ the default value when read from /proc or written
- * to disk. We merge in the correct value when reporting this value to clients of
- * getSummary().
- * @hide
- */
- public int defaultNetwork;
- /** @hide */
- @UnsupportedAppUsage
- public long rxBytes;
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public long rxPackets;
- /** @hide */
- @UnsupportedAppUsage
- public long txBytes;
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public long txPackets;
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public long operations;
-
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public Entry() {
- this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
- }
-
- /** @hide */
- public Entry(long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
- this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets,
- operations);
- }
-
- /** @hide */
- public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets,
- long txBytes, long txPackets, long operations) {
- this(iface, uid, set, tag, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO,
- rxBytes, rxPackets, txBytes, txPackets, operations);
- }
-
- /**
- * Construct a {@link Entry} object by giving statistics of packet and byte transferred on
- * both direction, and associated with a set of given conditions.
- *
- * @param iface interface name of this {@link Entry}. Or null if not specified.
- * @param uid uid of this {@link Entry}. {@link #UID_TETHERING} if this {@link Entry} is
- * for tethering. Or {@link #UID_ALL} if this {@link NetworkStats} is only
- * counting iface stats.
- * @param set usage state of this {@link Entry}.
- * @param tag tag of this {@link Entry}.
- * @param metered metered state of this {@link Entry}.
- * @param roaming roaming state of this {@link Entry}.
- * @param defaultNetwork default network status of this {@link Entry}.
- * @param rxBytes Number of bytes received for this {@link Entry}. Statistics should
- * represent the contents of IP packets, including IP headers.
- * @param rxPackets Number of packets received for this {@link Entry}. Statistics should
- * represent the contents of IP packets, including IP headers.
- * @param txBytes Number of bytes transmitted for this {@link Entry}. Statistics should
- * represent the contents of IP packets, including IP headers.
- * @param txPackets Number of bytes transmitted for this {@link Entry}. Statistics should
- * represent the contents of IP packets, including IP headers.
- * @param operations count of network operations performed for this {@link Entry}. This can
- * be used to derive bytes-per-operation.
- */
- public Entry(@Nullable String iface, int uid, @State int set, int tag,
- @Meteredness int metered, @Roaming int roaming, @DefaultNetwork int defaultNetwork,
- long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
- this.iface = iface;
- this.uid = uid;
- this.set = set;
- this.tag = tag;
- this.metered = metered;
- this.roaming = roaming;
- this.defaultNetwork = defaultNetwork;
- this.rxBytes = rxBytes;
- this.rxPackets = rxPackets;
- this.txBytes = txBytes;
- this.txPackets = txPackets;
- this.operations = operations;
- }
-
- /** @hide */
- public boolean isNegative() {
- return rxBytes < 0 || rxPackets < 0 || txBytes < 0 || txPackets < 0 || operations < 0;
- }
-
- /** @hide */
- public boolean isEmpty() {
- return rxBytes == 0 && rxPackets == 0 && txBytes == 0 && txPackets == 0
- && operations == 0;
- }
-
- /** @hide */
- public void add(Entry another) {
- this.rxBytes += another.rxBytes;
- this.rxPackets += another.rxPackets;
- this.txBytes += another.txBytes;
- this.txPackets += another.txPackets;
- this.operations += another.operations;
- }
-
- /**
- * @return interface name of this entry.
- * @hide
- */
- @Nullable public String getIface() {
- return iface;
- }
-
- /**
- * @return the uid of this entry.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public int getUid() {
- return uid;
- }
-
- /**
- * @return the set state of this entry.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @State public int getSet() {
- return set;
- }
-
- /**
- * @return the tag value of this entry.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public int getTag() {
- return tag;
- }
-
- /**
- * @return the metered state.
- * @hide
- */
- @Meteredness
- @SystemApi(client = MODULE_LIBRARIES)
- public int getMetered() {
- return metered;
- }
-
- /**
- * @return the roaming state.
- * @hide
- */
- @Roaming
- @SystemApi(client = MODULE_LIBRARIES)
- public int getRoaming() {
- return roaming;
- }
-
- /**
- * @return the default network state.
- * @hide
- */
- @DefaultNetwork
- @SystemApi(client = MODULE_LIBRARIES)
- public int getDefaultNetwork() {
- return defaultNetwork;
- }
-
- /**
- * @return the number of received bytes.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public long getRxBytes() {
- return rxBytes;
- }
-
- /**
- * @return the number of received packets.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public long getRxPackets() {
- return rxPackets;
- }
-
- /**
- * @return the number of transmitted bytes.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public long getTxBytes() {
- return txBytes;
- }
-
- /**
- * @return the number of transmitted packets.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public long getTxPackets() {
- return txPackets;
- }
-
- /**
- * @return the count of network operations performed for this entry.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public long getOperations() {
- return operations;
- }
-
- @Override
- public String toString() {
- final StringBuilder builder = new StringBuilder();
- builder.append("iface=").append(iface);
- builder.append(" uid=").append(uid);
- builder.append(" set=").append(setToString(set));
- builder.append(" tag=").append(tagToString(tag));
- builder.append(" metered=").append(meteredToString(metered));
- builder.append(" roaming=").append(roamingToString(roaming));
- builder.append(" defaultNetwork=").append(defaultNetworkToString(defaultNetwork));
- builder.append(" rxBytes=").append(rxBytes);
- builder.append(" rxPackets=").append(rxPackets);
- builder.append(" txBytes=").append(txBytes);
- builder.append(" txPackets=").append(txPackets);
- builder.append(" operations=").append(operations);
- return builder.toString();
- }
-
- /** @hide */
- @Override
- public boolean equals(@Nullable Object o) {
- if (o instanceof Entry) {
- final Entry e = (Entry) o;
- return uid == e.uid && set == e.set && tag == e.tag && metered == e.metered
- && roaming == e.roaming && defaultNetwork == e.defaultNetwork
- && rxBytes == e.rxBytes && rxPackets == e.rxPackets
- && txBytes == e.txBytes && txPackets == e.txPackets
- && operations == e.operations && TextUtils.equals(iface, e.iface);
- }
- return false;
- }
-
- /** @hide */
- @Override
- public int hashCode() {
- return Objects.hash(uid, set, tag, metered, roaming, defaultNetwork, iface);
- }
- }
-
- public NetworkStats(long elapsedRealtime, int initialSize) {
- this.elapsedRealtime = elapsedRealtime;
- this.size = 0;
- if (initialSize > 0) {
- this.capacity = initialSize;
- this.iface = new String[initialSize];
- this.uid = new int[initialSize];
- this.set = new int[initialSize];
- this.tag = new int[initialSize];
- this.metered = new int[initialSize];
- this.roaming = new int[initialSize];
- this.defaultNetwork = new int[initialSize];
- this.rxBytes = new long[initialSize];
- this.rxPackets = new long[initialSize];
- this.txBytes = new long[initialSize];
- this.txPackets = new long[initialSize];
- this.operations = new long[initialSize];
- } else {
- // Special case for use by NetworkStatsFactory to start out *really* empty.
- clear();
- }
- }
-
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public NetworkStats(Parcel parcel) {
- elapsedRealtime = parcel.readLong();
- size = parcel.readInt();
- capacity = parcel.readInt();
- iface = parcel.createStringArray();
- uid = parcel.createIntArray();
- set = parcel.createIntArray();
- tag = parcel.createIntArray();
- metered = parcel.createIntArray();
- roaming = parcel.createIntArray();
- defaultNetwork = parcel.createIntArray();
- rxBytes = parcel.createLongArray();
- rxPackets = parcel.createLongArray();
- txBytes = parcel.createLongArray();
- txPackets = parcel.createLongArray();
- operations = parcel.createLongArray();
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeLong(elapsedRealtime);
- dest.writeInt(size);
- dest.writeInt(capacity);
- dest.writeStringArray(iface);
- dest.writeIntArray(uid);
- dest.writeIntArray(set);
- dest.writeIntArray(tag);
- dest.writeIntArray(metered);
- dest.writeIntArray(roaming);
- dest.writeIntArray(defaultNetwork);
- dest.writeLongArray(rxBytes);
- dest.writeLongArray(rxPackets);
- dest.writeLongArray(txBytes);
- dest.writeLongArray(txPackets);
- dest.writeLongArray(operations);
- }
-
- /**
- * @hide
- */
- @Override
- public NetworkStats clone() {
- final NetworkStats clone = new NetworkStats(elapsedRealtime, size);
- NetworkStats.Entry entry = null;
- for (int i = 0; i < size; i++) {
- entry = getValues(i, entry);
- clone.insertEntry(entry);
- }
- return clone;
- }
-
- /**
- * Clear all data stored in this object.
- * @hide
- */
- public void clear() {
- this.capacity = 0;
- this.iface = EmptyArray.STRING;
- this.uid = EmptyArray.INT;
- this.set = EmptyArray.INT;
- this.tag = EmptyArray.INT;
- this.metered = EmptyArray.INT;
- this.roaming = EmptyArray.INT;
- this.defaultNetwork = EmptyArray.INT;
- this.rxBytes = EmptyArray.LONG;
- this.rxPackets = EmptyArray.LONG;
- this.txBytes = EmptyArray.LONG;
- this.txPackets = EmptyArray.LONG;
- this.operations = EmptyArray.LONG;
- }
-
- /** @hide */
- @VisibleForTesting
- public NetworkStats insertEntry(
- String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) {
- return insertEntry(
- iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L);
- }
-
- /** @hide */
- @VisibleForTesting
- public NetworkStats insertEntry(String iface, int uid, int set, int tag, long rxBytes,
- long rxPackets, long txBytes, long txPackets, long operations) {
- return insertEntry(new Entry(
- iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
- }
-
- /** @hide */
- @VisibleForTesting
- public NetworkStats insertEntry(String iface, int uid, int set, int tag, int metered,
- int roaming, int defaultNetwork, long rxBytes, long rxPackets, long txBytes,
- long txPackets, long operations) {
- return insertEntry(new Entry(
- iface, uid, set, tag, metered, roaming, defaultNetwork, rxBytes, rxPackets,
- txBytes, txPackets, operations));
- }
-
- /**
- * Add new stats entry, copying from given {@link Entry}. The {@link Entry}
- * object can be recycled across multiple calls.
- * @hide
- */
- public NetworkStats insertEntry(Entry entry) {
- if (size >= capacity) {
- final int newLength = Math.max(size, 10) * 3 / 2;
- iface = Arrays.copyOf(iface, newLength);
- uid = Arrays.copyOf(uid, newLength);
- set = Arrays.copyOf(set, newLength);
- tag = Arrays.copyOf(tag, newLength);
- metered = Arrays.copyOf(metered, newLength);
- roaming = Arrays.copyOf(roaming, newLength);
- defaultNetwork = Arrays.copyOf(defaultNetwork, newLength);
- rxBytes = Arrays.copyOf(rxBytes, newLength);
- rxPackets = Arrays.copyOf(rxPackets, newLength);
- txBytes = Arrays.copyOf(txBytes, newLength);
- txPackets = Arrays.copyOf(txPackets, newLength);
- operations = Arrays.copyOf(operations, newLength);
- capacity = newLength;
- }
-
- setValues(size, entry);
- size++;
-
- return this;
- }
-
- private void setValues(int i, Entry entry) {
- iface[i] = entry.iface;
- uid[i] = entry.uid;
- set[i] = entry.set;
- tag[i] = entry.tag;
- metered[i] = entry.metered;
- roaming[i] = entry.roaming;
- defaultNetwork[i] = entry.defaultNetwork;
- rxBytes[i] = entry.rxBytes;
- rxPackets[i] = entry.rxPackets;
- txBytes[i] = entry.txBytes;
- txPackets[i] = entry.txPackets;
- operations[i] = entry.operations;
- }
-
- /**
- * Iterate over Entry objects.
- *
- * Return an iterator of this object that will iterate through all contained Entry objects.
- *
- * This iterator does not support concurrent modification and makes no guarantee of fail-fast
- * behavior. If any method that can mutate the contents of this object is called while
- * iteration is in progress, either inside the loop or in another thread, then behavior is
- * undefined.
- * The remove() method is not implemented and will throw UnsupportedOperationException.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @NonNull public Iterator<Entry> iterator() {
- return new Iterator<Entry>() {
- int mIndex = 0;
-
- @Override
- public boolean hasNext() {
- return mIndex < size;
- }
-
- @Override
- public Entry next() {
- return getValues(mIndex++, null);
- }
- };
- }
-
- /**
- * Return specific stats entry.
- * @hide
- */
- @UnsupportedAppUsage
- public Entry getValues(int i, @Nullable Entry recycle) {
- final Entry entry = recycle != null ? recycle : new Entry();
- entry.iface = iface[i];
- entry.uid = uid[i];
- entry.set = set[i];
- entry.tag = tag[i];
- entry.metered = metered[i];
- entry.roaming = roaming[i];
- entry.defaultNetwork = defaultNetwork[i];
- entry.rxBytes = rxBytes[i];
- entry.rxPackets = rxPackets[i];
- entry.txBytes = txBytes[i];
- entry.txPackets = txPackets[i];
- entry.operations = operations[i];
- return entry;
- }
-
- /**
- * If @{code dest} is not equal to @{code src}, copy entry from index @{code src} to index
- * @{code dest}.
- */
- private void maybeCopyEntry(int dest, int src) {
- if (dest == src) return;
- iface[dest] = iface[src];
- uid[dest] = uid[src];
- set[dest] = set[src];
- tag[dest] = tag[src];
- metered[dest] = metered[src];
- roaming[dest] = roaming[src];
- defaultNetwork[dest] = defaultNetwork[src];
- rxBytes[dest] = rxBytes[src];
- rxPackets[dest] = rxPackets[src];
- txBytes[dest] = txBytes[src];
- txPackets[dest] = txPackets[src];
- operations[dest] = operations[src];
- }
-
- /** @hide */
- public long getElapsedRealtime() {
- return elapsedRealtime;
- }
-
- /** @hide */
- public void setElapsedRealtime(long time) {
- elapsedRealtime = time;
- }
-
- /**
- * Return age of this {@link NetworkStats} object with respect to
- * {@link SystemClock#elapsedRealtime()}.
- * @hide
- */
- public long getElapsedRealtimeAge() {
- return SystemClock.elapsedRealtime() - elapsedRealtime;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public int size() {
- return size;
- }
-
- /** @hide */
- @VisibleForTesting
- public int internalSize() {
- return capacity;
- }
-
- /** @hide */
- @Deprecated
- public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
- long txBytes, long txPackets, long operations) {
- return combineValues(
- iface, uid, SET_DEFAULT, tag, rxBytes, rxPackets, txBytes,
- txPackets, operations);
- }
-
- /** @hide */
- public NetworkStats combineValues(String iface, int uid, int set, int tag,
- long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
- return combineValues(new Entry(
- iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
- }
-
- /**
- * Combine given values with an existing row, or create a new row if
- * {@link #findIndex(String, int, int, int, int, int, int)} is unable to find match. Can
- * also be used to subtract values from existing rows. This method mutates the referencing
- * {@link NetworkStats} object.
- *
- * @param entry the {@link Entry} to combine.
- * @return a reference to this mutated {@link NetworkStats} object.
- * @hide
- */
- public @NonNull NetworkStats combineValues(@NonNull Entry entry) {
- final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.metered,
- entry.roaming, entry.defaultNetwork);
- if (i == -1) {
- // only create new entry when positive contribution
- insertEntry(entry);
- } else {
- rxBytes[i] += entry.rxBytes;
- rxPackets[i] += entry.rxPackets;
- txBytes[i] += entry.txBytes;
- txPackets[i] += entry.txPackets;
- operations[i] += entry.operations;
- }
- return this;
- }
-
- /**
- * Add given values with an existing row, or create a new row if
- * {@link #findIndex(String, int, int, int, int, int, int)} is unable to find match. Can
- * also be used to subtract values from existing rows.
- *
- * @param entry the {@link Entry} to add.
- * @return a new constructed {@link NetworkStats} object that contains the result.
- */
- public @NonNull NetworkStats addEntry(@NonNull Entry entry) {
- return this.clone().combineValues(entry);
- }
-
- /**
- * Add the given {@link NetworkStats} objects.
- *
- * @return the sum of two objects.
- */
- public @NonNull NetworkStats add(@NonNull NetworkStats another) {
- final NetworkStats ret = this.clone();
- ret.combineAllValues(another);
- return ret;
- }
-
- /**
- * Combine all values from another {@link NetworkStats} into this object.
- * @hide
- */
- public void combineAllValues(@NonNull NetworkStats another) {
- NetworkStats.Entry entry = null;
- for (int i = 0; i < another.size; i++) {
- entry = another.getValues(i, entry);
- combineValues(entry);
- }
- }
-
- /**
- * Find first stats index that matches the requested parameters.
- * @hide
- */
- public int findIndex(String iface, int uid, int set, int tag, int metered, int roaming,
- int defaultNetwork) {
- for (int i = 0; i < size; i++) {
- if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
- && metered == this.metered[i] && roaming == this.roaming[i]
- && defaultNetwork == this.defaultNetwork[i]
- && Objects.equals(iface, this.iface[i])) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Find first stats index that matches the requested parameters, starting
- * search around the hinted index as an optimization.
- * @hide
- */
- @VisibleForTesting
- public int findIndexHinted(String iface, int uid, int set, int tag, int metered, int roaming,
- int defaultNetwork, int hintIndex) {
- for (int offset = 0; offset < size; offset++) {
- final int halfOffset = offset / 2;
-
- // search outwards from hint index, alternating forward and backward
- final int i;
- if (offset % 2 == 0) {
- i = (hintIndex + halfOffset) % size;
- } else {
- i = (size + hintIndex - halfOffset - 1) % size;
- }
-
- if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
- && metered == this.metered[i] && roaming == this.roaming[i]
- && defaultNetwork == this.defaultNetwork[i]
- && Objects.equals(iface, this.iface[i])) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Splice in {@link #operations} from the given {@link NetworkStats} based
- * on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface},
- * since operation counts are at data layer.
- * @hide
- */
- public void spliceOperationsFrom(NetworkStats stats) {
- for (int i = 0; i < size; i++) {
- final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i], metered[i], roaming[i],
- defaultNetwork[i]);
- if (j == -1) {
- operations[i] = 0;
- } else {
- operations[i] = stats.operations[j];
- }
- }
- }
-
- /**
- * Return list of unique interfaces known by this data structure.
- * @hide
- */
- public String[] getUniqueIfaces() {
- final HashSet<String> ifaces = new HashSet<String>();
- for (String iface : this.iface) {
- if (iface != IFACE_ALL) {
- ifaces.add(iface);
- }
- }
- return ifaces.toArray(new String[ifaces.size()]);
- }
-
- /**
- * Return list of unique UIDs known by this data structure.
- * @hide
- */
- @UnsupportedAppUsage
- public int[] getUniqueUids() {
- final SparseBooleanArray uids = new SparseBooleanArray();
- for (int uid : this.uid) {
- uids.put(uid, true);
- }
-
- final int size = uids.size();
- final int[] result = new int[size];
- for (int i = 0; i < size; i++) {
- result[i] = uids.keyAt(i);
- }
- return result;
- }
-
- /**
- * Return total bytes represented by this snapshot object, usually used when
- * checking if a {@link #subtract(NetworkStats)} delta passes a threshold.
- * @hide
- */
- @UnsupportedAppUsage
- public long getTotalBytes() {
- final Entry entry = getTotal(null);
- return entry.rxBytes + entry.txBytes;
- }
-
- /**
- * Return total of all fields represented by this snapshot object.
- * @hide
- */
- @UnsupportedAppUsage
- public Entry getTotal(Entry recycle) {
- return getTotal(recycle, null, UID_ALL, false);
- }
-
- /**
- * Return total of all fields represented by this snapshot object matching
- * the requested {@link #uid}.
- * @hide
- */
- @UnsupportedAppUsage
- public Entry getTotal(Entry recycle, int limitUid) {
- return getTotal(recycle, null, limitUid, false);
- }
-
- /**
- * Return total of all fields represented by this snapshot object matching
- * the requested {@link #iface}.
- * @hide
- */
- public Entry getTotal(Entry recycle, HashSet<String> limitIface) {
- return getTotal(recycle, limitIface, UID_ALL, false);
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public Entry getTotalIncludingTags(Entry recycle) {
- return getTotal(recycle, null, UID_ALL, true);
- }
-
- /**
- * Return total of all fields represented by this snapshot object matching
- * the requested {@link #iface} and {@link #uid}.
- *
- * @param limitIface Set of {@link #iface} to include in total; or {@code
- * null} to include all ifaces.
- */
- private Entry getTotal(
- Entry recycle, HashSet<String> limitIface, int limitUid, boolean includeTags) {
- final Entry entry = recycle != null ? recycle : new Entry();
-
- entry.iface = IFACE_ALL;
- entry.uid = limitUid;
- entry.set = SET_ALL;
- entry.tag = TAG_NONE;
- entry.metered = METERED_ALL;
- entry.roaming = ROAMING_ALL;
- entry.defaultNetwork = DEFAULT_NETWORK_ALL;
- entry.rxBytes = 0;
- entry.rxPackets = 0;
- entry.txBytes = 0;
- entry.txPackets = 0;
- entry.operations = 0;
-
- for (int i = 0; i < size; i++) {
- final boolean matchesUid = (limitUid == UID_ALL) || (limitUid == uid[i]);
- final boolean matchesIface = (limitIface == null) || (limitIface.contains(iface[i]));
-
- if (matchesUid && matchesIface) {
- // skip specific tags, since already counted in TAG_NONE
- if (tag[i] != TAG_NONE && !includeTags) continue;
-
- entry.rxBytes += rxBytes[i];
- entry.rxPackets += rxPackets[i];
- entry.txBytes += txBytes[i];
- entry.txPackets += txPackets[i];
- entry.operations += operations[i];
- }
- }
- return entry;
- }
-
- /**
- * Fast path for battery stats.
- * @hide
- */
- public long getTotalPackets() {
- long total = 0;
- for (int i = size-1; i >= 0; i--) {
- total += rxPackets[i] + txPackets[i];
- }
- return total;
- }
-
- /**
- * Subtract the given {@link NetworkStats}, effectively leaving the delta
- * between two snapshots in time. Assumes that statistics rows collect over
- * time, and that none of them have disappeared. This method does not mutate
- * the referencing object.
- *
- * @return the delta between two objects.
- */
- public @NonNull NetworkStats subtract(@NonNull NetworkStats right) {
- return subtract(this, right, null, null);
- }
-
- /**
- * Subtract the two given {@link NetworkStats} objects, returning the delta
- * between two snapshots in time. Assumes that statistics rows collect over
- * time, and that none of them have disappeared.
- * <p>
- * If counters have rolled backwards, they are clamped to {@code 0} and
- * reported to the given {@link NonMonotonicObserver}.
- * @hide
- */
- public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right,
- NonMonotonicObserver<C> observer, C cookie) {
- return subtract(left, right, observer, cookie, null);
- }
-
- /**
- * Subtract the two given {@link NetworkStats} objects, returning the delta
- * between two snapshots in time. Assumes that statistics rows collect over
- * time, and that none of them have disappeared.
- * <p>
- * If counters have rolled backwards, they are clamped to {@code 0} and
- * reported to the given {@link NonMonotonicObserver}.
- * <p>
- * If <var>recycle</var> is supplied, this NetworkStats object will be
- * reused (and returned) as the result if it is large enough to contain
- * the data.
- * @hide
- */
- public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right,
- NonMonotonicObserver<C> observer, C cookie, NetworkStats recycle) {
- long deltaRealtime = left.elapsedRealtime - right.elapsedRealtime;
- if (deltaRealtime < 0) {
- if (observer != null) {
- observer.foundNonMonotonic(left, -1, right, -1, cookie);
- }
- deltaRealtime = 0;
- }
-
- // result will have our rows, and elapsed time between snapshots
- final Entry entry = new Entry();
- final NetworkStats result;
- if (recycle != null && recycle.capacity >= left.size) {
- result = recycle;
- result.size = 0;
- result.elapsedRealtime = deltaRealtime;
- } else {
- result = new NetworkStats(deltaRealtime, left.size);
- }
- for (int i = 0; i < left.size; i++) {
- entry.iface = left.iface[i];
- entry.uid = left.uid[i];
- entry.set = left.set[i];
- entry.tag = left.tag[i];
- entry.metered = left.metered[i];
- entry.roaming = left.roaming[i];
- entry.defaultNetwork = left.defaultNetwork[i];
- entry.rxBytes = left.rxBytes[i];
- entry.rxPackets = left.rxPackets[i];
- entry.txBytes = left.txBytes[i];
- entry.txPackets = left.txPackets[i];
- entry.operations = left.operations[i];
-
- // find remote row that matches, and subtract
- final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag,
- entry.metered, entry.roaming, entry.defaultNetwork, i);
- if (j != -1) {
- // Found matching row, subtract remote value.
- entry.rxBytes -= right.rxBytes[j];
- entry.rxPackets -= right.rxPackets[j];
- entry.txBytes -= right.txBytes[j];
- entry.txPackets -= right.txPackets[j];
- entry.operations -= right.operations[j];
- }
-
- if (entry.isNegative()) {
- if (observer != null) {
- observer.foundNonMonotonic(left, i, right, j, cookie);
- }
- entry.rxBytes = Math.max(entry.rxBytes, 0);
- entry.rxPackets = Math.max(entry.rxPackets, 0);
- entry.txBytes = Math.max(entry.txBytes, 0);
- entry.txPackets = Math.max(entry.txPackets, 0);
- entry.operations = Math.max(entry.operations, 0);
- }
-
- result.insertEntry(entry);
- }
-
- return result;
- }
-
- /**
- * Calculate and apply adjustments to captured statistics for 464xlat traffic.
- *
- * <p>This mutates stacked traffic stats, to account for IPv4/IPv6 header size difference.
- *
- * <p>UID stats, which are only accounted on the stacked interface, need to be increased
- * by 20 bytes/packet to account for translation overhead.
- *
- * <p>The potential additional overhead of 8 bytes/packet for ip fragments is ignored.
- *
- * <p>Interface stats need to sum traffic on both stacked and base interface because:
- * - eBPF offloaded packets appear only on the stacked interface
- * - Non-offloaded ingress packets appear only on the stacked interface
- * (due to iptables raw PREROUTING drop rules)
- * - Non-offloaded egress packets appear only on the stacked interface
- * (due to ignoring traffic from clat daemon by uid match)
- * (and of course the 20 bytes/packet overhead needs to be applied to stacked interface stats)
- *
- * <p>This method will behave fine if {@code stackedIfaces} is an non-synchronized but add-only
- * {@code ConcurrentHashMap}
- * @param baseTraffic Traffic on the base interfaces. Will be mutated.
- * @param stackedTraffic Stats with traffic stacked on top of our ifaces. Will also be mutated.
- * @param stackedIfaces Mapping ipv6if -> ipv4if interface where traffic is counted on both.
- * @hide
- */
- public static void apply464xlatAdjustments(NetworkStats baseTraffic,
- NetworkStats stackedTraffic, Map<String, String> stackedIfaces) {
- // For recycling
- Entry entry = null;
- for (int i = 0; i < stackedTraffic.size; i++) {
- entry = stackedTraffic.getValues(i, entry);
- if (entry == null) continue;
- if (entry.iface == null) continue;
- if (!entry.iface.startsWith(CLATD_INTERFACE_PREFIX)) continue;
-
- // For 464xlat traffic, per uid stats only counts the bytes of the native IPv4 packet
- // sent on the stacked interface with prefix "v4-" and drops the IPv6 header size after
- // unwrapping. To account correctly for on-the-wire traffic, add the 20 additional bytes
- // difference for all packets (http://b/12249687, http:/b/33681750).
- //
- // Note: this doesn't account for LRO/GRO/GSO/TSO (ie. >mtu) traffic correctly, nor
- // does it correctly account for the 8 extra bytes in the IPv6 fragmentation header.
- //
- // While the ebpf code path does try to simulate proper post segmentation packet
- // counts, we have nothing of the sort of xt_qtaguid stats.
- entry.rxBytes += entry.rxPackets * IPV4V6_HEADER_DELTA;
- entry.txBytes += entry.txPackets * IPV4V6_HEADER_DELTA;
- stackedTraffic.setValues(i, entry);
- }
- }
-
- /**
- * Calculate and apply adjustments to captured statistics for 464xlat traffic counted twice.
- *
- * <p>This mutates the object this method is called on. Equivalent to calling
- * {@link #apply464xlatAdjustments(NetworkStats, NetworkStats, Map)} with {@code this} as
- * base and stacked traffic.
- * @param stackedIfaces Mapping ipv6if -> ipv4if interface where traffic is counted on both.
- * @hide
- */
- public void apply464xlatAdjustments(Map<String, String> stackedIfaces) {
- apply464xlatAdjustments(this, this, stackedIfaces);
- }
-
- /**
- * Return total statistics grouped by {@link #iface}; doesn't mutate the
- * original structure.
- * @hide
- */
- public NetworkStats groupedByIface() {
- final NetworkStats stats = new NetworkStats(elapsedRealtime, 10);
-
- final Entry entry = new Entry();
- entry.uid = UID_ALL;
- entry.set = SET_ALL;
- entry.tag = TAG_NONE;
- entry.metered = METERED_ALL;
- entry.roaming = ROAMING_ALL;
- entry.defaultNetwork = DEFAULT_NETWORK_ALL;
- entry.operations = 0L;
-
- for (int i = 0; i < size; i++) {
- // skip specific tags, since already counted in TAG_NONE
- if (tag[i] != TAG_NONE) continue;
-
- entry.iface = iface[i];
- entry.rxBytes = rxBytes[i];
- entry.rxPackets = rxPackets[i];
- entry.txBytes = txBytes[i];
- entry.txPackets = txPackets[i];
- stats.combineValues(entry);
- }
-
- return stats;
- }
-
- /**
- * Return total statistics grouped by {@link #uid}; doesn't mutate the
- * original structure.
- * @hide
- */
- public NetworkStats groupedByUid() {
- final NetworkStats stats = new NetworkStats(elapsedRealtime, 10);
-
- final Entry entry = new Entry();
- entry.iface = IFACE_ALL;
- entry.set = SET_ALL;
- entry.tag = TAG_NONE;
- entry.metered = METERED_ALL;
- entry.roaming = ROAMING_ALL;
- entry.defaultNetwork = DEFAULT_NETWORK_ALL;
-
- for (int i = 0; i < size; i++) {
- // skip specific tags, since already counted in TAG_NONE
- if (tag[i] != TAG_NONE) continue;
-
- entry.uid = uid[i];
- entry.rxBytes = rxBytes[i];
- entry.rxPackets = rxPackets[i];
- entry.txBytes = txBytes[i];
- entry.txPackets = txPackets[i];
- entry.operations = operations[i];
- stats.combineValues(entry);
- }
-
- return stats;
- }
-
- /**
- * Remove all rows that match one of specified UIDs.
- * This mutates the original structure in place.
- * @hide
- */
- public void removeUids(int[] uids) {
- filter(e -> !CollectionUtils.contains(uids, e.uid));
- }
-
- /**
- * Remove all rows that match one of specified UIDs.
- * @return the result object.
- * @hide
- */
- @NonNull
- public NetworkStats removeEmptyEntries() {
- final NetworkStats ret = this.clone();
- ret.filter(e -> e.rxBytes != 0 || e.rxPackets != 0 || e.txBytes != 0 || e.txPackets != 0
- || e.operations != 0);
- return ret;
- }
-
- /**
- * Only keep entries that match all specified filters.
- *
- * <p>This mutates the original structure in place. After this method is called,
- * size is the number of matching entries, and capacity is the previous capacity.
- * @param limitUid UID to filter for, or {@link #UID_ALL}.
- * @param limitIfaces Interfaces to filter for, or {@link #INTERFACES_ALL}.
- * @param limitTag Tag to filter for, or {@link #TAG_ALL}.
- * @hide
- */
- public void filter(int limitUid, String[] limitIfaces, int limitTag) {
- if (limitUid == UID_ALL && limitTag == TAG_ALL && limitIfaces == INTERFACES_ALL) {
- return;
- }
- filter(e -> (limitUid == UID_ALL || limitUid == e.uid)
- && (limitTag == TAG_ALL || limitTag == e.tag)
- && (limitIfaces == INTERFACES_ALL
- || CollectionUtils.contains(limitIfaces, e.iface)));
- }
-
- /**
- * Only keep entries with {@link #set} value less than {@link #SET_DEBUG_START}.
- *
- * <p>This mutates the original structure in place.
- * @hide
- */
- public void filterDebugEntries() {
- filter(e -> e.set < SET_DEBUG_START);
- }
-
- private void filter(Predicate<Entry> predicate) {
- Entry entry = new Entry();
- int nextOutputEntry = 0;
- for (int i = 0; i < size; i++) {
- entry = getValues(i, entry);
- if (predicate.test(entry)) {
- if (nextOutputEntry != i) {
- setValues(nextOutputEntry, entry);
- }
- nextOutputEntry++;
- }
- }
- size = nextOutputEntry;
- }
-
- /** @hide */
- public void dump(String prefix, PrintWriter pw) {
- pw.print(prefix);
- pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime);
- for (int i = 0; i < size; i++) {
- pw.print(prefix);
- pw.print(" ["); pw.print(i); pw.print("]");
- pw.print(" iface="); pw.print(iface[i]);
- pw.print(" uid="); pw.print(uid[i]);
- pw.print(" set="); pw.print(setToString(set[i]));
- pw.print(" tag="); pw.print(tagToString(tag[i]));
- pw.print(" metered="); pw.print(meteredToString(metered[i]));
- pw.print(" roaming="); pw.print(roamingToString(roaming[i]));
- pw.print(" defaultNetwork="); pw.print(defaultNetworkToString(defaultNetwork[i]));
- pw.print(" rxBytes="); pw.print(rxBytes[i]);
- pw.print(" rxPackets="); pw.print(rxPackets[i]);
- pw.print(" txBytes="); pw.print(txBytes[i]);
- pw.print(" txPackets="); pw.print(txPackets[i]);
- pw.print(" operations="); pw.println(operations[i]);
- }
- }
-
- /**
- * Return text description of {@link #set} value.
- * @hide
- */
- public static String setToString(int set) {
- switch (set) {
- case SET_ALL:
- return "ALL";
- case SET_DEFAULT:
- return "DEFAULT";
- case SET_FOREGROUND:
- return "FOREGROUND";
- case SET_DBG_VPN_IN:
- return "DBG_VPN_IN";
- case SET_DBG_VPN_OUT:
- return "DBG_VPN_OUT";
- default:
- return "UNKNOWN";
- }
- }
-
- /**
- * Return text description of {@link #set} value.
- * @hide
- */
- public static String setToCheckinString(int set) {
- switch (set) {
- case SET_ALL:
- return "all";
- case SET_DEFAULT:
- return "def";
- case SET_FOREGROUND:
- return "fg";
- case SET_DBG_VPN_IN:
- return "vpnin";
- case SET_DBG_VPN_OUT:
- return "vpnout";
- default:
- return "unk";
- }
- }
-
- /**
- * @return true if the querySet matches the dataSet.
- * @hide
- */
- public static boolean setMatches(int querySet, int dataSet) {
- if (querySet == dataSet) {
- return true;
- }
- // SET_ALL matches all non-debugging sets.
- return querySet == SET_ALL && dataSet < SET_DEBUG_START;
- }
-
- /**
- * Return text description of {@link #tag} value.
- * @hide
- */
- public static String tagToString(int tag) {
- return "0x" + Integer.toHexString(tag);
- }
-
- /**
- * Return text description of {@link #metered} value.
- * @hide
- */
- public static String meteredToString(int metered) {
- switch (metered) {
- case METERED_ALL:
- return "ALL";
- case METERED_NO:
- return "NO";
- case METERED_YES:
- return "YES";
- default:
- return "UNKNOWN";
- }
- }
-
- /**
- * Return text description of {@link #roaming} value.
- * @hide
- */
- public static String roamingToString(int roaming) {
- switch (roaming) {
- case ROAMING_ALL:
- return "ALL";
- case ROAMING_NO:
- return "NO";
- case ROAMING_YES:
- return "YES";
- default:
- return "UNKNOWN";
- }
- }
-
- /**
- * Return text description of {@link #defaultNetwork} value.
- * @hide
- */
- public static String defaultNetworkToString(int defaultNetwork) {
- switch (defaultNetwork) {
- case DEFAULT_NETWORK_ALL:
- return "ALL";
- case DEFAULT_NETWORK_NO:
- return "NO";
- case DEFAULT_NETWORK_YES:
- return "YES";
- default:
- return "UNKNOWN";
- }
- }
-
- /** @hide */
- @Override
- public String toString() {
- final CharArrayWriter writer = new CharArrayWriter();
- dump("", new PrintWriter(writer));
- return writer.toString();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final @NonNull Creator<NetworkStats> CREATOR = new Creator<NetworkStats>() {
- @Override
- public NetworkStats createFromParcel(Parcel in) {
- return new NetworkStats(in);
- }
-
- @Override
- public NetworkStats[] newArray(int size) {
- return new NetworkStats[size];
- }
- };
-
- /** @hide */
- public interface NonMonotonicObserver<C> {
- public void foundNonMonotonic(
- NetworkStats left, int leftIndex, NetworkStats right, int rightIndex, C cookie);
- public void foundNonMonotonic(
- NetworkStats stats, int statsIndex, C cookie);
- }
-
- /**
- * VPN accounting. Move some VPN's underlying traffic to other UIDs that use tun0 iface.
- *
- * <p>This method should only be called on delta NetworkStats. Do not call this method on a
- * snapshot {@link NetworkStats} object because the tunUid and/or the underlyingIface may change
- * over time.
- *
- * <p>This method performs adjustments for one active VPN package and one VPN iface at a time.
- *
- * @param tunUid uid of the VPN application
- * @param tunIface iface of the vpn tunnel
- * @param underlyingIfaces underlying network ifaces used by the VPN application
- * @hide
- */
- public void migrateTun(int tunUid, @NonNull String tunIface,
- @NonNull List<String> underlyingIfaces) {
- // Combined usage by all apps using VPN.
- final Entry tunIfaceTotal = new Entry();
- // Usage by VPN, grouped by its {@code underlyingIfaces}.
- final Entry[] perInterfaceTotal = new Entry[underlyingIfaces.size()];
- // Usage by VPN, summed across all its {@code underlyingIfaces}.
- final Entry underlyingIfacesTotal = new Entry();
-
- for (int i = 0; i < perInterfaceTotal.length; i++) {
- perInterfaceTotal[i] = new Entry();
- }
-
- tunAdjustmentInit(tunUid, tunIface, underlyingIfaces, tunIfaceTotal, perInterfaceTotal,
- underlyingIfacesTotal);
-
- // If tunIface < underlyingIfacesTotal, it leaves the overhead traffic in the VPN app.
- // If tunIface > underlyingIfacesTotal, the VPN app doesn't get credit for data compression.
- // Negative stats should be avoided.
- final Entry[] moved =
- addTrafficToApplications(tunUid, tunIface, underlyingIfaces, tunIfaceTotal,
- perInterfaceTotal, underlyingIfacesTotal);
- deductTrafficFromVpnApp(tunUid, underlyingIfaces, moved);
- }
-
- /**
- * Initializes the data used by the migrateTun() method.
- *
- * <p>This is the first pass iteration which does the following work:
- *
- * <ul>
- * <li>Adds up all the traffic through the tunUid's underlyingIfaces (both foreground and
- * background).
- * <li>Adds up all the traffic through tun0 excluding traffic from the vpn app itself.
- * </ul>
- *
- * @param tunUid uid of the VPN application
- * @param tunIface iface of the vpn tunnel
- * @param underlyingIfaces underlying network ifaces used by the VPN application
- * @param tunIfaceTotal output parameter; combined data usage by all apps using VPN
- * @param perInterfaceTotal output parameter; data usage by VPN app, grouped by its {@code
- * underlyingIfaces}
- * @param underlyingIfacesTotal output parameter; data usage by VPN, summed across all of its
- * {@code underlyingIfaces}
- */
- private void tunAdjustmentInit(int tunUid, @NonNull String tunIface,
- @NonNull List<String> underlyingIfaces, @NonNull Entry tunIfaceTotal,
- @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
- final Entry recycle = new Entry();
- for (int i = 0; i < size; i++) {
- getValues(i, recycle);
- if (recycle.uid == UID_ALL) {
- throw new IllegalStateException(
- "Cannot adjust VPN accounting on an iface aggregated NetworkStats.");
- }
- if (recycle.set == SET_DBG_VPN_IN || recycle.set == SET_DBG_VPN_OUT) {
- throw new IllegalStateException(
- "Cannot adjust VPN accounting on a NetworkStats containing SET_DBG_VPN_*");
- }
- if (recycle.tag != TAG_NONE) {
- // TODO(b/123666283): Take all tags for tunUid into account.
- continue;
- }
-
- if (tunUid == Process.SYSTEM_UID) {
- // Kernel-based VPN or VCN, traffic sent by apps on the VPN/VCN network
- //
- // Since the data is not UID-accounted on underlying networks, just use VPN/VCN
- // network usage as ground truth. Encrypted traffic on the underlying networks will
- // never be processed here because encrypted traffic on the underlying interfaces
- // is not present in UID stats, and this method is only called on UID stats.
- if (tunIface.equals(recycle.iface)) {
- tunIfaceTotal.add(recycle);
- underlyingIfacesTotal.add(recycle);
-
- // In steady state, there should always be one network, but edge cases may
- // result in the network being null (network lost), and thus no underlying
- // ifaces is possible.
- if (perInterfaceTotal.length > 0) {
- // While platform VPNs and VCNs have exactly one underlying network, that
- // network may have multiple interfaces (eg for 464xlat). This layer does
- // not have the required information to identify which of the interfaces
- // were used. Select "any" of the interfaces. Since overhead is already
- // lost, this number is an approximation anyways.
- perInterfaceTotal[0].add(recycle);
- }
- }
- } else if (recycle.uid == tunUid) {
- // VpnService VPN, traffic sent by the VPN app over underlying networks
- for (int j = 0; j < underlyingIfaces.size(); j++) {
- if (Objects.equals(underlyingIfaces.get(j), recycle.iface)) {
- perInterfaceTotal[j].add(recycle);
- underlyingIfacesTotal.add(recycle);
- break;
- }
- }
- } else if (tunIface.equals(recycle.iface)) {
- // VpnService VPN; traffic sent by apps on the VPN network
- tunIfaceTotal.add(recycle);
- }
- }
- }
-
- /**
- * Distributes traffic across apps that are using given {@code tunIface}, and returns the total
- * traffic that should be moved off of {@code tunUid} grouped by {@code underlyingIfaces}.
- *
- * @param tunUid uid of the VPN application
- * @param tunIface iface of the vpn tunnel
- * @param underlyingIfaces underlying network ifaces used by the VPN application
- * @param tunIfaceTotal combined data usage across all apps using {@code tunIface}
- * @param perInterfaceTotal data usage by VPN app, grouped by its {@code underlyingIfaces}
- * @param underlyingIfacesTotal data usage by VPN, summed across all of its {@code
- * underlyingIfaces}
- */
- private Entry[] addTrafficToApplications(int tunUid, @NonNull String tunIface,
- @NonNull List<String> underlyingIfaces, @NonNull Entry tunIfaceTotal,
- @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
- // Traffic that should be moved off of each underlying interface for tunUid (see
- // deductTrafficFromVpnApp below).
- final Entry[] moved = new Entry[underlyingIfaces.size()];
- for (int i = 0; i < underlyingIfaces.size(); i++) {
- moved[i] = new Entry();
- }
-
- final Entry tmpEntry = new Entry();
- final int origSize = size;
- for (int i = 0; i < origSize; i++) {
- if (!Objects.equals(iface[i], tunIface)) {
- // Consider only entries that go onto the VPN interface.
- continue;
- }
-
- if (uid[i] == tunUid && tunUid != Process.SYSTEM_UID) {
- // Exclude VPN app from the redistribution, as it can choose to create packet
- // streams by writing to itself.
- //
- // However, for platform VPNs, do not exclude the system's usage of the VPN network,
- // since it is never local-only, and never double counted
- continue;
- }
- tmpEntry.uid = uid[i];
- tmpEntry.tag = tag[i];
- tmpEntry.metered = metered[i];
- tmpEntry.roaming = roaming[i];
- tmpEntry.defaultNetwork = defaultNetwork[i];
-
- // In a first pass, compute this entry's total share of data across all
- // underlyingIfaces. This is computed on the basis of the share of this entry's usage
- // over tunIface.
- // TODO: Consider refactoring first pass into a separate helper method.
- long totalRxBytes = 0;
- if (tunIfaceTotal.rxBytes > 0) {
- // Note - The multiplication below should not overflow since NetworkStatsService
- // processes this every time device has transmitted/received amount equivalent to
- // global threshold alert (~ 2MB) across all interfaces.
- final long rxBytesAcrossUnderlyingIfaces =
- multiplySafeByRational(underlyingIfacesTotal.rxBytes,
- rxBytes[i], tunIfaceTotal.rxBytes);
- // app must not be blamed for more than it consumed on tunIface
- totalRxBytes = Math.min(rxBytes[i], rxBytesAcrossUnderlyingIfaces);
- }
- long totalRxPackets = 0;
- if (tunIfaceTotal.rxPackets > 0) {
- final long rxPacketsAcrossUnderlyingIfaces =
- multiplySafeByRational(underlyingIfacesTotal.rxPackets,
- rxPackets[i], tunIfaceTotal.rxPackets);
- totalRxPackets = Math.min(rxPackets[i], rxPacketsAcrossUnderlyingIfaces);
- }
- long totalTxBytes = 0;
- if (tunIfaceTotal.txBytes > 0) {
- final long txBytesAcrossUnderlyingIfaces =
- multiplySafeByRational(underlyingIfacesTotal.txBytes,
- txBytes[i], tunIfaceTotal.txBytes);
- totalTxBytes = Math.min(txBytes[i], txBytesAcrossUnderlyingIfaces);
- }
- long totalTxPackets = 0;
- if (tunIfaceTotal.txPackets > 0) {
- final long txPacketsAcrossUnderlyingIfaces =
- multiplySafeByRational(underlyingIfacesTotal.txPackets,
- txPackets[i], tunIfaceTotal.txPackets);
- totalTxPackets = Math.min(txPackets[i], txPacketsAcrossUnderlyingIfaces);
- }
- long totalOperations = 0;
- if (tunIfaceTotal.operations > 0) {
- final long operationsAcrossUnderlyingIfaces =
- multiplySafeByRational(underlyingIfacesTotal.operations,
- operations[i], tunIfaceTotal.operations);
- totalOperations = Math.min(operations[i], operationsAcrossUnderlyingIfaces);
- }
- // In a second pass, distribute these values across interfaces in the proportion that
- // each interface represents of the total traffic of the underlying interfaces.
- for (int j = 0; j < underlyingIfaces.size(); j++) {
- tmpEntry.iface = underlyingIfaces.get(j);
- tmpEntry.rxBytes = 0;
- // Reset 'set' to correct value since it gets updated when adding debug info below.
- tmpEntry.set = set[i];
- if (underlyingIfacesTotal.rxBytes > 0) {
- tmpEntry.rxBytes =
- multiplySafeByRational(totalRxBytes,
- perInterfaceTotal[j].rxBytes,
- underlyingIfacesTotal.rxBytes);
- }
- tmpEntry.rxPackets = 0;
- if (underlyingIfacesTotal.rxPackets > 0) {
- tmpEntry.rxPackets =
- multiplySafeByRational(totalRxPackets,
- perInterfaceTotal[j].rxPackets,
- underlyingIfacesTotal.rxPackets);
- }
- tmpEntry.txBytes = 0;
- if (underlyingIfacesTotal.txBytes > 0) {
- tmpEntry.txBytes =
- multiplySafeByRational(totalTxBytes,
- perInterfaceTotal[j].txBytes,
- underlyingIfacesTotal.txBytes);
- }
- tmpEntry.txPackets = 0;
- if (underlyingIfacesTotal.txPackets > 0) {
- tmpEntry.txPackets =
- multiplySafeByRational(totalTxPackets,
- perInterfaceTotal[j].txPackets,
- underlyingIfacesTotal.txPackets);
- }
- tmpEntry.operations = 0;
- if (underlyingIfacesTotal.operations > 0) {
- tmpEntry.operations =
- multiplySafeByRational(totalOperations,
- perInterfaceTotal[j].operations,
- underlyingIfacesTotal.operations);
- }
- // tmpEntry now contains the migrated data of the i-th entry for the j-th underlying
- // interface. Add that data usage to this object.
- combineValues(tmpEntry);
- if (tag[i] == TAG_NONE) {
- // Add the migrated data to moved so it is deducted from the VPN app later.
- moved[j].add(tmpEntry);
- // Add debug info
- tmpEntry.set = SET_DBG_VPN_IN;
- combineValues(tmpEntry);
- }
- }
- }
- return moved;
- }
-
- private void deductTrafficFromVpnApp(
- int tunUid,
- @NonNull List<String> underlyingIfaces,
- @NonNull Entry[] moved) {
- if (tunUid == Process.SYSTEM_UID) {
- // No traffic recorded on a per-UID basis for in-kernel VPN/VCNs over underlying
- // networks; thus no traffic to deduct.
- return;
- }
-
- for (int i = 0; i < underlyingIfaces.size(); i++) {
- moved[i].uid = tunUid;
- // Add debug info
- moved[i].set = SET_DBG_VPN_OUT;
- moved[i].tag = TAG_NONE;
- moved[i].iface = underlyingIfaces.get(i);
- moved[i].metered = METERED_ALL;
- moved[i].roaming = ROAMING_ALL;
- moved[i].defaultNetwork = DEFAULT_NETWORK_ALL;
- combineValues(moved[i]);
-
- // Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
- // the TAG_NONE traffic.
- //
- // Relies on the fact that the underlying traffic only has state ROAMING_NO and
- // METERED_NO, which should be the case as it comes directly from the /proc file.
- // We only blend in the roaming data after applying these adjustments, by checking the
- // NetworkIdentity of the underlying iface.
- final int idxVpnBackground = findIndex(underlyingIfaces.get(i), tunUid, SET_DEFAULT,
- TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
- if (idxVpnBackground != -1) {
- // Note - tunSubtract also updates moved[i]; whatever traffic that's left is removed
- // from foreground usage.
- tunSubtract(idxVpnBackground, this, moved[i]);
- }
-
- final int idxVpnForeground = findIndex(underlyingIfaces.get(i), tunUid, SET_FOREGROUND,
- TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
- if (idxVpnForeground != -1) {
- tunSubtract(idxVpnForeground, this, moved[i]);
- }
- }
- }
-
- private static void tunSubtract(int i, @NonNull NetworkStats left, @NonNull Entry right) {
- long rxBytes = Math.min(left.rxBytes[i], right.rxBytes);
- left.rxBytes[i] -= rxBytes;
- right.rxBytes -= rxBytes;
-
- long rxPackets = Math.min(left.rxPackets[i], right.rxPackets);
- left.rxPackets[i] -= rxPackets;
- right.rxPackets -= rxPackets;
-
- long txBytes = Math.min(left.txBytes[i], right.txBytes);
- left.txBytes[i] -= txBytes;
- right.txBytes -= txBytes;
-
- long txPackets = Math.min(left.txPackets[i], right.txPackets);
- left.txPackets[i] -= txPackets;
- right.txPackets -= txPackets;
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsAccess.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsAccess.java
deleted file mode 100644
index b64fbdb..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsAccess.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.NetworkStats.UID_ALL;
-import static android.net.TrafficStats.UID_REMOVED;
-import static android.net.TrafficStats.UID_TETHERING;
-
-import android.Manifest;
-import android.annotation.IntDef;
-import android.app.AppOpsManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.os.Process;
-import android.os.UserHandle;
-import android.telephony.TelephonyManager;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Utility methods for controlling access to network stats APIs.
- *
- * @hide
- */
-public final class NetworkStatsAccess {
- private NetworkStatsAccess() {}
-
- /**
- * Represents an access level for the network usage history and statistics APIs.
- *
- * <p>Access levels are in increasing order; that is, it is reasonable to check access by
- * verifying that the caller's access level is at least the minimum required level.
- */
- @IntDef({
- Level.DEFAULT,
- Level.USER,
- Level.DEVICESUMMARY,
- Level.DEVICE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Level {
- /**
- * Default, unprivileged access level.
- *
- * <p>Can only access usage for one's own UID.
- *
- * <p>Every app will have at least this access level.
- */
- int DEFAULT = 0;
-
- /**
- * Access level for apps which can access usage for any app running in the same user.
- *
- * <p>Granted to:
- * <ul>
- * <li>Profile owners.
- * </ul>
- */
- int USER = 1;
-
- /**
- * Access level for apps which can access usage summary of device. Device summary includes
- * usage by apps running in any profiles/users, however this access level does not
- * allow querying usage of individual apps running in other profiles/users.
- *
- * <p>Granted to:
- * <ul>
- * <li>Apps with the PACKAGE_USAGE_STATS permission granted. Note that this is an AppOps bit
- * so it is not necessarily sufficient to declare this in the manifest.
- * <li>Apps with the (signature/privileged) READ_NETWORK_USAGE_HISTORY permission.
- * </ul>
- */
- int DEVICESUMMARY = 2;
-
- /**
- * Access level for apps which can access usage for any app on the device, including apps
- * running on other users/profiles.
- *
- * <p>Granted to:
- * <ul>
- * <li>Device owners.
- * <li>Carrier-privileged applications.
- * <li>The system UID.
- * </ul>
- */
- int DEVICE = 3;
- }
-
- /** Returns the {@link NetworkStatsAccess.Level} for the given caller. */
- public static @NetworkStatsAccess.Level int checkAccessLevel(
- Context context, int callingPid, int callingUid, String callingPackage) {
- final DevicePolicyManager mDpm = context.getSystemService(DevicePolicyManager.class);
- final TelephonyManager tm = (TelephonyManager)
- context.getSystemService(Context.TELEPHONY_SERVICE);
- boolean hasCarrierPrivileges;
- final long token = Binder.clearCallingIdentity();
- try {
- hasCarrierPrivileges = tm != null
- && tm.checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
- == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
-
- final boolean isDeviceOwner = mDpm != null && mDpm.isDeviceOwnerApp(callingPackage);
- final int appId = UserHandle.getAppId(callingUid);
-
- final boolean isNetworkStack = context.checkPermission(
- android.Manifest.permission.NETWORK_STACK, callingPid, callingUid)
- == PERMISSION_GRANTED;
-
- if (hasCarrierPrivileges || isDeviceOwner
- || appId == Process.SYSTEM_UID || isNetworkStack) {
- // Carrier-privileged apps and device owners, and the system (including the
- // network stack) can access data usage for all apps on the device.
- return NetworkStatsAccess.Level.DEVICE;
- }
-
- boolean hasAppOpsPermission = hasAppOpsPermission(context, callingUid, callingPackage);
- if (hasAppOpsPermission || context.checkCallingOrSelfPermission(
- READ_NETWORK_USAGE_HISTORY) == PackageManager.PERMISSION_GRANTED) {
- return NetworkStatsAccess.Level.DEVICESUMMARY;
- }
-
- //TODO(b/169395065) Figure out if this flow makes sense in Device Owner mode.
- boolean isProfileOwner = mDpm != null && (mDpm.isProfileOwnerApp(callingPackage)
- || mDpm.isDeviceOwnerApp(callingPackage));
- if (isProfileOwner) {
- // Apps with the AppOps permission, profile owners, and apps with the privileged
- // permission can access data usage for all apps in this user/profile.
- return NetworkStatsAccess.Level.USER;
- }
-
- // Everyone else gets default access (only to their own UID).
- return NetworkStatsAccess.Level.DEFAULT;
- }
-
- /**
- * Returns whether the given caller should be able to access the given UID when the caller has
- * the given {@link NetworkStatsAccess.Level}.
- */
- public static boolean isAccessibleToUser(int uid, int callerUid,
- @NetworkStatsAccess.Level int accessLevel) {
- final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
- final int callerUserId = UserHandle.getUserHandleForUid(callerUid).getIdentifier();
- switch (accessLevel) {
- case NetworkStatsAccess.Level.DEVICE:
- // Device-level access - can access usage for any uid.
- return true;
- case NetworkStatsAccess.Level.DEVICESUMMARY:
- // Can access usage for any app running in the same user, along
- // with some special uids (system, removed, or tethering) and
- // anonymized uids
- return uid == android.os.Process.SYSTEM_UID || uid == UID_REMOVED
- || uid == UID_TETHERING || uid == UID_ALL
- || userId == callerUserId;
- case NetworkStatsAccess.Level.USER:
- // User-level access - can access usage for any app running in the same user, along
- // with some special uids (system, removed, or tethering).
- return uid == android.os.Process.SYSTEM_UID || uid == UID_REMOVED
- || uid == UID_TETHERING
- || userId == callerUserId;
- case NetworkStatsAccess.Level.DEFAULT:
- default:
- // Default access level - can only access one's own usage.
- return uid == callerUid;
- }
- }
-
- private static boolean hasAppOpsPermission(
- Context context, int callingUid, String callingPackage) {
- if (callingPackage != null) {
- AppOpsManager appOps = (AppOpsManager) context.getSystemService(
- Context.APP_OPS_SERVICE);
-
- final int mode = appOps.noteOp(AppOpsManager.OPSTR_GET_USAGE_STATS,
- callingUid, callingPackage, null /* attributionTag */, null /* message */);
- if (mode == AppOpsManager.MODE_DEFAULT) {
- // The default behavior here is to check if PackageManager has given the app
- // permission.
- final int permissionCheck = context.checkCallingPermission(
- Manifest.permission.PACKAGE_USAGE_STATS);
- return permissionCheck == PackageManager.PERMISSION_GRANTED;
- }
- return (mode == AppOpsManager.MODE_ALLOWED);
- }
- return false;
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
deleted file mode 100644
index e385b33..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
+++ /dev/null
@@ -1,956 +0,0 @@
-/*
- * Copyright (C) 2012 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.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
-import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
-import static android.net.NetworkStats.IFACE_ALL;
-import static android.net.NetworkStats.METERED_NO;
-import static android.net.NetworkStats.METERED_YES;
-import static android.net.NetworkStats.ROAMING_NO;
-import static android.net.NetworkStats.ROAMING_YES;
-import static android.net.NetworkStats.SET_ALL;
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-import static android.net.TrafficStats.UID_REMOVED;
-import static android.text.format.DateUtils.WEEK_IN_MILLIS;
-
-import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.NetworkStats.State;
-import android.net.NetworkStatsHistory.Entry;
-import android.os.Binder;
-import android.service.NetworkStatsCollectionKeyProto;
-import android.service.NetworkStatsCollectionProto;
-import android.service.NetworkStatsCollectionStatsProto;
-import android.telephony.SubscriptionPlan;
-import android.text.format.DateUtils;
-import android.util.ArrayMap;
-import android.util.AtomicFile;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.Range;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FileRotator;
-import com.android.net.module.util.CollectionUtils;
-import com.android.net.module.util.NetworkStatsUtils;
-
-import libcore.io.IoUtils;
-
-import java.io.BufferedInputStream;
-import java.io.DataInput;
-import java.io.DataInputStream;
-import java.io.DataOutput;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.net.ProtocolException;
-import java.time.ZonedDateTime;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Collection of {@link NetworkStatsHistory}, stored based on combined key of
- * {@link NetworkIdentitySet}, UID, set, and tag. Knows how to persist itself.
- *
- * @hide
- */
-@SystemApi(client = MODULE_LIBRARIES)
-public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.Writer {
- private static final String TAG = NetworkStatsCollection.class.getSimpleName();
- /** File header magic number: "ANET" */
- private static final int FILE_MAGIC = 0x414E4554;
-
- private static final int VERSION_NETWORK_INIT = 1;
-
- private static final int VERSION_UID_INIT = 1;
- private static final int VERSION_UID_WITH_IDENT = 2;
- private static final int VERSION_UID_WITH_TAG = 3;
- private static final int VERSION_UID_WITH_SET = 4;
-
- private static final int VERSION_UNIFIED_INIT = 16;
-
- private ArrayMap<Key, NetworkStatsHistory> mStats = new ArrayMap<>();
-
- private final long mBucketDurationMillis;
-
- private long mStartMillis;
- private long mEndMillis;
- private long mTotalBytes;
- private boolean mDirty;
-
- /**
- * Construct a {@link NetworkStatsCollection} object.
- *
- * @param bucketDuration duration of the buckets in this object, in milliseconds.
- * @hide
- */
- public NetworkStatsCollection(long bucketDurationMillis) {
- mBucketDurationMillis = bucketDurationMillis;
- reset();
- }
-
- /** @hide */
- public void clear() {
- reset();
- }
-
- /** @hide */
- public void reset() {
- mStats.clear();
- mStartMillis = Long.MAX_VALUE;
- mEndMillis = Long.MIN_VALUE;
- mTotalBytes = 0;
- mDirty = false;
- }
-
- /** @hide */
- public long getStartMillis() {
- return mStartMillis;
- }
-
- /**
- * Return first atomic bucket in this collection, which is more conservative
- * than {@link #mStartMillis}.
- * @hide
- */
- public long getFirstAtomicBucketMillis() {
- if (mStartMillis == Long.MAX_VALUE) {
- return Long.MAX_VALUE;
- } else {
- return mStartMillis + mBucketDurationMillis;
- }
- }
-
- /** @hide */
- public long getEndMillis() {
- return mEndMillis;
- }
-
- /** @hide */
- public long getTotalBytes() {
- return mTotalBytes;
- }
-
- /** @hide */
- public boolean isDirty() {
- return mDirty;
- }
-
- /** @hide */
- public void clearDirty() {
- mDirty = false;
- }
-
- /** @hide */
- public boolean isEmpty() {
- return mStartMillis == Long.MAX_VALUE && mEndMillis == Long.MIN_VALUE;
- }
-
- /** @hide */
- @VisibleForTesting
- public long roundUp(long time) {
- if (time == Long.MIN_VALUE || time == Long.MAX_VALUE
- || time == SubscriptionPlan.TIME_UNKNOWN) {
- return time;
- } else {
- final long mod = time % mBucketDurationMillis;
- if (mod > 0) {
- time -= mod;
- time += mBucketDurationMillis;
- }
- return time;
- }
- }
-
- /** @hide */
- @VisibleForTesting
- public long roundDown(long time) {
- if (time == Long.MIN_VALUE || time == Long.MAX_VALUE
- || time == SubscriptionPlan.TIME_UNKNOWN) {
- return time;
- } else {
- final long mod = time % mBucketDurationMillis;
- if (mod > 0) {
- time -= mod;
- }
- return time;
- }
- }
-
- /** @hide */
- public int[] getRelevantUids(@NetworkStatsAccess.Level int accessLevel) {
- return getRelevantUids(accessLevel, Binder.getCallingUid());
- }
-
- /** @hide */
- public int[] getRelevantUids(@NetworkStatsAccess.Level int accessLevel,
- final int callerUid) {
- final ArrayList<Integer> uids = new ArrayList<>();
- for (int i = 0; i < mStats.size(); i++) {
- final Key key = mStats.keyAt(i);
- if (NetworkStatsAccess.isAccessibleToUser(key.uid, callerUid, accessLevel)) {
- int j = Collections.binarySearch(uids, new Integer(key.uid));
-
- if (j < 0) {
- j = ~j;
- uids.add(j, key.uid);
- }
- }
- }
- return CollectionUtils.toIntArray(uids);
- }
-
- /**
- * Combine all {@link NetworkStatsHistory} in this collection which match
- * the requested parameters.
- * @hide
- */
- public NetworkStatsHistory getHistory(NetworkTemplate template, SubscriptionPlan augmentPlan,
- int uid, int set, int tag, int fields, long start, long end,
- @NetworkStatsAccess.Level int accessLevel, int callerUid) {
- if (!NetworkStatsAccess.isAccessibleToUser(uid, callerUid, accessLevel)) {
- throw new SecurityException("Network stats history of uid " + uid
- + " is forbidden for caller " + callerUid);
- }
-
- // 180 days of history should be enough for anyone; if we end up needing
- // more, we'll dynamically grow the history object.
- final int bucketEstimate = (int) NetworkStatsUtils.constrain(
- ((end - start) / mBucketDurationMillis), 0,
- (180 * DateUtils.DAY_IN_MILLIS) / mBucketDurationMillis);
- final NetworkStatsHistory combined = new NetworkStatsHistory(
- mBucketDurationMillis, bucketEstimate, fields);
-
- // shortcut when we know stats will be empty
- if (start == end) return combined;
-
- // Figure out the window of time that we should be augmenting (if any)
- long augmentStart = SubscriptionPlan.TIME_UNKNOWN;
- long augmentEnd = (augmentPlan != null) ? augmentPlan.getDataUsageTime()
- : SubscriptionPlan.TIME_UNKNOWN;
- // And if augmenting, we might need to collect more data to adjust with
- long collectStart = start;
- long collectEnd = end;
-
- if (augmentEnd != SubscriptionPlan.TIME_UNKNOWN) {
- final Iterator<Range<ZonedDateTime>> it = augmentPlan.cycleIterator();
- while (it.hasNext()) {
- final Range<ZonedDateTime> cycle = it.next();
- final long cycleStart = cycle.getLower().toInstant().toEpochMilli();
- final long cycleEnd = cycle.getUpper().toInstant().toEpochMilli();
- if (cycleStart <= augmentEnd && augmentEnd < cycleEnd) {
- augmentStart = cycleStart;
- collectStart = Long.min(collectStart, augmentStart);
- collectEnd = Long.max(collectEnd, augmentEnd);
- break;
- }
- }
- }
-
- if (augmentStart != SubscriptionPlan.TIME_UNKNOWN) {
- // Shrink augmentation window so we don't risk undercounting.
- augmentStart = roundUp(augmentStart);
- augmentEnd = roundDown(augmentEnd);
- // Grow collection window so we get all the stats needed.
- collectStart = roundDown(collectStart);
- collectEnd = roundUp(collectEnd);
- }
-
- for (int i = 0; i < mStats.size(); i++) {
- final Key key = mStats.keyAt(i);
- if (key.uid == uid && NetworkStats.setMatches(set, key.set) && key.tag == tag
- && templateMatches(template, key.ident)) {
- final NetworkStatsHistory value = mStats.valueAt(i);
- combined.recordHistory(value, collectStart, collectEnd);
- }
- }
-
- if (augmentStart != SubscriptionPlan.TIME_UNKNOWN) {
- final NetworkStatsHistory.Entry entry = combined.getValues(
- augmentStart, augmentEnd, null);
-
- // If we don't have any recorded data for this time period, give
- // ourselves something to scale with.
- if (entry.rxBytes == 0 || entry.txBytes == 0) {
- combined.recordData(augmentStart, augmentEnd,
- new NetworkStats.Entry(1, 0, 1, 0, 0));
- combined.getValues(augmentStart, augmentEnd, entry);
- }
-
- final long rawBytes = (entry.rxBytes + entry.txBytes) == 0 ? 1 :
- (entry.rxBytes + entry.txBytes);
- final long rawRxBytes = entry.rxBytes == 0 ? 1 : entry.rxBytes;
- final long rawTxBytes = entry.txBytes == 0 ? 1 : entry.txBytes;
- final long targetBytes = augmentPlan.getDataUsageBytes();
-
- final long targetRxBytes = multiplySafeByRational(targetBytes, rawRxBytes, rawBytes);
- final long targetTxBytes = multiplySafeByRational(targetBytes, rawTxBytes, rawBytes);
-
-
- // Scale all matching buckets to reach anchor target
- final long beforeTotal = combined.getTotalBytes();
- for (int i = 0; i < combined.size(); i++) {
- combined.getValues(i, entry);
- if (entry.bucketStart >= augmentStart
- && entry.bucketStart + entry.bucketDuration <= augmentEnd) {
- entry.rxBytes = multiplySafeByRational(
- targetRxBytes, entry.rxBytes, rawRxBytes);
- entry.txBytes = multiplySafeByRational(
- targetTxBytes, entry.txBytes, rawTxBytes);
- // We purposefully clear out packet counters to indicate
- // that this data has been augmented.
- entry.rxPackets = 0;
- entry.txPackets = 0;
- combined.setValues(i, entry);
- }
- }
-
- final long deltaTotal = combined.getTotalBytes() - beforeTotal;
- if (deltaTotal != 0) {
- Log.d(TAG, "Augmented network usage by " + deltaTotal + " bytes");
- }
-
- // Finally we can slice data as originally requested
- final NetworkStatsHistory sliced = new NetworkStatsHistory(
- mBucketDurationMillis, bucketEstimate, fields);
- sliced.recordHistory(combined, start, end);
- return sliced;
- } else {
- return combined;
- }
- }
-
- /**
- * Summarize all {@link NetworkStatsHistory} in this collection which match
- * the requested parameters across the requested range.
- *
- * @param template - a predicate for filtering netstats.
- * @param start - start of the range, timestamp in milliseconds since the epoch.
- * @param end - end of the range, timestamp in milliseconds since the epoch.
- * @param accessLevel - caller access level.
- * @param callerUid - caller UID.
- * @hide
- */
- public NetworkStats getSummary(NetworkTemplate template, long start, long end,
- @NetworkStatsAccess.Level int accessLevel, int callerUid) {
- final long now = System.currentTimeMillis();
-
- final NetworkStats stats = new NetworkStats(end - start, 24);
-
- // shortcut when we know stats will be empty
- if (start == end) return stats;
-
- final NetworkStats.Entry entry = new NetworkStats.Entry();
- NetworkStatsHistory.Entry historyEntry = null;
-
- for (int i = 0; i < mStats.size(); i++) {
- final Key key = mStats.keyAt(i);
- if (templateMatches(template, key.ident)
- && NetworkStatsAccess.isAccessibleToUser(key.uid, callerUid, accessLevel)
- && key.set < NetworkStats.SET_DEBUG_START) {
- final NetworkStatsHistory value = mStats.valueAt(i);
- historyEntry = value.getValues(start, end, now, historyEntry);
-
- entry.iface = IFACE_ALL;
- entry.uid = key.uid;
- entry.set = key.set;
- entry.tag = key.tag;
- entry.defaultNetwork = key.ident.areAllMembersOnDefaultNetwork()
- ? DEFAULT_NETWORK_YES : DEFAULT_NETWORK_NO;
- entry.metered = key.ident.isAnyMemberMetered() ? METERED_YES : METERED_NO;
- entry.roaming = key.ident.isAnyMemberRoaming() ? ROAMING_YES : ROAMING_NO;
- entry.rxBytes = historyEntry.rxBytes;
- entry.rxPackets = historyEntry.rxPackets;
- entry.txBytes = historyEntry.txBytes;
- entry.txPackets = historyEntry.txPackets;
- entry.operations = historyEntry.operations;
-
- if (!entry.isEmpty()) {
- stats.combineValues(entry);
- }
- }
- }
-
- return stats;
- }
-
- /**
- * Record given {@link android.net.NetworkStats.Entry} into this collection.
- * @hide
- */
- public void recordData(NetworkIdentitySet ident, int uid, int set, int tag, long start,
- long end, NetworkStats.Entry entry) {
- final NetworkStatsHistory history = findOrCreateHistory(ident, uid, set, tag);
- history.recordData(start, end, entry);
- noteRecordedHistory(history.getStart(), history.getEnd(), entry.rxBytes + entry.txBytes);
- }
-
- /**
- * Record given {@link NetworkStatsHistory} into this collection.
- *
- * @hide
- */
- public void recordHistory(@NonNull Key key, @NonNull NetworkStatsHistory history) {
- Objects.requireNonNull(key);
- Objects.requireNonNull(history);
- if (history.size() == 0) return;
- noteRecordedHistory(history.getStart(), history.getEnd(), history.getTotalBytes());
-
- NetworkStatsHistory target = mStats.get(key);
- if (target == null) {
- target = new NetworkStatsHistory(history.getBucketDuration());
- mStats.put(key, target);
- }
- target.recordEntireHistory(history);
- }
-
- /**
- * Record all {@link NetworkStatsHistory} contained in the given collection
- * into this collection.
- *
- * @hide
- */
- public void recordCollection(@NonNull NetworkStatsCollection another) {
- Objects.requireNonNull(another);
- for (int i = 0; i < another.mStats.size(); i++) {
- final Key key = another.mStats.keyAt(i);
- final NetworkStatsHistory value = another.mStats.valueAt(i);
- recordHistory(key, value);
- }
- }
-
- private NetworkStatsHistory findOrCreateHistory(
- NetworkIdentitySet ident, int uid, int set, int tag) {
- final Key key = new Key(ident, uid, set, tag);
- final NetworkStatsHistory existing = mStats.get(key);
-
- // update when no existing, or when bucket duration changed
- NetworkStatsHistory updated = null;
- if (existing == null) {
- updated = new NetworkStatsHistory(mBucketDurationMillis, 10);
- } else if (existing.getBucketDuration() != mBucketDurationMillis) {
- updated = new NetworkStatsHistory(existing, mBucketDurationMillis);
- }
-
- if (updated != null) {
- mStats.put(key, updated);
- return updated;
- } else {
- return existing;
- }
- }
-
- /** @hide */
- @Override
- public void read(InputStream in) throws IOException {
- read((DataInput) new DataInputStream(in));
- }
-
- private void read(DataInput in) throws IOException {
- // verify file magic header intact
- final int magic = in.readInt();
- if (magic != FILE_MAGIC) {
- throw new ProtocolException("unexpected magic: " + magic);
- }
-
- final int version = in.readInt();
- switch (version) {
- case VERSION_UNIFIED_INIT: {
- // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory))
- final int identSize = in.readInt();
- for (int i = 0; i < identSize; i++) {
- final NetworkIdentitySet ident = new NetworkIdentitySet(in);
-
- final int size = in.readInt();
- for (int j = 0; j < size; j++) {
- final int uid = in.readInt();
- final int set = in.readInt();
- final int tag = in.readInt();
-
- final Key key = new Key(ident, uid, set, tag);
- final NetworkStatsHistory history = new NetworkStatsHistory(in);
- recordHistory(key, history);
- }
- }
- break;
- }
- default: {
- throw new ProtocolException("unexpected version: " + version);
- }
- }
- }
-
- /** @hide */
- @Override
- public void write(OutputStream out) throws IOException {
- write((DataOutput) new DataOutputStream(out));
- out.flush();
- }
-
- private void write(DataOutput out) throws IOException {
- // cluster key lists grouped by ident
- final HashMap<NetworkIdentitySet, ArrayList<Key>> keysByIdent = new HashMap<>();
- for (Key key : mStats.keySet()) {
- ArrayList<Key> keys = keysByIdent.get(key.ident);
- if (keys == null) {
- keys = new ArrayList<>();
- keysByIdent.put(key.ident, keys);
- }
- keys.add(key);
- }
-
- out.writeInt(FILE_MAGIC);
- out.writeInt(VERSION_UNIFIED_INIT);
-
- out.writeInt(keysByIdent.size());
- for (NetworkIdentitySet ident : keysByIdent.keySet()) {
- final ArrayList<Key> keys = keysByIdent.get(ident);
- ident.writeToStream(out);
-
- out.writeInt(keys.size());
- for (Key key : keys) {
- final NetworkStatsHistory history = mStats.get(key);
- out.writeInt(key.uid);
- out.writeInt(key.set);
- out.writeInt(key.tag);
- history.writeToStream(out);
- }
- }
- }
-
- /**
- * Read legacy network summary statistics file format into the collection,
- * See {@code NetworkStatsService#maybeUpgradeLegacyStatsLocked}.
- *
- * @deprecated
- * @hide
- */
- @Deprecated
- public void readLegacyNetwork(File file) throws IOException {
- final AtomicFile inputFile = new AtomicFile(file);
-
- DataInputStream in = null;
- try {
- in = new DataInputStream(new BufferedInputStream(inputFile.openRead()));
-
- // verify file magic header intact
- final int magic = in.readInt();
- if (magic != FILE_MAGIC) {
- throw new ProtocolException("unexpected magic: " + magic);
- }
-
- final int version = in.readInt();
- switch (version) {
- case VERSION_NETWORK_INIT: {
- // network := size *(NetworkIdentitySet NetworkStatsHistory)
- final int size = in.readInt();
- for (int i = 0; i < size; i++) {
- final NetworkIdentitySet ident = new NetworkIdentitySet(in);
- final NetworkStatsHistory history = new NetworkStatsHistory(in);
-
- final Key key = new Key(ident, UID_ALL, SET_ALL, TAG_NONE);
- recordHistory(key, history);
- }
- break;
- }
- default: {
- throw new ProtocolException("unexpected version: " + version);
- }
- }
- } catch (FileNotFoundException e) {
- // missing stats is okay, probably first boot
- } finally {
- IoUtils.closeQuietly(in);
- }
- }
-
- /**
- * Read legacy Uid statistics file format into the collection,
- * See {@code NetworkStatsService#maybeUpgradeLegacyStatsLocked}.
- *
- * @deprecated
- * @hide
- */
- @Deprecated
- public void readLegacyUid(File file, boolean onlyTags) throws IOException {
- final AtomicFile inputFile = new AtomicFile(file);
-
- DataInputStream in = null;
- try {
- in = new DataInputStream(new BufferedInputStream(inputFile.openRead()));
-
- // verify file magic header intact
- final int magic = in.readInt();
- if (magic != FILE_MAGIC) {
- throw new ProtocolException("unexpected magic: " + magic);
- }
-
- final int version = in.readInt();
- switch (version) {
- case VERSION_UID_INIT: {
- // uid := size *(UID NetworkStatsHistory)
-
- // drop this data version, since we don't have a good
- // mapping into NetworkIdentitySet.
- break;
- }
- case VERSION_UID_WITH_IDENT: {
- // uid := size *(NetworkIdentitySet size *(UID NetworkStatsHistory))
-
- // drop this data version, since this version only existed
- // for a short time.
- break;
- }
- case VERSION_UID_WITH_TAG:
- case VERSION_UID_WITH_SET: {
- // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory))
- final int identSize = in.readInt();
- for (int i = 0; i < identSize; i++) {
- final NetworkIdentitySet ident = new NetworkIdentitySet(in);
-
- final int size = in.readInt();
- for (int j = 0; j < size; j++) {
- final int uid = in.readInt();
- final int set = (version >= VERSION_UID_WITH_SET) ? in.readInt()
- : SET_DEFAULT;
- final int tag = in.readInt();
-
- final Key key = new Key(ident, uid, set, tag);
- final NetworkStatsHistory history = new NetworkStatsHistory(in);
-
- if ((tag == TAG_NONE) != onlyTags) {
- recordHistory(key, history);
- }
- }
- }
- break;
- }
- default: {
- throw new ProtocolException("unexpected version: " + version);
- }
- }
- } catch (FileNotFoundException e) {
- // missing stats is okay, probably first boot
- } finally {
- IoUtils.closeQuietly(in);
- }
- }
-
- /**
- * Remove any {@link NetworkStatsHistory} attributed to the requested UID,
- * moving any {@link NetworkStats#TAG_NONE} series to
- * {@link TrafficStats#UID_REMOVED}.
- * @hide
- */
- public void removeUids(int[] uids) {
- final ArrayList<Key> knownKeys = new ArrayList<>();
- knownKeys.addAll(mStats.keySet());
-
- // migrate all UID stats into special "removed" bucket
- for (Key key : knownKeys) {
- if (CollectionUtils.contains(uids, key.uid)) {
- // only migrate combined TAG_NONE history
- if (key.tag == TAG_NONE) {
- final NetworkStatsHistory uidHistory = mStats.get(key);
- final NetworkStatsHistory removedHistory = findOrCreateHistory(
- key.ident, UID_REMOVED, SET_DEFAULT, TAG_NONE);
- removedHistory.recordEntireHistory(uidHistory);
- }
- mStats.remove(key);
- mDirty = true;
- }
- }
- }
-
- private void noteRecordedHistory(long startMillis, long endMillis, long totalBytes) {
- if (startMillis < mStartMillis) mStartMillis = startMillis;
- if (endMillis > mEndMillis) mEndMillis = endMillis;
- mTotalBytes += totalBytes;
- mDirty = true;
- }
-
- private int estimateBuckets() {
- return (int) (Math.min(mEndMillis - mStartMillis, WEEK_IN_MILLIS * 5)
- / mBucketDurationMillis);
- }
-
- private ArrayList<Key> getSortedKeys() {
- final ArrayList<Key> keys = new ArrayList<>();
- keys.addAll(mStats.keySet());
- Collections.sort(keys, (left, right) -> Key.compare(left, right));
- return keys;
- }
-
- /** @hide */
- public void dump(IndentingPrintWriter pw) {
- for (Key key : getSortedKeys()) {
- pw.print("ident="); pw.print(key.ident.toString());
- pw.print(" uid="); pw.print(key.uid);
- pw.print(" set="); pw.print(NetworkStats.setToString(key.set));
- pw.print(" tag="); pw.println(NetworkStats.tagToString(key.tag));
-
- final NetworkStatsHistory history = mStats.get(key);
- pw.increaseIndent();
- history.dump(pw, true);
- pw.decreaseIndent();
- }
- }
-
- /** @hide */
- public void dumpDebug(ProtoOutputStream proto, long tag) {
- final long start = proto.start(tag);
-
- for (Key key : getSortedKeys()) {
- final long startStats = proto.start(NetworkStatsCollectionProto.STATS);
-
- // Key
- final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY);
- key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY);
- proto.write(NetworkStatsCollectionKeyProto.UID, key.uid);
- proto.write(NetworkStatsCollectionKeyProto.SET, key.set);
- proto.write(NetworkStatsCollectionKeyProto.TAG, key.tag);
- proto.end(startKey);
-
- // Value
- final NetworkStatsHistory history = mStats.get(key);
- history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY);
- proto.end(startStats);
- }
-
- proto.end(start);
- }
-
- /** @hide */
- public void dumpCheckin(PrintWriter pw, long start, long end) {
- dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateMobileWildcard(), "cell");
- dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateWifiWildcard(), "wifi");
- dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateEthernet(), "eth");
- dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateBluetooth(), "bt");
- }
-
- /**
- * Dump all contained stats that match requested parameters, but group
- * together all matching {@link NetworkTemplate} under a single prefix.
- */
- private void dumpCheckin(PrintWriter pw, long start, long end, NetworkTemplate groupTemplate,
- String groupPrefix) {
- final ArrayMap<Key, NetworkStatsHistory> grouped = new ArrayMap<>();
-
- // Walk through all history, grouping by matching network templates
- for (int i = 0; i < mStats.size(); i++) {
- final Key key = mStats.keyAt(i);
- final NetworkStatsHistory value = mStats.valueAt(i);
-
- if (!templateMatches(groupTemplate, key.ident)) continue;
- if (key.set >= NetworkStats.SET_DEBUG_START) continue;
-
- final Key groupKey = new Key(null, key.uid, key.set, key.tag);
- NetworkStatsHistory groupHistory = grouped.get(groupKey);
- if (groupHistory == null) {
- groupHistory = new NetworkStatsHistory(value.getBucketDuration());
- grouped.put(groupKey, groupHistory);
- }
- groupHistory.recordHistory(value, start, end);
- }
-
- for (int i = 0; i < grouped.size(); i++) {
- final Key key = grouped.keyAt(i);
- final NetworkStatsHistory value = grouped.valueAt(i);
-
- if (value.size() == 0) continue;
-
- pw.print("c,");
- pw.print(groupPrefix); pw.print(',');
- pw.print(key.uid); pw.print(',');
- pw.print(NetworkStats.setToCheckinString(key.set)); pw.print(',');
- pw.print(key.tag);
- pw.println();
-
- value.dumpCheckin(pw);
- }
- }
-
- /**
- * Test if given {@link NetworkTemplate} matches any {@link NetworkIdentity}
- * in the given {@link NetworkIdentitySet}.
- */
- private static boolean templateMatches(NetworkTemplate template, NetworkIdentitySet identSet) {
- for (NetworkIdentity ident : identSet) {
- if (template.matches(ident)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Get the all historical stats of the collection {@link NetworkStatsCollection}.
- *
- * @return All {@link NetworkStatsHistory} in this collection.
- */
- @NonNull
- public Map<Key, NetworkStatsHistory> getEntries() {
- return new ArrayMap(mStats);
- }
-
- /**
- * Builder class for {@link NetworkStatsCollection}.
- */
- public static final class Builder {
- private final long mBucketDurationMillis;
- private final ArrayMap<Key, NetworkStatsHistory> mEntries = new ArrayMap<>();
-
- /**
- * Creates a new Builder with given bucket duration.
- *
- * @param bucketDuration Duration of the buckets of the object, in milliseconds.
- */
- public Builder(long bucketDurationMillis) {
- mBucketDurationMillis = bucketDurationMillis;
- }
-
- /**
- * Add association of the history with the specified key in this map.
- *
- * @param key The object used to identify a network, see {@link Key}.
- * @param history {@link NetworkStatsHistory} instance associated to the given {@link Key}.
- * @return The builder object.
- */
- @NonNull
- public NetworkStatsCollection.Builder addEntry(@NonNull Key key,
- @NonNull NetworkStatsHistory history) {
- Objects.requireNonNull(key);
- Objects.requireNonNull(history);
- final List<Entry> historyEntries = history.getEntries();
-
- final NetworkStatsHistory.Builder historyBuilder =
- new NetworkStatsHistory.Builder(mBucketDurationMillis, historyEntries.size());
- for (Entry entry : historyEntries) {
- historyBuilder.addEntry(entry);
- }
-
- mEntries.put(key, historyBuilder.build());
- return this;
- }
-
- /**
- * Builds the instance of the {@link NetworkStatsCollection}.
- *
- * @return the built instance of {@link NetworkStatsCollection}.
- */
- @NonNull
- public NetworkStatsCollection build() {
- final NetworkStatsCollection collection =
- new NetworkStatsCollection(mBucketDurationMillis);
- for (int i = 0; i < mEntries.size(); i++) {
- collection.recordHistory(mEntries.keyAt(i), mEntries.valueAt(i));
- }
- return collection;
- }
- }
-
- /**
- * the identifier that associate with the {@link NetworkStatsHistory} object to identify
- * a certain record in the {@link NetworkStatsCollection} object.
- */
- public static final class Key {
- /** @hide */
- public final NetworkIdentitySet ident;
- /** @hide */
- public final int uid;
- /** @hide */
- public final int set;
- /** @hide */
- public final int tag;
-
- private final int mHashCode;
-
- /**
- * Construct a {@link Key} object.
- *
- * @param ident a Set of {@link NetworkIdentity} that associated with the record.
- * @param uid Uid of the record.
- * @param set Set of the record, see {@code NetworkStats#SET_*}.
- * @param tag Tag of the record, see {@link TrafficStats#setThreadStatsTag(int)}.
- */
- public Key(@NonNull Set<NetworkIdentity> ident, int uid, @State int set, int tag) {
- this(new NetworkIdentitySet(Objects.requireNonNull(ident)), uid, set, tag);
- }
-
- /** @hide */
- public Key(@NonNull NetworkIdentitySet ident, int uid, int set, int tag) {
- this.ident = Objects.requireNonNull(ident);
- this.uid = uid;
- this.set = set;
- this.tag = tag;
- mHashCode = Objects.hash(ident, uid, set, tag);
- }
-
- @Override
- public int hashCode() {
- return mHashCode;
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (obj instanceof Key) {
- final Key key = (Key) obj;
- return uid == key.uid && set == key.set && tag == key.tag
- && Objects.equals(ident, key.ident);
- }
- return false;
- }
-
- /** @hide */
- public static int compare(@NonNull Key left, @NonNull Key right) {
- Objects.requireNonNull(left);
- Objects.requireNonNull(right);
- int res = 0;
- if (left.ident != null && right.ident != null) {
- res = NetworkIdentitySet.compare(left.ident, right.ident);
- }
- if (res == 0) {
- res = Integer.compare(left.uid, right.uid);
- }
- if (res == 0) {
- res = Integer.compare(left.set, right.set);
- }
- if (res == 0) {
- res = Integer.compare(left.tag, right.tag);
- }
- return res;
- }
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.aidl b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.aidl
deleted file mode 100644
index 8b9069f..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2011, 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.net;
-
-parcelable NetworkStatsHistory;
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
deleted file mode 100644
index 301fef9..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
- * Copyright (C) 2011 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.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-import static android.net.NetworkStats.IFACE_ALL;
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-import static android.net.NetworkStatsHistory.DataStreamUtils.readFullLongArray;
-import static android.net.NetworkStatsHistory.DataStreamUtils.readVarLongArray;
-import static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLongArray;
-import static android.net.NetworkStatsHistory.Entry.UNKNOWN;
-import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray;
-import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
-import static android.text.format.DateUtils.SECOND_IN_MILLIS;
-
-import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.service.NetworkStatsHistoryBucketProto;
-import android.service.NetworkStatsHistoryProto;
-import android.util.IndentingPrintWriter;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.net.module.util.CollectionUtils;
-import com.android.net.module.util.NetworkStatsUtils;
-
-import libcore.util.EmptyArray;
-
-import java.io.CharArrayWriter;
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.ProtocolException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
-
-/**
- * Collection of historical network statistics, recorded into equally-sized
- * "buckets" in time. Internally it stores data in {@code long} series for more
- * efficient persistence.
- * <p>
- * Each bucket is defined by a {@link #bucketStart} timestamp, and lasts for
- * {@link #bucketDuration}. Internally assumes that {@link #bucketStart} is
- * sorted at all times.
- *
- * @hide
- */
-@SystemApi(client = MODULE_LIBRARIES)
-public final class NetworkStatsHistory implements Parcelable {
- private static final int VERSION_INIT = 1;
- private static final int VERSION_ADD_PACKETS = 2;
- private static final int VERSION_ADD_ACTIVE = 3;
-
- /** @hide */
- public static final int FIELD_ACTIVE_TIME = 0x01;
- /** @hide */
- public static final int FIELD_RX_BYTES = 0x02;
- /** @hide */
- public static final int FIELD_RX_PACKETS = 0x04;
- /** @hide */
- public static final int FIELD_TX_BYTES = 0x08;
- /** @hide */
- public static final int FIELD_TX_PACKETS = 0x10;
- /** @hide */
- public static final int FIELD_OPERATIONS = 0x20;
- /** @hide */
- public static final int FIELD_ALL = 0xFFFFFFFF;
-
- private long bucketDuration;
- private int bucketCount;
- private long[] bucketStart;
- private long[] activeTime;
- private long[] rxBytes;
- private long[] rxPackets;
- private long[] txBytes;
- private long[] txPackets;
- private long[] operations;
- private long totalBytes;
-
- /** @hide */
- public NetworkStatsHistory(long bucketDuration, long[] bucketStart, long[] activeTime,
- long[] rxBytes, long[] rxPackets, long[] txBytes, long[] txPackets,
- long[] operations, int bucketCount, long totalBytes) {
- this.bucketDuration = bucketDuration;
- this.bucketStart = bucketStart;
- this.activeTime = activeTime;
- this.rxBytes = rxBytes;
- this.rxPackets = rxPackets;
- this.txBytes = txBytes;
- this.txPackets = txPackets;
- this.operations = operations;
- this.bucketCount = bucketCount;
- this.totalBytes = totalBytes;
- }
-
- /**
- * An instance to represent a single record in a {@link NetworkStatsHistory} object.
- */
- public static final class Entry {
- /** @hide */
- public static final long UNKNOWN = -1;
-
- /** @hide */
- // TODO: Migrate all callers to get duration from the history object and remove this field.
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public long bucketDuration;
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public long bucketStart;
- /** @hide */
- public long activeTime;
- /** @hide */
- @UnsupportedAppUsage
- public long rxBytes;
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public long rxPackets;
- /** @hide */
- @UnsupportedAppUsage
- public long txBytes;
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public long txPackets;
- /** @hide */
- public long operations;
- /** @hide */
- Entry() {}
-
- /**
- * Construct a {@link Entry} instance to represent a single record in a
- * {@link NetworkStatsHistory} object.
- *
- * @param bucketStart Start of period for this {@link Entry}, in milliseconds since the
- * Unix epoch, see {@link java.lang.System#currentTimeMillis}.
- * @param activeTime Active time for this {@link Entry}, in milliseconds.
- * @param rxBytes Number of bytes received for this {@link Entry}. Statistics should
- * represent the contents of IP packets, including IP headers.
- * @param rxPackets Number of packets received for this {@link Entry}. Statistics should
- * represent the contents of IP packets, including IP headers.
- * @param txBytes Number of bytes transmitted for this {@link Entry}. Statistics should
- * represent the contents of IP packets, including IP headers.
- * @param txPackets Number of bytes transmitted for this {@link Entry}. Statistics should
- * represent the contents of IP packets, including IP headers.
- * @param operations count of network operations performed for this {@link Entry}. This can
- * be used to derive bytes-per-operation.
- */
- public Entry(long bucketStart, long activeTime, long rxBytes,
- long rxPackets, long txBytes, long txPackets, long operations) {
- this.bucketStart = bucketStart;
- this.activeTime = activeTime;
- this.rxBytes = rxBytes;
- this.rxPackets = rxPackets;
- this.txBytes = txBytes;
- this.txPackets = txPackets;
- this.operations = operations;
- }
-
- /**
- * Get start timestamp of the bucket's time interval, in milliseconds since the Unix epoch.
- */
- public long getBucketStart() {
- return bucketStart;
- }
-
- /**
- * Get active time of the bucket's time interval, in milliseconds.
- */
- public long getActiveTime() {
- return activeTime;
- }
-
- /** Get number of bytes received for this {@link Entry}. */
- public long getRxBytes() {
- return rxBytes;
- }
-
- /** Get number of packets received for this {@link Entry}. */
- public long getRxPackets() {
- return rxPackets;
- }
-
- /** Get number of bytes transmitted for this {@link Entry}. */
- public long getTxBytes() {
- return txBytes;
- }
-
- /** Get number of packets transmitted for this {@link Entry}. */
- public long getTxPackets() {
- return txPackets;
- }
-
- /** Get count of network operations performed for this {@link Entry}. */
- public long getOperations() {
- return operations;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o.getClass() != getClass()) return false;
- Entry entry = (Entry) o;
- return bucketStart == entry.bucketStart
- && activeTime == entry.activeTime && rxBytes == entry.rxBytes
- && rxPackets == entry.rxPackets && txBytes == entry.txBytes
- && txPackets == entry.txPackets && operations == entry.operations;
- }
-
- @Override
- public int hashCode() {
- return (int) (bucketStart * 2
- + activeTime * 3
- + rxBytes * 5
- + rxPackets * 7
- + txBytes * 11
- + txPackets * 13
- + operations * 17);
- }
-
- @Override
- public String toString() {
- return "Entry{"
- + "bucketStart=" + bucketStart
- + ", activeTime=" + activeTime
- + ", rxBytes=" + rxBytes
- + ", rxPackets=" + rxPackets
- + ", txBytes=" + txBytes
- + ", txPackets=" + txPackets
- + ", operations=" + operations
- + "}";
- }
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public NetworkStatsHistory(long bucketDuration) {
- this(bucketDuration, 10, FIELD_ALL);
- }
-
- /** @hide */
- public NetworkStatsHistory(long bucketDuration, int initialSize) {
- this(bucketDuration, initialSize, FIELD_ALL);
- }
-
- /** @hide */
- public NetworkStatsHistory(long bucketDuration, int initialSize, int fields) {
- this.bucketDuration = bucketDuration;
- bucketStart = new long[initialSize];
- if ((fields & FIELD_ACTIVE_TIME) != 0) activeTime = new long[initialSize];
- if ((fields & FIELD_RX_BYTES) != 0) rxBytes = new long[initialSize];
- if ((fields & FIELD_RX_PACKETS) != 0) rxPackets = new long[initialSize];
- if ((fields & FIELD_TX_BYTES) != 0) txBytes = new long[initialSize];
- if ((fields & FIELD_TX_PACKETS) != 0) txPackets = new long[initialSize];
- if ((fields & FIELD_OPERATIONS) != 0) operations = new long[initialSize];
- bucketCount = 0;
- totalBytes = 0;
- }
-
- /** @hide */
- public NetworkStatsHistory(NetworkStatsHistory existing, long bucketDuration) {
- this(bucketDuration, existing.estimateResizeBuckets(bucketDuration));
- recordEntireHistory(existing);
- }
-
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public NetworkStatsHistory(Parcel in) {
- bucketDuration = in.readLong();
- bucketStart = readLongArray(in);
- activeTime = readLongArray(in);
- rxBytes = readLongArray(in);
- rxPackets = readLongArray(in);
- txBytes = readLongArray(in);
- txPackets = readLongArray(in);
- operations = readLongArray(in);
- bucketCount = bucketStart.length;
- totalBytes = in.readLong();
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel out, int flags) {
- out.writeLong(bucketDuration);
- writeLongArray(out, bucketStart, bucketCount);
- writeLongArray(out, activeTime, bucketCount);
- writeLongArray(out, rxBytes, bucketCount);
- writeLongArray(out, rxPackets, bucketCount);
- writeLongArray(out, txBytes, bucketCount);
- writeLongArray(out, txPackets, bucketCount);
- writeLongArray(out, operations, bucketCount);
- out.writeLong(totalBytes);
- }
-
- /** @hide */
- public NetworkStatsHistory(DataInput in) throws IOException {
- final int version = in.readInt();
- switch (version) {
- case VERSION_INIT: {
- bucketDuration = in.readLong();
- bucketStart = readFullLongArray(in);
- rxBytes = readFullLongArray(in);
- rxPackets = new long[bucketStart.length];
- txBytes = readFullLongArray(in);
- txPackets = new long[bucketStart.length];
- operations = new long[bucketStart.length];
- bucketCount = bucketStart.length;
- totalBytes = CollectionUtils.total(rxBytes) + CollectionUtils.total(txBytes);
- break;
- }
- case VERSION_ADD_PACKETS:
- case VERSION_ADD_ACTIVE: {
- bucketDuration = in.readLong();
- bucketStart = readVarLongArray(in);
- activeTime = (version >= VERSION_ADD_ACTIVE) ? readVarLongArray(in)
- : new long[bucketStart.length];
- rxBytes = readVarLongArray(in);
- rxPackets = readVarLongArray(in);
- txBytes = readVarLongArray(in);
- txPackets = readVarLongArray(in);
- operations = readVarLongArray(in);
- bucketCount = bucketStart.length;
- totalBytes = CollectionUtils.total(rxBytes) + CollectionUtils.total(txBytes);
- break;
- }
- default: {
- throw new ProtocolException("unexpected version: " + version);
- }
- }
-
- if (bucketStart.length != bucketCount || rxBytes.length != bucketCount
- || rxPackets.length != bucketCount || txBytes.length != bucketCount
- || txPackets.length != bucketCount || operations.length != bucketCount) {
- throw new ProtocolException("Mismatched history lengths");
- }
- }
-
- /** @hide */
- public void writeToStream(DataOutput out) throws IOException {
- out.writeInt(VERSION_ADD_ACTIVE);
- out.writeLong(bucketDuration);
- writeVarLongArray(out, bucketStart, bucketCount);
- writeVarLongArray(out, activeTime, bucketCount);
- writeVarLongArray(out, rxBytes, bucketCount);
- writeVarLongArray(out, rxPackets, bucketCount);
- writeVarLongArray(out, txBytes, bucketCount);
- writeVarLongArray(out, txPackets, bucketCount);
- writeVarLongArray(out, operations, bucketCount);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public int size() {
- return bucketCount;
- }
-
- /** @hide */
- public long getBucketDuration() {
- return bucketDuration;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public long getStart() {
- if (bucketCount > 0) {
- return bucketStart[0];
- } else {
- return Long.MAX_VALUE;
- }
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public long getEnd() {
- if (bucketCount > 0) {
- return bucketStart[bucketCount - 1] + bucketDuration;
- } else {
- return Long.MIN_VALUE;
- }
- }
-
- /**
- * Return total bytes represented by this history.
- * @hide
- */
- public long getTotalBytes() {
- return totalBytes;
- }
-
- /**
- * Return index of bucket that contains or is immediately before the
- * requested time.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public int getIndexBefore(long time) {
- int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time);
- if (index < 0) {
- index = (~index) - 1;
- } else {
- index -= 1;
- }
- return NetworkStatsUtils.constrain(index, 0, bucketCount - 1);
- }
-
- /**
- * Return index of bucket that contains or is immediately after the
- * requested time.
- * @hide
- */
- public int getIndexAfter(long time) {
- int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time);
- if (index < 0) {
- index = ~index;
- } else {
- index += 1;
- }
- return NetworkStatsUtils.constrain(index, 0, bucketCount - 1);
- }
-
- /**
- * Return specific stats entry.
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public Entry getValues(int i, Entry recycle) {
- final Entry entry = recycle != null ? recycle : new Entry();
- entry.bucketStart = bucketStart[i];
- entry.bucketDuration = bucketDuration;
- entry.activeTime = getLong(activeTime, i, UNKNOWN);
- entry.rxBytes = getLong(rxBytes, i, UNKNOWN);
- entry.rxPackets = getLong(rxPackets, i, UNKNOWN);
- entry.txBytes = getLong(txBytes, i, UNKNOWN);
- entry.txPackets = getLong(txPackets, i, UNKNOWN);
- entry.operations = getLong(operations, i, UNKNOWN);
- return entry;
- }
-
- /**
- * Get List of {@link Entry} of the {@link NetworkStatsHistory} instance.
- *
- * @return
- */
- @NonNull
- public List<Entry> getEntries() {
- // TODO: Return a wrapper that uses this list instead, to prevent the returned result
- // from being changed.
- final ArrayList<Entry> ret = new ArrayList<>(size());
- for (int i = 0; i < size(); i++) {
- ret.add(getValues(i, null /* recycle */));
- }
- return ret;
- }
-
- /** @hide */
- public void setValues(int i, Entry entry) {
- // Unwind old values
- if (rxBytes != null) totalBytes -= rxBytes[i];
- if (txBytes != null) totalBytes -= txBytes[i];
-
- bucketStart[i] = entry.bucketStart;
- setLong(activeTime, i, entry.activeTime);
- setLong(rxBytes, i, entry.rxBytes);
- setLong(rxPackets, i, entry.rxPackets);
- setLong(txBytes, i, entry.txBytes);
- setLong(txPackets, i, entry.txPackets);
- setLong(operations, i, entry.operations);
-
- // Apply new values
- if (rxBytes != null) totalBytes += rxBytes[i];
- if (txBytes != null) totalBytes += txBytes[i];
- }
-
- /**
- * Record that data traffic occurred in the given time range. Will
- * distribute across internal buckets, creating new buckets as needed.
- * @hide
- */
- @Deprecated
- public void recordData(long start, long end, long rxBytes, long txBytes) {
- recordData(start, end, new NetworkStats.Entry(
- IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, 0L, txBytes, 0L, 0L));
- }
-
- /**
- * Record that data traffic occurred in the given time range. Will
- * distribute across internal buckets, creating new buckets as needed.
- * @hide
- */
- public void recordData(long start, long end, NetworkStats.Entry entry) {
- long rxBytes = entry.rxBytes;
- long rxPackets = entry.rxPackets;
- long txBytes = entry.txBytes;
- long txPackets = entry.txPackets;
- long operations = entry.operations;
-
- if (entry.isNegative()) {
- throw new IllegalArgumentException("tried recording negative data");
- }
- if (entry.isEmpty()) {
- return;
- }
-
- // create any buckets needed by this range
- ensureBuckets(start, end);
- // Return fast if there is still no entry. This would typically happen when the start,
- // end or duration are not valid values, e.g. start > end, negative duration value, etc.
- if (bucketCount == 0) return;
-
- // distribute data usage into buckets
- long duration = end - start;
- final int startIndex = getIndexAfter(end);
- for (int i = startIndex; i >= 0; i--) {
- final long curStart = bucketStart[i];
- final long curEnd = curStart + bucketDuration;
-
- // bucket is older than record; we're finished
- if (curEnd < start) break;
- // bucket is newer than record; keep looking
- if (curStart > end) continue;
-
- final long overlap = Math.min(curEnd, end) - Math.max(curStart, start);
- if (overlap <= 0) continue;
-
- // integer math each time is faster than floating point
- final long fracRxBytes = multiplySafeByRational(rxBytes, overlap, duration);
- final long fracRxPackets = multiplySafeByRational(rxPackets, overlap, duration);
- final long fracTxBytes = multiplySafeByRational(txBytes, overlap, duration);
- final long fracTxPackets = multiplySafeByRational(txPackets, overlap, duration);
- final long fracOperations = multiplySafeByRational(operations, overlap, duration);
-
-
- addLong(activeTime, i, overlap);
- addLong(this.rxBytes, i, fracRxBytes); rxBytes -= fracRxBytes;
- addLong(this.rxPackets, i, fracRxPackets); rxPackets -= fracRxPackets;
- addLong(this.txBytes, i, fracTxBytes); txBytes -= fracTxBytes;
- addLong(this.txPackets, i, fracTxPackets); txPackets -= fracTxPackets;
- addLong(this.operations, i, fracOperations); operations -= fracOperations;
-
- duration -= overlap;
- }
-
- totalBytes += entry.rxBytes + entry.txBytes;
- }
-
- /**
- * Record an entire {@link NetworkStatsHistory} into this history. Usually
- * for combining together stats for external reporting.
- * @hide
- */
- @UnsupportedAppUsage
- public void recordEntireHistory(NetworkStatsHistory input) {
- recordHistory(input, Long.MIN_VALUE, Long.MAX_VALUE);
- }
-
- /**
- * Record given {@link NetworkStatsHistory} into this history, copying only
- * buckets that atomically occur in the inclusive time range. Doesn't
- * interpolate across partial buckets.
- * @hide
- */
- public void recordHistory(NetworkStatsHistory input, long start, long end) {
- final NetworkStats.Entry entry = new NetworkStats.Entry(
- IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
- for (int i = 0; i < input.bucketCount; i++) {
- final long bucketStart = input.bucketStart[i];
- final long bucketEnd = bucketStart + input.bucketDuration;
-
- // skip when bucket is outside requested range
- if (bucketStart < start || bucketEnd > end) continue;
-
- entry.rxBytes = getLong(input.rxBytes, i, 0L);
- entry.rxPackets = getLong(input.rxPackets, i, 0L);
- entry.txBytes = getLong(input.txBytes, i, 0L);
- entry.txPackets = getLong(input.txPackets, i, 0L);
- entry.operations = getLong(input.operations, i, 0L);
-
- recordData(bucketStart, bucketEnd, entry);
- }
- }
-
- /**
- * Ensure that buckets exist for given time range, creating as needed.
- */
- private void ensureBuckets(long start, long end) {
- // normalize incoming range to bucket boundaries
- start -= start % bucketDuration;
- end += (bucketDuration - (end % bucketDuration)) % bucketDuration;
-
- for (long now = start; now < end; now += bucketDuration) {
- // try finding existing bucket
- final int index = Arrays.binarySearch(bucketStart, 0, bucketCount, now);
- if (index < 0) {
- // bucket missing, create and insert
- insertBucket(~index, now);
- }
- }
- }
-
- /**
- * Insert new bucket at requested index and starting time.
- */
- private void insertBucket(int index, long start) {
- // create more buckets when needed
- if (bucketCount >= bucketStart.length) {
- final int newLength = Math.max(bucketStart.length, 10) * 3 / 2;
- bucketStart = Arrays.copyOf(bucketStart, newLength);
- if (activeTime != null) activeTime = Arrays.copyOf(activeTime, newLength);
- if (rxBytes != null) rxBytes = Arrays.copyOf(rxBytes, newLength);
- if (rxPackets != null) rxPackets = Arrays.copyOf(rxPackets, newLength);
- if (txBytes != null) txBytes = Arrays.copyOf(txBytes, newLength);
- if (txPackets != null) txPackets = Arrays.copyOf(txPackets, newLength);
- if (operations != null) operations = Arrays.copyOf(operations, newLength);
- }
-
- // create gap when inserting bucket in middle
- if (index < bucketCount) {
- final int dstPos = index + 1;
- final int length = bucketCount - index;
-
- System.arraycopy(bucketStart, index, bucketStart, dstPos, length);
- if (activeTime != null) System.arraycopy(activeTime, index, activeTime, dstPos, length);
- if (rxBytes != null) System.arraycopy(rxBytes, index, rxBytes, dstPos, length);
- if (rxPackets != null) System.arraycopy(rxPackets, index, rxPackets, dstPos, length);
- if (txBytes != null) System.arraycopy(txBytes, index, txBytes, dstPos, length);
- if (txPackets != null) System.arraycopy(txPackets, index, txPackets, dstPos, length);
- if (operations != null) System.arraycopy(operations, index, operations, dstPos, length);
- }
-
- bucketStart[index] = start;
- setLong(activeTime, index, 0L);
- setLong(rxBytes, index, 0L);
- setLong(rxPackets, index, 0L);
- setLong(txBytes, index, 0L);
- setLong(txPackets, index, 0L);
- setLong(operations, index, 0L);
- bucketCount++;
- }
-
- /**
- * Clear all data stored in this object.
- * @hide
- */
- public void clear() {
- bucketStart = EmptyArray.LONG;
- if (activeTime != null) activeTime = EmptyArray.LONG;
- if (rxBytes != null) rxBytes = EmptyArray.LONG;
- if (rxPackets != null) rxPackets = EmptyArray.LONG;
- if (txBytes != null) txBytes = EmptyArray.LONG;
- if (txPackets != null) txPackets = EmptyArray.LONG;
- if (operations != null) operations = EmptyArray.LONG;
- bucketCount = 0;
- totalBytes = 0;
- }
-
- /**
- * Remove buckets older than requested cutoff.
- * @hide
- */
- public void removeBucketsBefore(long cutoff) {
- // TODO: Consider use getIndexBefore.
- int i;
- for (i = 0; i < bucketCount; i++) {
- final long curStart = bucketStart[i];
- final long curEnd = curStart + bucketDuration;
-
- // cutoff happens before or during this bucket; everything before
- // this bucket should be removed.
- if (curEnd > cutoff) break;
- }
-
- if (i > 0) {
- final int length = bucketStart.length;
- bucketStart = Arrays.copyOfRange(bucketStart, i, length);
- if (activeTime != null) activeTime = Arrays.copyOfRange(activeTime, i, length);
- if (rxBytes != null) rxBytes = Arrays.copyOfRange(rxBytes, i, length);
- if (rxPackets != null) rxPackets = Arrays.copyOfRange(rxPackets, i, length);
- if (txBytes != null) txBytes = Arrays.copyOfRange(txBytes, i, length);
- if (txPackets != null) txPackets = Arrays.copyOfRange(txPackets, i, length);
- if (operations != null) operations = Arrays.copyOfRange(operations, i, length);
- bucketCount -= i;
-
- totalBytes = 0;
- if (rxBytes != null) totalBytes += CollectionUtils.total(rxBytes);
- if (txBytes != null) totalBytes += CollectionUtils.total(txBytes);
- }
- }
-
- /**
- * Return interpolated data usage across the requested range. Interpolates
- * across buckets, so values may be rounded slightly.
- *
- * <p>If the active bucket is not completed yet, it returns the proportional value of it
- * based on its duration and the {@code end} param.
- *
- * @param start - start of the range, timestamp in milliseconds since the epoch.
- * @param end - end of the range, timestamp in milliseconds since the epoch.
- * @param recycle - entry instance for performance, could be null.
- * @hide
- */
- @UnsupportedAppUsage
- public Entry getValues(long start, long end, Entry recycle) {
- return getValues(start, end, Long.MAX_VALUE, recycle);
- }
-
- /**
- * Return interpolated data usage across the requested range. Interpolates
- * across buckets, so values may be rounded slightly.
- *
- * @param start - start of the range, timestamp in milliseconds since the epoch.
- * @param end - end of the range, timestamp in milliseconds since the epoch.
- * @param now - current timestamp in milliseconds since the epoch (wall clock).
- * @param recycle - entry instance for performance, could be null.
- * @hide
- */
- @UnsupportedAppUsage
- public Entry getValues(long start, long end, long now, Entry recycle) {
- final Entry entry = recycle != null ? recycle : new Entry();
- entry.bucketDuration = end - start;
- entry.bucketStart = start;
- entry.activeTime = activeTime != null ? 0 : UNKNOWN;
- entry.rxBytes = rxBytes != null ? 0 : UNKNOWN;
- entry.rxPackets = rxPackets != null ? 0 : UNKNOWN;
- entry.txBytes = txBytes != null ? 0 : UNKNOWN;
- entry.txPackets = txPackets != null ? 0 : UNKNOWN;
- entry.operations = operations != null ? 0 : UNKNOWN;
-
- // Return fast if there is no entry.
- if (bucketCount == 0) return entry;
-
- final int startIndex = getIndexAfter(end);
- for (int i = startIndex; i >= 0; i--) {
- final long curStart = bucketStart[i];
- long curEnd = curStart + bucketDuration;
-
- // bucket is older than request; we're finished
- if (curEnd <= start) break;
- // bucket is newer than request; keep looking
- if (curStart >= end) continue;
-
- // the active bucket is shorter then a normal completed bucket
- if (curEnd > now) curEnd = now;
- // usually this is simply bucketDuration
- final long bucketSpan = curEnd - curStart;
- // prevent division by zero
- if (bucketSpan <= 0) continue;
-
- final long overlapEnd = curEnd < end ? curEnd : end;
- final long overlapStart = curStart > start ? curStart : start;
- final long overlap = overlapEnd - overlapStart;
- if (overlap <= 0) continue;
-
- // integer math each time is faster than floating point
- if (activeTime != null) {
- entry.activeTime += multiplySafeByRational(activeTime[i], overlap, bucketSpan);
- }
- if (rxBytes != null) {
- entry.rxBytes += multiplySafeByRational(rxBytes[i], overlap, bucketSpan);
- }
- if (rxPackets != null) {
- entry.rxPackets += multiplySafeByRational(rxPackets[i], overlap, bucketSpan);
- }
- if (txBytes != null) {
- entry.txBytes += multiplySafeByRational(txBytes[i], overlap, bucketSpan);
- }
- if (txPackets != null) {
- entry.txPackets += multiplySafeByRational(txPackets[i], overlap, bucketSpan);
- }
- if (operations != null) {
- entry.operations += multiplySafeByRational(operations[i], overlap, bucketSpan);
- }
- }
- return entry;
- }
-
- /**
- * @deprecated only for temporary testing
- * @hide
- */
- @Deprecated
- public void generateRandom(long start, long end, long bytes) {
- final Random r = new Random();
-
- final float fractionRx = r.nextFloat();
- final long rxBytes = (long) (bytes * fractionRx);
- final long txBytes = (long) (bytes * (1 - fractionRx));
-
- final long rxPackets = rxBytes / 1024;
- final long txPackets = txBytes / 1024;
- final long operations = rxBytes / 2048;
-
- generateRandom(start, end, rxBytes, rxPackets, txBytes, txPackets, operations, r);
- }
-
- /**
- * @deprecated only for temporary testing
- * @hide
- */
- @Deprecated
- public void generateRandom(long start, long end, long rxBytes, long rxPackets, long txBytes,
- long txPackets, long operations, Random r) {
- ensureBuckets(start, end);
-
- final NetworkStats.Entry entry = new NetworkStats.Entry(
- IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
- while (rxBytes > 1024 || rxPackets > 128 || txBytes > 1024 || txPackets > 128
- || operations > 32) {
- final long curStart = randomLong(r, start, end);
- final long curEnd = curStart + randomLong(r, 0, (end - curStart) / 2);
-
- entry.rxBytes = randomLong(r, 0, rxBytes);
- entry.rxPackets = randomLong(r, 0, rxPackets);
- entry.txBytes = randomLong(r, 0, txBytes);
- entry.txPackets = randomLong(r, 0, txPackets);
- entry.operations = randomLong(r, 0, operations);
-
- rxBytes -= entry.rxBytes;
- rxPackets -= entry.rxPackets;
- txBytes -= entry.txBytes;
- txPackets -= entry.txPackets;
- operations -= entry.operations;
-
- recordData(curStart, curEnd, entry);
- }
- }
-
- /** @hide */
- public static long randomLong(Random r, long start, long end) {
- return (long) (start + (r.nextFloat() * (end - start)));
- }
-
- /**
- * Quickly determine if this history intersects with given window.
- * @hide
- */
- public boolean intersects(long start, long end) {
- final long dataStart = getStart();
- final long dataEnd = getEnd();
- if (start >= dataStart && start <= dataEnd) return true;
- if (end >= dataStart && end <= dataEnd) return true;
- if (dataStart >= start && dataStart <= end) return true;
- if (dataEnd >= start && dataEnd <= end) return true;
- return false;
- }
-
- /** @hide */
- public void dump(IndentingPrintWriter pw, boolean fullHistory) {
- pw.print("NetworkStatsHistory: bucketDuration=");
- pw.println(bucketDuration / SECOND_IN_MILLIS);
- pw.increaseIndent();
-
- final int start = fullHistory ? 0 : Math.max(0, bucketCount - 32);
- if (start > 0) {
- pw.print("(omitting "); pw.print(start); pw.println(" buckets)");
- }
-
- for (int i = start; i < bucketCount; i++) {
- pw.print("st="); pw.print(bucketStart[i] / SECOND_IN_MILLIS);
- if (rxBytes != null) { pw.print(" rb="); pw.print(rxBytes[i]); }
- if (rxPackets != null) { pw.print(" rp="); pw.print(rxPackets[i]); }
- if (txBytes != null) { pw.print(" tb="); pw.print(txBytes[i]); }
- if (txPackets != null) { pw.print(" tp="); pw.print(txPackets[i]); }
- if (operations != null) { pw.print(" op="); pw.print(operations[i]); }
- pw.println();
- }
-
- pw.decreaseIndent();
- }
-
- /** @hide */
- public void dumpCheckin(PrintWriter pw) {
- pw.print("d,");
- pw.print(bucketDuration / SECOND_IN_MILLIS);
- pw.println();
-
- for (int i = 0; i < bucketCount; i++) {
- pw.print("b,");
- pw.print(bucketStart[i] / SECOND_IN_MILLIS); pw.print(',');
- if (rxBytes != null) { pw.print(rxBytes[i]); } else { pw.print("*"); } pw.print(',');
- if (rxPackets != null) { pw.print(rxPackets[i]); } else { pw.print("*"); } pw.print(',');
- if (txBytes != null) { pw.print(txBytes[i]); } else { pw.print("*"); } pw.print(',');
- if (txPackets != null) { pw.print(txPackets[i]); } else { pw.print("*"); } pw.print(',');
- if (operations != null) { pw.print(operations[i]); } else { pw.print("*"); }
- pw.println();
- }
- }
-
- /** @hide */
- public void dumpDebug(ProtoOutputStream proto, long tag) {
- final long start = proto.start(tag);
-
- proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS, bucketDuration);
-
- for (int i = 0; i < bucketCount; i++) {
- final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS);
-
- proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS,
- bucketStart[i]);
- dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES, rxBytes, i);
- dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS, rxPackets, i);
- dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES, txBytes, i);
- dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS, txPackets, i);
- dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS, operations, i);
-
- proto.end(startBucket);
- }
-
- proto.end(start);
- }
-
- private static void dumpDebug(ProtoOutputStream proto, long tag, long[] array, int index) {
- if (array != null) {
- proto.write(tag, array[index]);
- }
- }
-
- @Override
- public String toString() {
- final CharArrayWriter writer = new CharArrayWriter();
- dump(new IndentingPrintWriter(writer, " "), false);
- return writer.toString();
- }
-
- @UnsupportedAppUsage
- public static final @android.annotation.NonNull Creator<NetworkStatsHistory> CREATOR = new Creator<NetworkStatsHistory>() {
- @Override
- public NetworkStatsHistory createFromParcel(Parcel in) {
- return new NetworkStatsHistory(in);
- }
-
- @Override
- public NetworkStatsHistory[] newArray(int size) {
- return new NetworkStatsHistory[size];
- }
- };
-
- private static long getLong(long[] array, int i, long value) {
- return array != null ? array[i] : value;
- }
-
- private static void setLong(long[] array, int i, long value) {
- if (array != null) array[i] = value;
- }
-
- private static void addLong(long[] array, int i, long value) {
- if (array != null) array[i] += value;
- }
-
- /** @hide */
- public int estimateResizeBuckets(long newBucketDuration) {
- return (int) (size() * getBucketDuration() / newBucketDuration);
- }
-
- /**
- * Utility methods for interacting with {@link DataInputStream} and
- * {@link DataOutputStream}, mostly dealing with writing partial arrays.
- * @hide
- */
- public static class DataStreamUtils {
- @Deprecated
- public static long[] readFullLongArray(DataInput in) throws IOException {
- final int size = in.readInt();
- if (size < 0) throw new ProtocolException("negative array size");
- final long[] values = new long[size];
- for (int i = 0; i < values.length; i++) {
- values[i] = in.readLong();
- }
- return values;
- }
-
- /**
- * Read variable-length {@link Long} using protobuf-style approach.
- */
- public static long readVarLong(DataInput in) throws IOException {
- int shift = 0;
- long result = 0;
- while (shift < 64) {
- byte b = in.readByte();
- result |= (long) (b & 0x7F) << shift;
- if ((b & 0x80) == 0)
- return result;
- shift += 7;
- }
- throw new ProtocolException("malformed long");
- }
-
- /**
- * Write variable-length {@link Long} using protobuf-style approach.
- */
- public static void writeVarLong(DataOutput out, long value) throws IOException {
- while (true) {
- if ((value & ~0x7FL) == 0) {
- out.writeByte((int) value);
- return;
- } else {
- out.writeByte(((int) value & 0x7F) | 0x80);
- value >>>= 7;
- }
- }
- }
-
- public static long[] readVarLongArray(DataInput in) throws IOException {
- final int size = in.readInt();
- if (size == -1) return null;
- if (size < 0) throw new ProtocolException("negative array size");
- final long[] values = new long[size];
- for (int i = 0; i < values.length; i++) {
- values[i] = readVarLong(in);
- }
- return values;
- }
-
- public static void writeVarLongArray(DataOutput out, long[] values, int size)
- throws IOException {
- if (values == null) {
- out.writeInt(-1);
- return;
- }
- if (size > values.length) {
- throw new IllegalArgumentException("size larger than length");
- }
- out.writeInt(size);
- for (int i = 0; i < size; i++) {
- writeVarLong(out, values[i]);
- }
- }
- }
-
- /**
- * Utility methods for interacting with {@link Parcel} structures, mostly
- * dealing with writing partial arrays.
- * @hide
- */
- public static class ParcelUtils {
- public static long[] readLongArray(Parcel in) {
- final int size = in.readInt();
- if (size == -1) return null;
- final long[] values = new long[size];
- for (int i = 0; i < values.length; i++) {
- values[i] = in.readLong();
- }
- return values;
- }
-
- public static void writeLongArray(Parcel out, long[] values, int size) {
- if (values == null) {
- out.writeInt(-1);
- return;
- }
- if (size > values.length) {
- throw new IllegalArgumentException("size larger than length");
- }
- out.writeInt(size);
- for (int i = 0; i < size; i++) {
- out.writeLong(values[i]);
- }
- }
- }
-
- /**
- * Builder class for {@link NetworkStatsHistory}.
- */
- public static final class Builder {
- private final long mBucketDuration;
- private final List<Long> mBucketStart;
- private final List<Long> mActiveTime;
- private final List<Long> mRxBytes;
- private final List<Long> mRxPackets;
- private final List<Long> mTxBytes;
- private final List<Long> mTxPackets;
- private final List<Long> mOperations;
-
- /**
- * Creates a new Builder with given bucket duration and initial capacity to construct
- * {@link NetworkStatsHistory} objects.
- *
- * @param bucketDuration Duration of the buckets of the object, in milliseconds.
- * @param initialCapacity Estimated number of records.
- */
- public Builder(long bucketDuration, int initialCapacity) {
- mBucketDuration = bucketDuration;
- mBucketStart = new ArrayList<>(initialCapacity);
- mActiveTime = new ArrayList<>(initialCapacity);
- mRxBytes = new ArrayList<>(initialCapacity);
- mRxPackets = new ArrayList<>(initialCapacity);
- mTxBytes = new ArrayList<>(initialCapacity);
- mTxPackets = new ArrayList<>(initialCapacity);
- mOperations = new ArrayList<>(initialCapacity);
- }
-
- /**
- * Add an {@link Entry} into the {@link NetworkStatsHistory} instance.
- *
- * @param entry The target {@link Entry} object.
- * @return The builder object.
- */
- @NonNull
- public Builder addEntry(@NonNull Entry entry) {
- mBucketStart.add(entry.bucketStart);
- mActiveTime.add(entry.activeTime);
- mRxBytes.add(entry.rxBytes);
- mRxPackets.add(entry.rxPackets);
- mTxBytes.add(entry.txBytes);
- mTxPackets.add(entry.txPackets);
- mOperations.add(entry.operations);
- return this;
- }
-
- private static long sum(@NonNull List<Long> list) {
- long sum = 0;
- for (long entry : list) {
- sum += entry;
- }
- return sum;
- }
-
- /**
- * Builds the instance of the {@link NetworkStatsHistory}.
- *
- * @return the built instance of {@link NetworkStatsHistory}.
- */
- @NonNull
- public NetworkStatsHistory build() {
- return new NetworkStatsHistory(mBucketDuration,
- CollectionUtils.toLongArray(mBucketStart),
- CollectionUtils.toLongArray(mActiveTime),
- CollectionUtils.toLongArray(mRxBytes),
- CollectionUtils.toLongArray(mRxPackets),
- CollectionUtils.toLongArray(mTxBytes),
- CollectionUtils.toLongArray(mTxPackets),
- CollectionUtils.toLongArray(mOperations),
- mBucketStart.size(),
- sum(mRxBytes) + sum(mTxBytes));
- }
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
deleted file mode 100644
index 7b5afd7..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
+++ /dev/null
@@ -1,1119 +0,0 @@
-/*
- * Copyright (C) 2011 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.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
-import static android.net.ConnectivityManager.TYPE_ETHERNET;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_PROXY;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
-import static android.net.ConnectivityManager.TYPE_WIMAX;
-import static android.net.NetworkIdentity.OEM_NONE;
-import static android.net.NetworkIdentity.OEM_PAID;
-import static android.net.NetworkIdentity.OEM_PRIVATE;
-import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
-import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
-import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
-import static android.net.NetworkStats.METERED_ALL;
-import static android.net.NetworkStats.METERED_NO;
-import static android.net.NetworkStats.METERED_YES;
-import static android.net.NetworkStats.ROAMING_ALL;
-import static android.net.NetworkStats.ROAMING_NO;
-import static android.net.NetworkStats.ROAMING_YES;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.app.usage.NetworkStatsManager;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.wifi.WifiInfo;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.ArraySet;
-
-import com.android.net.module.util.CollectionUtils;
-import com.android.net.module.util.NetworkIdentityUtils;
-import com.android.net.module.util.NetworkStatsUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * Predicate used to match {@link NetworkIdentity}, usually when collecting
- * statistics. (It should probably have been named {@code NetworkPredicate}.)
- *
- * @hide
- */
-@SystemApi(client = MODULE_LIBRARIES)
-public final class NetworkTemplate implements Parcelable {
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "MATCH_" }, value = {
- MATCH_MOBILE,
- MATCH_WIFI,
- MATCH_ETHERNET,
- MATCH_BLUETOOTH,
- MATCH_PROXY,
- MATCH_CARRIER,
- })
- public @interface TemplateMatchRule{}
-
- /** Match rule to match cellular networks with given Subscriber Ids. */
- public static final int MATCH_MOBILE = 1;
- /** Match rule to match wifi networks. */
- public static final int MATCH_WIFI = 4;
- /** Match rule to match ethernet networks. */
- public static final int MATCH_ETHERNET = 5;
- /**
- * Match rule to match all cellular networks.
- *
- * @hide
- */
- public static final int MATCH_MOBILE_WILDCARD = 6;
- /**
- * Match rule to match all wifi networks.
- *
- * @hide
- */
- public static final int MATCH_WIFI_WILDCARD = 7;
- /** Match rule to match bluetooth networks. */
- public static final int MATCH_BLUETOOTH = 8;
- /**
- * Match rule to match networks with {@link ConnectivityManager#TYPE_PROXY} as the legacy
- * network type.
- */
- public static final int MATCH_PROXY = 9;
- /**
- * Match rule to match all networks with subscriberId inside the template. Some carriers
- * may offer non-cellular networks like WiFi, which will be matched by this rule.
- */
- public static final int MATCH_CARRIER = 10;
-
- // TODO: Remove this and replace all callers with WIFI_NETWORK_KEY_ALL.
- /** @hide */
- public static final String WIFI_NETWORKID_ALL = null;
-
- /**
- * Wi-Fi Network Key is never supposed to be null (if it is, it is a bug that
- * should be fixed), so it's not possible to want to match null vs
- * non-null. Therefore it's fine to use null as a sentinel for Wifi Network Key.
- *
- * @hide
- */
- public static final String WIFI_NETWORK_KEY_ALL = WIFI_NETWORKID_ALL;
-
- /**
- * Include all network types when filtering. This is meant to merge in with the
- * {@code TelephonyManager.NETWORK_TYPE_*} constants, and thus needs to stay in sync.
- */
- public static final int NETWORK_TYPE_ALL = -1;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "OEM_MANAGED_" }, value = {
- OEM_MANAGED_ALL,
- OEM_MANAGED_NO,
- OEM_MANAGED_YES,
- OEM_MANAGED_PAID,
- OEM_MANAGED_PRIVATE
- })
- public @interface OemManaged{}
-
- /**
- * Value to match both OEM managed and unmanaged networks (all networks).
- */
- public static final int OEM_MANAGED_ALL = -1;
- /**
- * Value to match networks which are not OEM managed.
- */
- public static final int OEM_MANAGED_NO = OEM_NONE;
- /**
- * Value to match any OEM managed network.
- */
- public static final int OEM_MANAGED_YES = -2;
- /**
- * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}.
- */
- public static final int OEM_MANAGED_PAID = OEM_PAID;
- /**
- * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}.
- */
- public static final int OEM_MANAGED_PRIVATE = OEM_PRIVATE;
-
- private static boolean isKnownMatchRule(final int rule) {
- switch (rule) {
- case MATCH_MOBILE:
- case MATCH_WIFI:
- case MATCH_ETHERNET:
- case MATCH_MOBILE_WILDCARD:
- case MATCH_WIFI_WILDCARD:
- case MATCH_BLUETOOTH:
- case MATCH_PROXY:
- case MATCH_CARRIER:
- return true;
-
- default:
- return false;
- }
- }
-
- /**
- * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
- * the given IMSI.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
- return new NetworkTemplate(MATCH_MOBILE, subscriberId, null);
- }
-
- /**
- * Template to match cellular networks with the given IMSI, {@code ratType} and
- * {@code metered}. Use {@link #NETWORK_TYPE_ALL} to include all network types when
- * filtering. See {@code TelephonyManager.NETWORK_TYPE_*}.
- *
- * @hide
- */
- public static NetworkTemplate buildTemplateMobileWithRatType(@Nullable String subscriberId,
- int ratType, int metered) {
- if (TextUtils.isEmpty(subscriberId)) {
- return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null /* subscriberId */,
- null /* matchSubscriberIds */,
- new String[0] /* matchWifiNetworkKeys */, metered, ROAMING_ALL,
- DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL,
- NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
- }
- return new NetworkTemplate(MATCH_MOBILE, subscriberId, new String[] { subscriberId },
- new String[0] /* matchWifiNetworkKeys */,
- metered, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL,
- NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
- }
-
- /**
- * Template to match metered {@link ConnectivityManager#TYPE_MOBILE} networks,
- * regardless of IMSI.
- *
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static NetworkTemplate buildTemplateMobileWildcard() {
- return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null);
- }
-
- /**
- * Template to match all metered {@link ConnectivityManager#TYPE_WIFI} networks,
- * regardless of key of the wifi network.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public static NetworkTemplate buildTemplateWifiWildcard() {
- // TODO: Consider replace this with MATCH_WIFI with NETWORK_ID_ALL
- // and SUBSCRIBER_ID_MATCH_RULE_ALL.
- return new NetworkTemplate(MATCH_WIFI_WILDCARD, null, null);
- }
-
- /** @hide */
- @Deprecated
- @UnsupportedAppUsage
- public static NetworkTemplate buildTemplateWifi() {
- return buildTemplateWifiWildcard();
- }
-
- /**
- * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
- * given key of the wifi network.
- *
- * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()}
- * to know details about the key.
- * @hide
- */
- public static NetworkTemplate buildTemplateWifi(@NonNull String wifiNetworkKey) {
- Objects.requireNonNull(wifiNetworkKey);
- return new NetworkTemplate(MATCH_WIFI, null /* subscriberId */,
- new String[] { null } /* matchSubscriberIds */,
- new String[] { wifiNetworkKey }, METERED_ALL, ROAMING_ALL,
- DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
- NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL);
- }
-
- /**
- * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks with the given
- * key of the wifi network and IMSI.
- *
- * Call with {@link #WIFI_NETWORK_KEY_ALL} for {@code wifiNetworkKey} to get result regardless
- * of key of the wifi network.
- *
- * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()}
- * to know details about the key.
- * @param subscriberId the IMSI associated to this wifi network.
- *
- * @hide
- */
- public static NetworkTemplate buildTemplateWifi(@Nullable String wifiNetworkKey,
- @Nullable String subscriberId) {
- return new NetworkTemplate(MATCH_WIFI, subscriberId, new String[] { subscriberId },
- wifiNetworkKey != null
- ? new String[] { wifiNetworkKey } : new String[0],
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
- NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
- }
-
- /**
- * Template to combine all {@link ConnectivityManager#TYPE_ETHERNET} style
- * networks together.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public static NetworkTemplate buildTemplateEthernet() {
- return new NetworkTemplate(MATCH_ETHERNET, null, null);
- }
-
- /**
- * Template to combine all {@link ConnectivityManager#TYPE_BLUETOOTH} style
- * networks together.
- *
- * @hide
- */
- public static NetworkTemplate buildTemplateBluetooth() {
- return new NetworkTemplate(MATCH_BLUETOOTH, null, null);
- }
-
- /**
- * Template to combine all {@link ConnectivityManager#TYPE_PROXY} style
- * networks together.
- *
- * @hide
- */
- public static NetworkTemplate buildTemplateProxy() {
- return new NetworkTemplate(MATCH_PROXY, null, null);
- }
-
- /**
- * Template to match all metered carrier networks with the given IMSI.
- *
- * @hide
- */
- public static NetworkTemplate buildTemplateCarrierMetered(@NonNull String subscriberId) {
- Objects.requireNonNull(subscriberId);
- return new NetworkTemplate(MATCH_CARRIER, subscriberId,
- new String[] { subscriberId },
- new String[0] /* matchWifiNetworkKeys */,
- METERED_YES, ROAMING_ALL,
- DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
- NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
- }
-
- private final int mMatchRule;
- private final String mSubscriberId;
-
- /**
- * Ugh, templates are designed to target a single subscriber, but we might
- * need to match several "merged" subscribers. These are the subscribers
- * that should be considered to match this template.
- * <p>
- * Since the merge set is dynamic, it should <em>not</em> be persisted or
- * used for determining equality.
- */
- private final String[] mMatchSubscriberIds;
-
- @NonNull
- private final String[] mMatchWifiNetworkKeys;
-
- // Matches for the NetworkStats constants METERED_*, ROAMING_* and DEFAULT_NETWORK_*.
- private final int mMetered;
- private final int mRoaming;
- private final int mDefaultNetwork;
- private final int mRatType;
- /**
- * The subscriber Id match rule defines how the template should match networks with
- * specific subscriberId(s). See NetworkTemplate#SUBSCRIBER_ID_MATCH_RULE_* for more detail.
- */
- private final int mSubscriberIdMatchRule;
-
- // Bitfield containing OEM network properties{@code NetworkIdentity#OEM_*}.
- private final int mOemManaged;
-
- private static void checkValidSubscriberIdMatchRule(int matchRule, int subscriberIdMatchRule) {
- switch (matchRule) {
- case MATCH_MOBILE:
- case MATCH_CARRIER:
- // MOBILE and CARRIER templates must always specify a subscriber ID.
- if (subscriberIdMatchRule == NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL) {
- throw new IllegalArgumentException("Invalid SubscriberIdMatchRule "
- + "on match rule: " + getMatchRuleName(matchRule));
- }
- return;
- default:
- return;
- }
- }
-
- /** @hide */
- // TODO: Deprecate this constructor, mark it @UnsupportedAppUsage(maxTargetSdk = S)
- @UnsupportedAppUsage
- public NetworkTemplate(int matchRule, String subscriberId, String wifiNetworkKey) {
- this(matchRule, subscriberId, new String[] { subscriberId }, wifiNetworkKey);
- }
-
- /** @hide */
- public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
- String wifiNetworkKey) {
- // Older versions used to only match MATCH_MOBILE and MATCH_MOBILE_WILDCARD templates
- // to metered networks. It is now possible to match mobile with any meteredness, but
- // in order to preserve backward compatibility of @UnsupportedAppUsage methods, this
- //constructor passes METERED_YES for these types.
- this(matchRule, subscriberId, matchSubscriberIds,
- wifiNetworkKey != null ? new String[] { wifiNetworkKey } : new String[0],
- (matchRule == MATCH_MOBILE || matchRule == MATCH_MOBILE_WILDCARD) ? METERED_YES
- : METERED_ALL , ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
- OEM_MANAGED_ALL, NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
- }
-
- /** @hide */
- // TODO: Remove it after updating all of the caller.
- public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
- String wifiNetworkKey, int metered, int roaming, int defaultNetwork, int ratType,
- int oemManaged) {
- this(matchRule, subscriberId, matchSubscriberIds,
- wifiNetworkKey != null ? new String[] { wifiNetworkKey } : new String[0],
- metered, roaming, defaultNetwork, ratType, oemManaged,
- NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT);
- }
-
- /** @hide */
- public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
- String[] matchWifiNetworkKeys, int metered, int roaming,
- int defaultNetwork, int ratType, int oemManaged, int subscriberIdMatchRule) {
- Objects.requireNonNull(matchWifiNetworkKeys);
- mMatchRule = matchRule;
- mSubscriberId = subscriberId;
- // TODO: Check whether mMatchSubscriberIds = null or mMatchSubscriberIds = {null} when
- // mSubscriberId is null
- mMatchSubscriberIds = matchSubscriberIds;
- mMatchWifiNetworkKeys = matchWifiNetworkKeys;
- mMetered = metered;
- mRoaming = roaming;
- mDefaultNetwork = defaultNetwork;
- mRatType = ratType;
- mOemManaged = oemManaged;
- mSubscriberIdMatchRule = subscriberIdMatchRule;
- checkValidSubscriberIdMatchRule(matchRule, subscriberIdMatchRule);
- if (!isKnownMatchRule(matchRule)) {
- throw new IllegalArgumentException("Unknown network template rule " + matchRule
- + " will not match any identity.");
- }
- }
-
- private NetworkTemplate(Parcel in) {
- mMatchRule = in.readInt();
- mSubscriberId = in.readString();
- mMatchSubscriberIds = in.createStringArray();
- mMatchWifiNetworkKeys = in.createStringArray();
- mMetered = in.readInt();
- mRoaming = in.readInt();
- mDefaultNetwork = in.readInt();
- mRatType = in.readInt();
- mOemManaged = in.readInt();
- mSubscriberIdMatchRule = in.readInt();
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mMatchRule);
- dest.writeString(mSubscriberId);
- dest.writeStringArray(mMatchSubscriberIds);
- dest.writeStringArray(mMatchWifiNetworkKeys);
- dest.writeInt(mMetered);
- dest.writeInt(mRoaming);
- dest.writeInt(mDefaultNetwork);
- dest.writeInt(mRatType);
- dest.writeInt(mOemManaged);
- dest.writeInt(mSubscriberIdMatchRule);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public String toString() {
- final StringBuilder builder = new StringBuilder("NetworkTemplate: ");
- builder.append("matchRule=").append(getMatchRuleName(mMatchRule));
- if (mSubscriberId != null) {
- builder.append(", subscriberId=").append(
- NetworkIdentityUtils.scrubSubscriberId(mSubscriberId));
- }
- if (mMatchSubscriberIds != null) {
- builder.append(", matchSubscriberIds=").append(
- Arrays.toString(NetworkIdentityUtils.scrubSubscriberIds(mMatchSubscriberIds)));
- }
- builder.append(", matchWifiNetworkKeys=").append(Arrays.toString(mMatchWifiNetworkKeys));
- if (mMetered != METERED_ALL) {
- builder.append(", metered=").append(NetworkStats.meteredToString(mMetered));
- }
- if (mRoaming != ROAMING_ALL) {
- builder.append(", roaming=").append(NetworkStats.roamingToString(mRoaming));
- }
- if (mDefaultNetwork != DEFAULT_NETWORK_ALL) {
- builder.append(", defaultNetwork=").append(NetworkStats.defaultNetworkToString(
- mDefaultNetwork));
- }
- if (mRatType != NETWORK_TYPE_ALL) {
- builder.append(", ratType=").append(mRatType);
- }
- if (mOemManaged != OEM_MANAGED_ALL) {
- builder.append(", oemManaged=").append(getOemManagedNames(mOemManaged));
- }
- builder.append(", subscriberIdMatchRule=")
- .append(subscriberIdMatchRuleToString(mSubscriberIdMatchRule));
- return builder.toString();
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mMatchRule, mSubscriberId, Arrays.hashCode(mMatchWifiNetworkKeys),
- mMetered, mRoaming, mDefaultNetwork, mRatType, mOemManaged, mSubscriberIdMatchRule);
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (obj instanceof NetworkTemplate) {
- final NetworkTemplate other = (NetworkTemplate) obj;
- return mMatchRule == other.mMatchRule
- && Objects.equals(mSubscriberId, other.mSubscriberId)
- && mMetered == other.mMetered
- && mRoaming == other.mRoaming
- && mDefaultNetwork == other.mDefaultNetwork
- && mRatType == other.mRatType
- && mOemManaged == other.mOemManaged
- && mSubscriberIdMatchRule == other.mSubscriberIdMatchRule
- && Arrays.equals(mMatchWifiNetworkKeys, other.mMatchWifiNetworkKeys);
- }
- return false;
- }
-
- private static String subscriberIdMatchRuleToString(int rule) {
- switch (rule) {
- case NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT:
- return "EXACT_MATCH";
- case NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL:
- return "ALL";
- default:
- return "Unknown rule " + rule;
- }
- }
-
- /** @hide */
- public boolean isMatchRuleMobile() {
- switch (mMatchRule) {
- case MATCH_MOBILE:
- case MATCH_MOBILE_WILDCARD:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Get match rule of the template. See {@code MATCH_*}.
- */
- @UnsupportedAppUsage
- public int getMatchRule() {
- // Wildcard rules are not exposed. For external callers, convert wildcard rules to
- // exposed rules before returning.
- switch (mMatchRule) {
- case MATCH_MOBILE_WILDCARD:
- return MATCH_MOBILE;
- case MATCH_WIFI_WILDCARD:
- return MATCH_WIFI;
- default:
- return mMatchRule;
- }
- }
-
- /**
- * Get subscriber Id of the template.
- * @hide
- */
- @Nullable
- @UnsupportedAppUsage
- public String getSubscriberId() {
- return mSubscriberId;
- }
-
- /**
- * Get set of subscriber Ids of the template.
- */
- @NonNull
- public Set<String> getSubscriberIds() {
- return new ArraySet<>(Arrays.asList(mMatchSubscriberIds));
- }
-
- /**
- * Get the set of Wifi Network Keys of the template.
- * See {@link WifiInfo#getNetworkKey()}.
- */
- @NonNull
- public Set<String> getWifiNetworkKeys() {
- return new ArraySet<>(Arrays.asList(mMatchWifiNetworkKeys));
- }
-
- /** @hide */
- // TODO: Remove this and replace all callers with {@link #getWifiNetworkKeys()}.
- @Nullable
- public String getNetworkId() {
- return getWifiNetworkKeys().isEmpty() ? null : getWifiNetworkKeys().iterator().next();
- }
-
- /**
- * Get meteredness filter of the template.
- */
- @NetworkStats.Meteredness
- public int getMeteredness() {
- return mMetered;
- }
-
- /**
- * Get roaming filter of the template.
- */
- @NetworkStats.Roaming
- public int getRoaming() {
- return mRoaming;
- }
-
- /**
- * Get the default network status filter of the template.
- */
- @NetworkStats.DefaultNetwork
- public int getDefaultNetworkStatus() {
- return mDefaultNetwork;
- }
-
- /**
- * Get the Radio Access Technology(RAT) type filter of the template.
- */
- public int getRatType() {
- return mRatType;
- }
-
- /**
- * Get the OEM managed filter of the template. See {@code OEM_MANAGED_*} or
- * {@code android.net.NetworkIdentity#OEM_*}.
- */
- @OemManaged
- public int getOemManaged() {
- return mOemManaged;
- }
-
- /**
- * Test if given {@link NetworkIdentity} matches this template.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public boolean matches(@NonNull NetworkIdentity ident) {
- Objects.requireNonNull(ident);
- if (!matchesMetered(ident)) return false;
- if (!matchesRoaming(ident)) return false;
- if (!matchesDefaultNetwork(ident)) return false;
- if (!matchesOemNetwork(ident)) return false;
-
- switch (mMatchRule) {
- case MATCH_MOBILE:
- return matchesMobile(ident);
- case MATCH_WIFI:
- return matchesWifi(ident);
- case MATCH_ETHERNET:
- return matchesEthernet(ident);
- case MATCH_MOBILE_WILDCARD:
- return matchesMobileWildcard(ident);
- case MATCH_WIFI_WILDCARD:
- return matchesWifiWildcard(ident);
- case MATCH_BLUETOOTH:
- return matchesBluetooth(ident);
- case MATCH_PROXY:
- return matchesProxy(ident);
- case MATCH_CARRIER:
- return matchesCarrier(ident);
- default:
- // We have no idea what kind of network template we are, so we
- // just claim not to match anything.
- return false;
- }
- }
-
- private boolean matchesMetered(NetworkIdentity ident) {
- return (mMetered == METERED_ALL)
- || (mMetered == METERED_YES && ident.mMetered)
- || (mMetered == METERED_NO && !ident.mMetered);
- }
-
- private boolean matchesRoaming(NetworkIdentity ident) {
- return (mRoaming == ROAMING_ALL)
- || (mRoaming == ROAMING_YES && ident.mRoaming)
- || (mRoaming == ROAMING_NO && !ident.mRoaming);
- }
-
- private boolean matchesDefaultNetwork(NetworkIdentity ident) {
- return (mDefaultNetwork == DEFAULT_NETWORK_ALL)
- || (mDefaultNetwork == DEFAULT_NETWORK_YES && ident.mDefaultNetwork)
- || (mDefaultNetwork == DEFAULT_NETWORK_NO && !ident.mDefaultNetwork);
- }
-
- private boolean matchesOemNetwork(NetworkIdentity ident) {
- return (mOemManaged == OEM_MANAGED_ALL)
- || (mOemManaged == OEM_MANAGED_YES
- && ident.mOemManaged != OEM_NONE)
- || (mOemManaged == ident.mOemManaged);
- }
-
- private boolean matchesCollapsedRatType(NetworkIdentity ident) {
- return mRatType == NETWORK_TYPE_ALL
- || NetworkStatsManager.getCollapsedRatType(mRatType)
- == NetworkStatsManager.getCollapsedRatType(ident.mRatType);
- }
-
- /**
- * Check if this template matches {@code subscriberId}. Returns true if this
- * template was created with {@code SUBSCRIBER_ID_MATCH_RULE_ALL}, or with a
- * {@code mMatchSubscriberIds} array that contains {@code subscriberId}.
- *
- * @hide
- */
- public boolean matchesSubscriberId(@Nullable String subscriberId) {
- return mSubscriberIdMatchRule == NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL
- || CollectionUtils.contains(mMatchSubscriberIds, subscriberId);
- }
-
- /**
- * Check if network matches key of the wifi network.
- * Returns true when the key matches, or when {@code mMatchWifiNetworkKeys} is
- * empty.
- *
- * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getNetworkKey()}
- * to know details about the key.
- */
- private boolean matchesWifiNetworkKey(@NonNull String wifiNetworkKey) {
- Objects.requireNonNull(wifiNetworkKey);
- return CollectionUtils.isEmpty(mMatchWifiNetworkKeys)
- || CollectionUtils.contains(mMatchWifiNetworkKeys, wifiNetworkKey);
- }
-
- /**
- * Check if mobile network matches IMSI.
- */
- private boolean matchesMobile(NetworkIdentity ident) {
- if (ident.mType == TYPE_WIMAX) {
- // TODO: consider matching against WiMAX subscriber identity
- return true;
- } else {
- return ident.mType == TYPE_MOBILE && !CollectionUtils.isEmpty(mMatchSubscriberIds)
- && CollectionUtils.contains(mMatchSubscriberIds, ident.mSubscriberId)
- && matchesCollapsedRatType(ident);
- }
- }
-
- /**
- * Check if matches Wi-Fi network template.
- */
- private boolean matchesWifi(NetworkIdentity ident) {
- switch (ident.mType) {
- case TYPE_WIFI:
- return matchesSubscriberId(ident.mSubscriberId)
- && matchesWifiNetworkKey(ident.mWifiNetworkKey);
- default:
- return false;
- }
- }
-
- /**
- * Check if matches Ethernet network template.
- */
- private boolean matchesEthernet(NetworkIdentity ident) {
- if (ident.mType == TYPE_ETHERNET) {
- return true;
- }
- return false;
- }
-
- /**
- * Check if matches carrier network. The carrier networks means it includes the subscriberId.
- */
- private boolean matchesCarrier(NetworkIdentity ident) {
- return ident.mSubscriberId != null
- && !CollectionUtils.isEmpty(mMatchSubscriberIds)
- && CollectionUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
- }
-
- private boolean matchesMobileWildcard(NetworkIdentity ident) {
- if (ident.mType == TYPE_WIMAX) {
- return true;
- } else {
- return ident.mType == TYPE_MOBILE && matchesCollapsedRatType(ident);
- }
- }
-
- private boolean matchesWifiWildcard(NetworkIdentity ident) {
- switch (ident.mType) {
- case TYPE_WIFI:
- case TYPE_WIFI_P2P:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Check if matches Bluetooth network template.
- */
- private boolean matchesBluetooth(NetworkIdentity ident) {
- if (ident.mType == TYPE_BLUETOOTH) {
- return true;
- }
- return false;
- }
-
- /**
- * Check if matches Proxy network template.
- */
- private boolean matchesProxy(NetworkIdentity ident) {
- return ident.mType == TYPE_PROXY;
- }
-
- private static String getMatchRuleName(int matchRule) {
- switch (matchRule) {
- case MATCH_MOBILE:
- return "MOBILE";
- case MATCH_WIFI:
- return "WIFI";
- case MATCH_ETHERNET:
- return "ETHERNET";
- case MATCH_MOBILE_WILDCARD:
- return "MOBILE_WILDCARD";
- case MATCH_WIFI_WILDCARD:
- return "WIFI_WILDCARD";
- case MATCH_BLUETOOTH:
- return "BLUETOOTH";
- case MATCH_PROXY:
- return "PROXY";
- case MATCH_CARRIER:
- return "CARRIER";
- default:
- return "UNKNOWN(" + matchRule + ")";
- }
- }
-
- private static String getOemManagedNames(int oemManaged) {
- switch (oemManaged) {
- case OEM_MANAGED_ALL:
- return "OEM_MANAGED_ALL";
- case OEM_MANAGED_NO:
- return "OEM_MANAGED_NO";
- case OEM_MANAGED_YES:
- return "OEM_MANAGED_YES";
- default:
- return NetworkIdentity.getOemManagedNames(oemManaged);
- }
- }
-
- /**
- * Examine the given template and normalize it.
- * We pick the "lowest" merged subscriber as the primary
- * for key purposes, and expand the template to match all other merged
- * subscribers.
- * <p>
- * For example, given an incoming template matching B, and the currently
- * active merge set [A,B], we'd return a new template that primarily matches
- * A, but also matches B.
- * TODO: remove and use {@link #normalize(NetworkTemplate, List)}.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public static NetworkTemplate normalize(NetworkTemplate template, String[] merged) {
- return normalize(template, Arrays.<String[]>asList(merged));
- }
-
- /**
- * Examine the given template and normalize it.
- * We pick the "lowest" merged subscriber as the primary
- * for key purposes, and expand the template to match all other merged
- * subscribers.
- *
- * There can be multiple merged subscriberIds for multi-SIM devices.
- *
- * <p>
- * For example, given an incoming template matching B, and the currently
- * active merge set [A,B], we'd return a new template that primarily matches
- * A, but also matches B.
- *
- * @hide
- */
- // TODO: @SystemApi when ready.
- public static NetworkTemplate normalize(NetworkTemplate template, List<String[]> mergedList) {
- // Now there are several types of network which uses SubscriberId to store network
- // information. For instances:
- // The TYPE_WIFI with subscriberId means that it is a merged carrier wifi network.
- // The TYPE_CARRIER means that the network associate to specific carrier network.
-
- if (template.mSubscriberId == null) return template;
-
- for (String[] merged : mergedList) {
- if (CollectionUtils.contains(merged, template.mSubscriberId)) {
- // Requested template subscriber is part of the merge group; return
- // a template that matches all merged subscribers.
- final String[] matchWifiNetworkKeys = template.mMatchWifiNetworkKeys;
- return new NetworkTemplate(template.mMatchRule, merged[0], merged,
- CollectionUtils.isEmpty(matchWifiNetworkKeys)
- ? null : matchWifiNetworkKeys[0]);
- }
- }
-
- return template;
- }
-
- @UnsupportedAppUsage
- public static final @android.annotation.NonNull Creator<NetworkTemplate> CREATOR = new Creator<NetworkTemplate>() {
- @Override
- public NetworkTemplate createFromParcel(Parcel in) {
- return new NetworkTemplate(in);
- }
-
- @Override
- public NetworkTemplate[] newArray(int size) {
- return new NetworkTemplate[size];
- }
- };
-
- /**
- * Builder class for NetworkTemplate.
- */
- public static final class Builder {
- private final int mMatchRule;
- // Use a SortedSet to provide a deterministic order when fetching the first one.
- @NonNull
- private final SortedSet<String> mMatchSubscriberIds =
- new TreeSet<>(Comparator.nullsFirst(Comparator.naturalOrder()));
- @NonNull
- private final SortedSet<String> mMatchWifiNetworkKeys = new TreeSet<>();
-
- // Matches for the NetworkStats constants METERED_*, ROAMING_* and DEFAULT_NETWORK_*.
- private int mMetered;
- private int mRoaming;
- private int mDefaultNetwork;
- private int mRatType;
-
- // Bitfield containing OEM network properties {@code NetworkIdentity#OEM_*}.
- private int mOemManaged;
-
- /**
- * Creates a new Builder with given match rule to construct NetworkTemplate objects.
- *
- * @param matchRule the match rule of the template, see {@code MATCH_*}.
- */
- public Builder(@TemplateMatchRule final int matchRule) {
- assertRequestableMatchRule(matchRule);
- // Initialize members with default values.
- mMatchRule = matchRule;
- mMetered = METERED_ALL;
- mRoaming = ROAMING_ALL;
- mDefaultNetwork = DEFAULT_NETWORK_ALL;
- mRatType = NETWORK_TYPE_ALL;
- mOemManaged = OEM_MANAGED_ALL;
- }
-
- /**
- * Set the Subscriber Ids. Calling this function with an empty set represents
- * the intention of matching any Subscriber Ids.
- *
- * @param subscriberIds the list of Subscriber Ids.
- * @return this builder.
- */
- @NonNull
- public Builder setSubscriberIds(@NonNull Set<String> subscriberIds) {
- Objects.requireNonNull(subscriberIds);
- mMatchSubscriberIds.clear();
- mMatchSubscriberIds.addAll(subscriberIds);
- return this;
- }
-
- /**
- * Set the Wifi Network Keys. Calling this function with an empty set represents
- * the intention of matching any Wifi Network Key.
- *
- * @param wifiNetworkKeys the list of Wifi Network Key,
- * see {@link WifiInfo#getNetworkKey()}.
- * Or an empty list to match all networks.
- * Note that {@code getNetworkKey()} might get null key
- * when wifi disconnects. However, the caller should never invoke
- * this function with a null Wifi Network Key since such statistics
- * never exists.
- * @return this builder.
- */
- @NonNull
- public Builder setWifiNetworkKeys(@NonNull Set<String> wifiNetworkKeys) {
- Objects.requireNonNull(wifiNetworkKeys);
- for (String key : wifiNetworkKeys) {
- if (key == null) {
- throw new IllegalArgumentException("Null is not a valid key");
- }
- }
- mMatchWifiNetworkKeys.clear();
- mMatchWifiNetworkKeys.addAll(wifiNetworkKeys);
- return this;
- }
-
- /**
- * Set the meteredness filter.
- *
- * @param metered the meteredness filter.
- * @return this builder.
- */
- @NonNull
- public Builder setMeteredness(@NetworkStats.Meteredness int metered) {
- mMetered = metered;
- return this;
- }
-
- /**
- * Set the roaming filter.
- *
- * @param roaming the roaming filter.
- * @return this builder.
- */
- @NonNull
- public Builder setRoaming(@NetworkStats.Roaming int roaming) {
- mRoaming = roaming;
- return this;
- }
-
- /**
- * Set the default network status filter.
- *
- * @param defaultNetwork the default network status filter.
- * @return this builder.
- */
- @NonNull
- public Builder setDefaultNetworkStatus(@NetworkStats.DefaultNetwork int defaultNetwork) {
- mDefaultNetwork = defaultNetwork;
- return this;
- }
-
- /**
- * Set the Radio Access Technology(RAT) type filter.
- *
- * @param ratType the Radio Access Technology(RAT) type filter. Use
- * {@link #NETWORK_TYPE_ALL} to include all network types when filtering.
- * See {@code TelephonyManager.NETWORK_TYPE_*}.
- * @return this builder.
- */
- @NonNull
- public Builder setRatType(int ratType) {
- // Input will be validated with the match rule when building the template.
- mRatType = ratType;
- return this;
- }
-
- /**
- * Set the OEM managed filter.
- *
- * @param oemManaged the match rule to match different type of OEM managed network or
- * unmanaged networks. See {@code OEM_MANAGED_*}.
- * @return this builder.
- */
- @NonNull
- public Builder setOemManaged(@OemManaged int oemManaged) {
- mOemManaged = oemManaged;
- return this;
- }
-
- /**
- * Check whether the match rule is requestable.
- *
- * @param matchRule the target match rule to be checked.
- */
- private static void assertRequestableMatchRule(final int matchRule) {
- if (!isKnownMatchRule(matchRule)
- || matchRule == MATCH_PROXY
- || matchRule == MATCH_MOBILE_WILDCARD
- || matchRule == MATCH_WIFI_WILDCARD) {
- throw new IllegalArgumentException("Invalid match rule: "
- + getMatchRuleName(matchRule));
- }
- }
-
- private void assertRequestableParameters() {
- validateWifiNetworkKeys();
- // TODO: Check all the input are legitimate.
- }
-
- private void validateWifiNetworkKeys() {
- if (mMatchRule != MATCH_WIFI && !mMatchWifiNetworkKeys.isEmpty()) {
- throw new IllegalArgumentException("Trying to build non wifi match rule: "
- + mMatchRule + " with wifi network keys");
- }
- }
-
- /**
- * For backward compatibility, deduce match rule to a wildcard match rule
- * if the Subscriber Ids are empty.
- */
- private int getWildcardDeducedMatchRule() {
- if (mMatchRule == MATCH_MOBILE && mMatchSubscriberIds.isEmpty()) {
- return MATCH_MOBILE_WILDCARD;
- } else if (mMatchRule == MATCH_WIFI && mMatchSubscriberIds.isEmpty()
- && mMatchWifiNetworkKeys.isEmpty()) {
- return MATCH_WIFI_WILDCARD;
- }
- return mMatchRule;
- }
-
- /**
- * Builds the instance of the NetworkTemplate.
- *
- * @return the built instance of NetworkTemplate.
- */
- @NonNull
- public NetworkTemplate build() {
- assertRequestableParameters();
- final int subscriberIdMatchRule = mMatchSubscriberIds.isEmpty()
- ? NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL
- : NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT;
- return new NetworkTemplate(getWildcardDeducedMatchRule(),
- mMatchSubscriberIds.isEmpty() ? null : mMatchSubscriberIds.iterator().next(),
- mMatchSubscriberIds.toArray(new String[0]),
- mMatchWifiNetworkKeys.toArray(new String[0]), mMetered, mRoaming,
- mDefaultNetwork, mRatType, mOemManaged, subscriberIdMatchRule);
- }
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
deleted file mode 100644
index dc4ac55..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
+++ /dev/null
@@ -1,1148 +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.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-
-import android.annotation.NonNull;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
-import android.app.DownloadManager;
-import android.app.backup.BackupManager;
-import android.app.usage.NetworkStatsManager;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.media.MediaPlayer;
-import android.os.Binder;
-import android.os.Build;
-import android.os.RemoteException;
-import android.os.StrictMode;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.DatagramSocket;
-import java.net.Socket;
-import java.net.SocketException;
-
-/**
- * Class that provides network traffic statistics. These statistics include
- * bytes transmitted and received and network packets transmitted and received,
- * over all interfaces, over the mobile interface, and on a per-UID basis.
- * <p>
- * These statistics may not be available on all platforms. If the statistics are
- * not supported by this device, {@link #UNSUPPORTED} will be returned.
- * <p>
- * Note that the statistics returned by this class reset and start from zero
- * after every reboot. To access more robust historical network statistics data,
- * use {@link NetworkStatsManager} instead.
- */
-public class TrafficStats {
- static {
- System.loadLibrary("framework-connectivity-tiramisu-jni");
- }
-
- private static final String TAG = TrafficStats.class.getSimpleName();
- /**
- * The return value to indicate that the device does not support the statistic.
- */
- public final static int UNSUPPORTED = -1;
-
- /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */
- @Deprecated
- public static final long KB_IN_BYTES = 1024;
- /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */
- @Deprecated
- public static final long MB_IN_BYTES = KB_IN_BYTES * 1024;
- /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */
- @Deprecated
- public static final long GB_IN_BYTES = MB_IN_BYTES * 1024;
- /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */
- @Deprecated
- public static final long TB_IN_BYTES = GB_IN_BYTES * 1024;
- /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */
- @Deprecated
- public static final long PB_IN_BYTES = TB_IN_BYTES * 1024;
-
- /**
- * Special UID value used when collecting {@link NetworkStatsHistory} for
- * removed applications.
- *
- * @hide
- */
- public static final int UID_REMOVED = -4;
-
- /**
- * Special UID value used when collecting {@link NetworkStatsHistory} for
- * tethering traffic.
- *
- * @hide
- */
- public static final int UID_TETHERING = NetworkStats.UID_TETHERING;
-
- /**
- * Tag values in this range are reserved for the network stack. The network stack is
- * running as UID {@link android.os.Process.NETWORK_STACK_UID} when in the mainline
- * module separate process, and as the system UID otherwise.
- */
- /** @hide */
- @SystemApi
- public static final int TAG_NETWORK_STACK_RANGE_START = 0xFFFFFD00;
- /** @hide */
- @SystemApi
- public static final int TAG_NETWORK_STACK_RANGE_END = 0xFFFFFEFF;
-
- /**
- * Tags between 0xFFFFFF00 and 0xFFFFFFFF are reserved and used internally by system services
- * like DownloadManager when performing traffic on behalf of an application.
- */
- // Please note there is no enforcement of these constants, so do not rely on them to
- // determine that the caller is a system caller.
- /** @hide */
- @SystemApi
- public static final int TAG_SYSTEM_IMPERSONATION_RANGE_START = 0xFFFFFF00;
- /** @hide */
- @SystemApi
- public static final int TAG_SYSTEM_IMPERSONATION_RANGE_END = 0xFFFFFF0F;
-
- /**
- * Tag values between these ranges are reserved for the network stack to do traffic
- * on behalf of applications. It is a subrange of the range above.
- */
- /** @hide */
- @SystemApi
- public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_START = 0xFFFFFF80;
- /** @hide */
- @SystemApi
- public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_END = 0xFFFFFF8F;
-
- /**
- * Default tag value for {@link DownloadManager} traffic.
- *
- * @hide
- */
- public static final int TAG_SYSTEM_DOWNLOAD = 0xFFFFFF01;
-
- /**
- * Default tag value for {@link MediaPlayer} traffic.
- *
- * @hide
- */
- public static final int TAG_SYSTEM_MEDIA = 0xFFFFFF02;
-
- /**
- * Default tag value for {@link BackupManager} backup traffic; that is,
- * traffic from the device to the storage backend.
- *
- * @hide
- */
- public static final int TAG_SYSTEM_BACKUP = 0xFFFFFF03;
-
- /**
- * Default tag value for {@link BackupManager} restore traffic; that is,
- * app data retrieved from the storage backend at install time.
- *
- * @hide
- */
- public static final int TAG_SYSTEM_RESTORE = 0xFFFFFF04;
-
- /**
- * Default tag value for code (typically APKs) downloaded by an app store on
- * behalf of the app, such as updates.
- *
- * @hide
- */
- public static final int TAG_SYSTEM_APP = 0xFFFFFF05;
-
- // TODO : remove this constant when Wifi code is updated
- /** @hide */
- public static final int TAG_SYSTEM_PROBE = 0xFFFFFF42;
-
- private static INetworkStatsService sStatsService;
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
- private synchronized static INetworkStatsService getStatsService() {
- if (sStatsService == null) {
- throw new IllegalStateException("TrafficStats not initialized, uid="
- + Binder.getCallingUid());
- }
- return sStatsService;
- }
-
- /**
- * Snapshot of {@link NetworkStats} when the currently active profiling
- * session started, or {@code null} if no session active.
- *
- * @see #startDataProfiling(Context)
- * @see #stopDataProfiling(Context)
- */
- private static NetworkStats sActiveProfilingStart;
-
- private static Object sProfilingLock = new Object();
-
- private static final String LOOPBACK_IFACE = "lo";
-
- /**
- * Initialization {@link TrafficStats} with the context, to
- * allow {@link TrafficStats} to fetch the needed binder.
- *
- * @param context a long-lived context, such as the application context or system
- * server context.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @SuppressLint("VisiblySynchronized")
- public static synchronized void init(@NonNull final Context context) {
- if (sStatsService != null) {
- throw new IllegalStateException("TrafficStats is already initialized, uid="
- + Binder.getCallingUid());
- }
- final NetworkStatsManager statsManager =
- context.getSystemService(NetworkStatsManager.class);
- if (statsManager == null) {
- // TODO: Currently Process.isSupplemental is not working yet, because it depends on
- // process to run in a certain UID range, which is not true for now. Change this
- // to Log.wtf once Process.isSupplemental is ready.
- Log.e(TAG, "TrafficStats not initialized, uid=" + Binder.getCallingUid());
- return;
- }
- sStatsService = statsManager.getBinder();
- }
-
- /**
- * Attach the socket tagger implementation to the current process, to
- * get notified when a socket's {@link FileDescriptor} is assigned to
- * a thread. See {@link SocketTagger#set(SocketTagger)}.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static void attachSocketTagger() {
- dalvik.system.SocketTagger.set(new SocketTagger());
- }
-
- private static class SocketTagger extends dalvik.system.SocketTagger {
-
- // TODO: set to false
- private static final boolean LOGD = true;
-
- SocketTagger() {
- }
-
- @Override
- public void tag(FileDescriptor fd) throws SocketException {
- final UidTag tagInfo = sThreadUidTag.get();
- if (LOGD) {
- Log.d(TAG, "tagSocket(" + fd.getInt$() + ") with statsTag=0x"
- + Integer.toHexString(tagInfo.tag) + ", statsUid=" + tagInfo.uid);
- }
- if (tagInfo.tag == -1) {
- StrictMode.noteUntaggedSocket();
- }
-
- if (tagInfo.tag == -1 && tagInfo.uid == -1) return;
- final int errno = native_tagSocketFd(fd, tagInfo.tag, tagInfo.uid);
- if (errno < 0) {
- Log.i(TAG, "tagSocketFd(" + fd.getInt$() + ", "
- + tagInfo.tag + ", "
- + tagInfo.uid + ") failed with errno" + errno);
- }
- }
-
- @Override
- public void untag(FileDescriptor fd) throws SocketException {
- if (LOGD) {
- Log.i(TAG, "untagSocket(" + fd.getInt$() + ")");
- }
-
- final UidTag tagInfo = sThreadUidTag.get();
- if (tagInfo.tag == -1 && tagInfo.uid == -1) return;
-
- final int errno = native_untagSocketFd(fd);
- if (errno < 0) {
- Log.w(TAG, "untagSocket(" + fd.getInt$() + ") failed with errno " + errno);
- }
- }
- }
-
- private static native int native_tagSocketFd(FileDescriptor fd, int tag, int uid);
- private static native int native_untagSocketFd(FileDescriptor fd);
-
- private static class UidTag {
- public int tag = -1;
- public int uid = -1;
- }
-
- private static ThreadLocal<UidTag> sThreadUidTag = new ThreadLocal<UidTag>() {
- @Override
- protected UidTag initialValue() {
- return new UidTag();
- }
- };
-
- /**
- * Set active tag to use when accounting {@link Socket} traffic originating
- * from the current thread. Only one active tag per thread is supported.
- * <p>
- * Changes only take effect during subsequent calls to
- * {@link #tagSocket(Socket)}.
- * <p>
- * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and
- * used internally by system services like {@link DownloadManager} when
- * performing traffic on behalf of an application.
- *
- * @see #clearThreadStatsTag()
- */
- public static void setThreadStatsTag(int tag) {
- getAndSetThreadStatsTag(tag);
- }
-
- /**
- * Set active tag to use when accounting {@link Socket} traffic originating
- * from the current thread. Only one active tag per thread is supported.
- * <p>
- * Changes only take effect during subsequent calls to
- * {@link #tagSocket(Socket)}.
- * <p>
- * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and
- * used internally by system services like {@link DownloadManager} when
- * performing traffic on behalf of an application.
- *
- * @return the current tag for the calling thread, which can be used to
- * restore any existing values after a nested operation is finished
- */
- public static int getAndSetThreadStatsTag(int tag) {
- final int old = sThreadUidTag.get().tag;
- sThreadUidTag.get().tag = tag;
- return old;
- }
-
- /**
- * Set active tag to use when accounting {@link Socket} traffic originating
- * from the current thread. The tag used internally is well-defined to
- * distinguish all backup-related traffic.
- *
- * @hide
- */
- @SystemApi
- public static void setThreadStatsTagBackup() {
- setThreadStatsTag(TAG_SYSTEM_BACKUP);
- }
-
- /**
- * Set active tag to use when accounting {@link Socket} traffic originating
- * from the current thread. The tag used internally is well-defined to
- * distinguish all restore-related traffic.
- *
- * @hide
- */
- @SystemApi
- public static void setThreadStatsTagRestore() {
- setThreadStatsTag(TAG_SYSTEM_RESTORE);
- }
-
- /**
- * Set active tag to use when accounting {@link Socket} traffic originating
- * from the current thread. The tag used internally is well-defined to
- * distinguish all code (typically APKs) downloaded by an app store on
- * behalf of the app, such as updates.
- *
- * @hide
- */
- @SystemApi
- public static void setThreadStatsTagApp() {
- setThreadStatsTag(TAG_SYSTEM_APP);
- }
-
- /**
- * Set active tag to use when accounting {@link Socket} traffic originating
- * from the current thread. The tag used internally is well-defined to
- * distinguish all download provider traffic.
- *
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- public static void setThreadStatsTagDownload() {
- setThreadStatsTag(TAG_SYSTEM_DOWNLOAD);
- }
-
- /**
- * Get the active tag used when accounting {@link Socket} traffic originating
- * from the current thread. Only one active tag per thread is supported.
- * {@link #tagSocket(Socket)}.
- *
- * @see #setThreadStatsTag(int)
- */
- public static int getThreadStatsTag() {
- return sThreadUidTag.get().tag;
- }
-
- /**
- * Clear any active tag set to account {@link Socket} traffic originating
- * from the current thread.
- *
- * @see #setThreadStatsTag(int)
- */
- public static void clearThreadStatsTag() {
- sThreadUidTag.get().tag = -1;
- }
-
- /**
- * Set specific UID to use when accounting {@link Socket} traffic
- * originating from the current thread. Designed for use when performing an
- * operation on behalf of another application, or when another application
- * is performing operations on your behalf.
- * <p>
- * Any app can <em>accept</em> blame for traffic performed on a socket
- * originally created by another app by calling this method with the
- * {@link android.system.Os#getuid()} value. However, only apps holding the
- * {@code android.Manifest.permission#UPDATE_DEVICE_STATS} permission may
- * <em>assign</em> blame to another UIDs.
- * <p>
- * Changes only take effect during subsequent calls to
- * {@link #tagSocket(Socket)}.
- */
- @SuppressLint("RequiresPermission")
- public static void setThreadStatsUid(int uid) {
- sThreadUidTag.get().uid = uid;
- }
-
- /**
- * Get the active UID used when accounting {@link Socket} traffic originating
- * from the current thread. Only one active tag per thread is supported.
- * {@link #tagSocket(Socket)}.
- *
- * @see #setThreadStatsUid(int)
- */
- public static int getThreadStatsUid() {
- return sThreadUidTag.get().uid;
- }
-
- /**
- * Set specific UID to use when accounting {@link Socket} traffic
- * originating from the current thread as the calling UID. Designed for use
- * when another application is performing operations on your behalf.
- * <p>
- * Changes only take effect during subsequent calls to
- * {@link #tagSocket(Socket)}.
- *
- * @removed
- * @deprecated use {@link #setThreadStatsUid(int)} instead.
- */
- @Deprecated
- public static void setThreadStatsUidSelf() {
- setThreadStatsUid(android.os.Process.myUid());
- }
-
- /**
- * Clear any active UID set to account {@link Socket} traffic originating
- * from the current thread.
- *
- * @see #setThreadStatsUid(int)
- */
- @SuppressLint("RequiresPermission")
- public static void clearThreadStatsUid() {
- setThreadStatsUid(-1);
- }
-
- /**
- * Tag the given {@link Socket} with any statistics parameters active for
- * the current thread. Subsequent calls always replace any existing
- * parameters. When finished, call {@link #untagSocket(Socket)} to remove
- * statistics parameters.
- *
- * @see #setThreadStatsTag(int)
- */
- public static void tagSocket(@NonNull Socket socket) throws SocketException {
- SocketTagger.get().tag(socket);
- }
-
- /**
- * Remove any statistics parameters from the given {@link Socket}.
- * <p>
- * In Android 8.1 (API level 27) and lower, a socket is automatically
- * untagged when it's sent to another process using binder IPC with a
- * {@code ParcelFileDescriptor} container. In Android 9.0 (API level 28)
- * and higher, the socket tag is kept when the socket is sent to another
- * process using binder IPC. You can mimic the previous behavior by
- * calling {@code untagSocket()} before sending the socket to another
- * process.
- */
- public static void untagSocket(@NonNull Socket socket) throws SocketException {
- SocketTagger.get().untag(socket);
- }
-
- /**
- * Tag the given {@link DatagramSocket} with any statistics parameters
- * active for the current thread. Subsequent calls always replace any
- * existing parameters. When finished, call
- * {@link #untagDatagramSocket(DatagramSocket)} to remove statistics
- * parameters.
- *
- * @see #setThreadStatsTag(int)
- */
- public static void tagDatagramSocket(@NonNull DatagramSocket socket) throws SocketException {
- SocketTagger.get().tag(socket);
- }
-
- /**
- * Remove any statistics parameters from the given {@link DatagramSocket}.
- */
- public static void untagDatagramSocket(@NonNull DatagramSocket socket) throws SocketException {
- SocketTagger.get().untag(socket);
- }
-
- /**
- * Tag the given {@link FileDescriptor} socket with any statistics
- * parameters active for the current thread. Subsequent calls always replace
- * any existing parameters. When finished, call
- * {@link #untagFileDescriptor(FileDescriptor)} to remove statistics
- * parameters.
- *
- * @see #setThreadStatsTag(int)
- */
- public static void tagFileDescriptor(@NonNull FileDescriptor fd) throws IOException {
- SocketTagger.get().tag(fd);
- }
-
- /**
- * Remove any statistics parameters from the given {@link FileDescriptor}
- * socket.
- */
- public static void untagFileDescriptor(@NonNull FileDescriptor fd) throws IOException {
- SocketTagger.get().untag(fd);
- }
-
- /**
- * Start profiling data usage for current UID. Only one profiling session
- * can be active at a time.
- *
- * @hide
- */
- public static void startDataProfiling(Context context) {
- synchronized (sProfilingLock) {
- if (sActiveProfilingStart != null) {
- throw new IllegalStateException("already profiling data");
- }
-
- // take snapshot in time; we calculate delta later
- sActiveProfilingStart = getDataLayerSnapshotForUid(context);
- }
- }
-
- /**
- * Stop profiling data usage for current UID.
- *
- * @return Detailed {@link NetworkStats} of data that occurred since last
- * {@link #startDataProfiling(Context)} call.
- * @hide
- */
- public static NetworkStats stopDataProfiling(Context context) {
- synchronized (sProfilingLock) {
- if (sActiveProfilingStart == null) {
- throw new IllegalStateException("not profiling data");
- }
-
- // subtract starting values and return delta
- final NetworkStats profilingStop = getDataLayerSnapshotForUid(context);
- final NetworkStats profilingDelta = NetworkStats.subtract(
- profilingStop, sActiveProfilingStart, null, null);
- sActiveProfilingStart = null;
- return profilingDelta;
- }
- }
-
- /**
- * Increment count of network operations performed under the accounting tag
- * currently active on the calling thread. This can be used to derive
- * bytes-per-operation.
- *
- * @param operationCount Number of operations to increment count by.
- */
- public static void incrementOperationCount(int operationCount) {
- final int tag = getThreadStatsTag();
- incrementOperationCount(tag, operationCount);
- }
-
- /**
- * Increment count of network operations performed under the given
- * accounting tag. This can be used to derive bytes-per-operation.
- *
- * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}.
- * @param operationCount Number of operations to increment count by.
- */
- public static void incrementOperationCount(int tag, int operationCount) {
- final int uid = android.os.Process.myUid();
- try {
- getStatsService().incrementOperationCount(uid, tag, operationCount);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** {@hide} */
- public static void closeQuietly(INetworkStatsSession session) {
- // TODO: move to NetworkStatsService once it exists
- if (session != null) {
- try {
- session.close();
- } catch (RuntimeException rethrown) {
- throw rethrown;
- } catch (Exception ignored) {
- }
- }
- }
-
- private static long addIfSupported(long stat) {
- return (stat == UNSUPPORTED) ? 0 : stat;
- }
-
- /**
- * Return number of packets transmitted across mobile networks since device
- * boot. Counts packets across all mobile network interfaces, and always
- * increases monotonically since device boot. Statistics are measured at the
- * network layer, so they include both TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
- * return {@link #UNSUPPORTED} on devices where statistics aren't available.
- */
- public static long getMobileTxPackets() {
- long total = 0;
- for (String iface : getMobileIfaces()) {
- total += addIfSupported(getTxPackets(iface));
- }
- return total;
- }
-
- /**
- * Return number of packets received across mobile networks since device
- * boot. Counts packets across all mobile network interfaces, and always
- * increases monotonically since device boot. Statistics are measured at the
- * network layer, so they include both TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
- * return {@link #UNSUPPORTED} on devices where statistics aren't available.
- */
- public static long getMobileRxPackets() {
- long total = 0;
- for (String iface : getMobileIfaces()) {
- total += addIfSupported(getRxPackets(iface));
- }
- return total;
- }
-
- /**
- * Return number of bytes transmitted across mobile networks since device
- * boot. Counts packets across all mobile network interfaces, and always
- * increases monotonically since device boot. Statistics are measured at the
- * network layer, so they include both TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
- * return {@link #UNSUPPORTED} on devices where statistics aren't available.
- */
- public static long getMobileTxBytes() {
- long total = 0;
- for (String iface : getMobileIfaces()) {
- total += addIfSupported(getTxBytes(iface));
- }
- return total;
- }
-
- /**
- * Return number of bytes received across mobile networks since device boot.
- * Counts packets across all mobile network interfaces, and always increases
- * monotonically since device boot. Statistics are measured at the network
- * layer, so they include both TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
- * return {@link #UNSUPPORTED} on devices where statistics aren't available.
- */
- public static long getMobileRxBytes() {
- long total = 0;
- for (String iface : getMobileIfaces()) {
- total += addIfSupported(getRxBytes(iface));
- }
- return total;
- }
-
- /** {@hide} */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static long getMobileTcpRxPackets() {
- long total = 0;
- for (String iface : getMobileIfaces()) {
- long stat = UNSUPPORTED;
- try {
- stat = getStatsService().getIfaceStats(iface, TYPE_TCP_RX_PACKETS);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- total += addIfSupported(stat);
- }
- return total;
- }
-
- /** {@hide} */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static long getMobileTcpTxPackets() {
- long total = 0;
- for (String iface : getMobileIfaces()) {
- long stat = UNSUPPORTED;
- try {
- stat = getStatsService().getIfaceStats(iface, TYPE_TCP_TX_PACKETS);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- total += addIfSupported(stat);
- }
- return total;
- }
-
- /**
- * Return the number of packets transmitted on the specified interface since the interface
- * was created. Statistics are measured at the network layer, so both TCP and
- * UDP usage are included.
- *
- * Note that the returned values are partial statistics that do not count data from several
- * sources and do not apply several adjustments that are necessary for correctness, such
- * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to
- * determine whether traffic is being transferred on the specific interface but are not a
- * substitute for the more accurate statistics provided by the {@link NetworkStatsManager}
- * APIs.
- *
- * @param iface The name of the interface.
- * @return The number of transmitted packets.
- */
- public static long getTxPackets(@NonNull String iface) {
- try {
- return getStatsService().getIfaceStats(iface, TYPE_TX_PACKETS);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return the number of packets received on the specified interface since the interface was
- * created. Statistics are measured at the network layer, so both TCP
- * and UDP usage are included.
- *
- * Note that the returned values are partial statistics that do not count data from several
- * sources and do not apply several adjustments that are necessary for correctness, such
- * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to
- * determine whether traffic is being transferred on the specific interface but are not a
- * substitute for the more accurate statistics provided by the {@link NetworkStatsManager}
- * APIs.
- *
- * @param iface The name of the interface.
- * @return The number of received packets.
- */
- public static long getRxPackets(@NonNull String iface) {
- try {
- return getStatsService().getIfaceStats(iface, TYPE_RX_PACKETS);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return the number of bytes transmitted on the specified interface since the interface
- * was created. Statistics are measured at the network layer, so both TCP and
- * UDP usage are included.
- *
- * Note that the returned values are partial statistics that do not count data from several
- * sources and do not apply several adjustments that are necessary for correctness, such
- * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to
- * determine whether traffic is being transferred on the specific interface but are not a
- * substitute for the more accurate statistics provided by the {@link NetworkStatsManager}
- * APIs.
- *
- * @param iface The name of the interface.
- * @return The number of transmitted bytes.
- */
- public static long getTxBytes(@NonNull String iface) {
- try {
- return getStatsService().getIfaceStats(iface, TYPE_TX_BYTES);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return the number of bytes received on the specified interface since the interface
- * was created. Statistics are measured at the network layer, so both TCP
- * and UDP usage are included.
- *
- * Note that the returned values are partial statistics that do not count data from several
- * sources and do not apply several adjustments that are necessary for correctness, such
- * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to
- * determine whether traffic is being transferred on the specific interface but are not a
- * substitute for the more accurate statistics provided by the {@link NetworkStatsManager}
- * APIs.
- *
- * @param iface The name of the interface.
- * @return The number of received bytes.
- */
- public static long getRxBytes(@NonNull String iface) {
- try {
- return getStatsService().getIfaceStats(iface, TYPE_RX_BYTES);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** {@hide} */
- @TestApi
- public static long getLoopbackTxPackets() {
- try {
- return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_TX_PACKETS);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** {@hide} */
- @TestApi
- public static long getLoopbackRxPackets() {
- try {
- return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_RX_PACKETS);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** {@hide} */
- @TestApi
- public static long getLoopbackTxBytes() {
- try {
- return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_TX_BYTES);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** {@hide} */
- @TestApi
- public static long getLoopbackRxBytes() {
- try {
- return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_RX_BYTES);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return number of packets transmitted since device boot. Counts packets
- * across all network interfaces, and always increases monotonically since
- * device boot. Statistics are measured at the network layer, so they
- * include both TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
- * return {@link #UNSUPPORTED} on devices where statistics aren't available.
- */
- public static long getTotalTxPackets() {
- try {
- return getStatsService().getTotalStats(TYPE_TX_PACKETS);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return number of packets received since device boot. Counts packets
- * across all network interfaces, and always increases monotonically since
- * device boot. Statistics are measured at the network layer, so they
- * include both TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
- * return {@link #UNSUPPORTED} on devices where statistics aren't available.
- */
- public static long getTotalRxPackets() {
- try {
- return getStatsService().getTotalStats(TYPE_RX_PACKETS);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return number of bytes transmitted since device boot. Counts packets
- * across all network interfaces, and always increases monotonically since
- * device boot. Statistics are measured at the network layer, so they
- * include both TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
- * return {@link #UNSUPPORTED} on devices where statistics aren't available.
- */
- public static long getTotalTxBytes() {
- try {
- return getStatsService().getTotalStats(TYPE_TX_BYTES);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return number of bytes received since device boot. Counts packets across
- * all network interfaces, and always increases monotonically since device
- * boot. Statistics are measured at the network layer, so they include both
- * TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
- * return {@link #UNSUPPORTED} on devices where statistics aren't available.
- */
- public static long getTotalRxBytes() {
- try {
- return getStatsService().getTotalStats(TYPE_RX_BYTES);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return number of bytes transmitted by the given UID since device boot.
- * Counts packets across all network interfaces, and always increases
- * monotonically since device boot. Statistics are measured at the network
- * layer, so they include both TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
- * return {@link #UNSUPPORTED} on devices where statistics aren't available.
- * <p>
- * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
- * report traffic statistics for the calling UID. It will return
- * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
- * historical network statistics belonging to other UIDs, use
- * {@link NetworkStatsManager}.
- *
- * @see android.os.Process#myUid()
- * @see android.content.pm.ApplicationInfo#uid
- */
- public static long getUidTxBytes(int uid) {
- try {
- return getStatsService().getUidStats(uid, TYPE_TX_BYTES);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return number of bytes received by the given UID since device boot.
- * Counts packets across all network interfaces, and always increases
- * monotonically since device boot. Statistics are measured at the network
- * layer, so they include both TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
- * {@link #UNSUPPORTED} on devices where statistics aren't available.
- * <p>
- * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
- * report traffic statistics for the calling UID. It will return
- * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
- * historical network statistics belonging to other UIDs, use
- * {@link NetworkStatsManager}.
- *
- * @see android.os.Process#myUid()
- * @see android.content.pm.ApplicationInfo#uid
- */
- public static long getUidRxBytes(int uid) {
- try {
- return getStatsService().getUidStats(uid, TYPE_RX_BYTES);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return number of packets transmitted by the given UID since device boot.
- * Counts packets across all network interfaces, and always increases
- * monotonically since device boot. Statistics are measured at the network
- * layer, so they include both TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
- * {@link #UNSUPPORTED} on devices where statistics aren't available.
- * <p>
- * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
- * report traffic statistics for the calling UID. It will return
- * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
- * historical network statistics belonging to other UIDs, use
- * {@link NetworkStatsManager}.
- *
- * @see android.os.Process#myUid()
- * @see android.content.pm.ApplicationInfo#uid
- */
- public static long getUidTxPackets(int uid) {
- try {
- return getStatsService().getUidStats(uid, TYPE_TX_PACKETS);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return number of packets received by the given UID since device boot.
- * Counts packets across all network interfaces, and always increases
- * monotonically since device boot. Statistics are measured at the network
- * layer, so they include both TCP and UDP usage.
- * <p>
- * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
- * {@link #UNSUPPORTED} on devices where statistics aren't available.
- * <p>
- * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
- * report traffic statistics for the calling UID. It will return
- * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
- * historical network statistics belonging to other UIDs, use
- * {@link NetworkStatsManager}.
- *
- * @see android.os.Process#myUid()
- * @see android.content.pm.ApplicationInfo#uid
- */
- public static long getUidRxPackets(int uid) {
- try {
- return getStatsService().getUidStats(uid, TYPE_RX_PACKETS);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
- * transport layer statistics are no longer available, and will
- * always return {@link #UNSUPPORTED}.
- * @see #getUidTxBytes(int)
- */
- @Deprecated
- public static long getUidTcpTxBytes(int uid) {
- return UNSUPPORTED;
- }
-
- /**
- * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
- * transport layer statistics are no longer available, and will
- * always return {@link #UNSUPPORTED}.
- * @see #getUidRxBytes(int)
- */
- @Deprecated
- public static long getUidTcpRxBytes(int uid) {
- return UNSUPPORTED;
- }
-
- /**
- * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
- * transport layer statistics are no longer available, and will
- * always return {@link #UNSUPPORTED}.
- * @see #getUidTxBytes(int)
- */
- @Deprecated
- public static long getUidUdpTxBytes(int uid) {
- return UNSUPPORTED;
- }
-
- /**
- * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
- * transport layer statistics are no longer available, and will
- * always return {@link #UNSUPPORTED}.
- * @see #getUidRxBytes(int)
- */
- @Deprecated
- public static long getUidUdpRxBytes(int uid) {
- return UNSUPPORTED;
- }
-
- /**
- * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
- * transport layer statistics are no longer available, and will
- * always return {@link #UNSUPPORTED}.
- * @see #getUidTxPackets(int)
- */
- @Deprecated
- public static long getUidTcpTxSegments(int uid) {
- return UNSUPPORTED;
- }
-
- /**
- * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
- * transport layer statistics are no longer available, and will
- * always return {@link #UNSUPPORTED}.
- * @see #getUidRxPackets(int)
- */
- @Deprecated
- public static long getUidTcpRxSegments(int uid) {
- return UNSUPPORTED;
- }
-
- /**
- * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
- * transport layer statistics are no longer available, and will
- * always return {@link #UNSUPPORTED}.
- * @see #getUidTxPackets(int)
- */
- @Deprecated
- public static long getUidUdpTxPackets(int uid) {
- return UNSUPPORTED;
- }
-
- /**
- * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
- * transport layer statistics are no longer available, and will
- * always return {@link #UNSUPPORTED}.
- * @see #getUidRxPackets(int)
- */
- @Deprecated
- public static long getUidUdpRxPackets(int uid) {
- return UNSUPPORTED;
- }
-
- /**
- * Return detailed {@link NetworkStats} for the current UID. Requires no
- * special permission.
- */
- private static NetworkStats getDataLayerSnapshotForUid(Context context) {
- // TODO: take snapshot locally, since proc file is now visible
- final int uid = android.os.Process.myUid();
- try {
- return getStatsService().getDataLayerSnapshotForUid(uid);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return set of any ifaces associated with mobile networks since boot.
- * Interfaces are never removed from this list, so counters should always be
- * monotonic.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
- private static String[] getMobileIfaces() {
- try {
- return getStatsService().getMobileIfaces();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- // NOTE: keep these in sync with {@code com_android_server_net_NetworkStatsService.cpp}.
- /** {@hide} */
- public static final int TYPE_RX_BYTES = 0;
- /** {@hide} */
- public static final int TYPE_RX_PACKETS = 1;
- /** {@hide} */
- public static final int TYPE_TX_BYTES = 2;
- /** {@hide} */
- public static final int TYPE_TX_PACKETS = 3;
- /** {@hide} */
- public static final int TYPE_TCP_RX_PACKETS = 4;
- /** {@hide} */
- public static final int TYPE_TCP_TX_PACKETS = 5;
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/UnderlyingNetworkInfo.aidl b/packages/ConnectivityT/framework-t/src/android/net/UnderlyingNetworkInfo.aidl
deleted file mode 100644
index a56f2f4..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/UnderlyingNetworkInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-parcelable UnderlyingNetworkInfo;
diff --git a/packages/ConnectivityT/framework-t/src/android/net/UnderlyingNetworkInfo.java b/packages/ConnectivityT/framework-t/src/android/net/UnderlyingNetworkInfo.java
deleted file mode 100644
index 7ab53b1..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/UnderlyingNetworkInfo.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * A lightweight container used to carry information on the networks that underly a given
- * virtual network.
- *
- * @hide
- */
-@SystemApi(client = MODULE_LIBRARIES)
-public final class UnderlyingNetworkInfo implements Parcelable {
- /** The owner of this network. */
- private final int mOwnerUid;
-
- /** The interface name of this network. */
- @NonNull
- private final String mIface;
-
- /** The names of the interfaces underlying this network. */
- @NonNull
- private final List<String> mUnderlyingIfaces;
-
- public UnderlyingNetworkInfo(int ownerUid, @NonNull String iface,
- @NonNull List<String> underlyingIfaces) {
- Objects.requireNonNull(iface);
- Objects.requireNonNull(underlyingIfaces);
- mOwnerUid = ownerUid;
- mIface = iface;
- mUnderlyingIfaces = Collections.unmodifiableList(new ArrayList<>(underlyingIfaces));
- }
-
- private UnderlyingNetworkInfo(@NonNull Parcel in) {
- mOwnerUid = in.readInt();
- mIface = in.readString();
- List<String> underlyingIfaces = new ArrayList<>();
- in.readList(underlyingIfaces, null /*classLoader*/, java.lang.String.class);
- mUnderlyingIfaces = Collections.unmodifiableList(underlyingIfaces);
- }
-
- /** Get the owner of this network. */
- public int getOwnerUid() {
- return mOwnerUid;
- }
-
- /** Get the interface name of this network. */
- @NonNull
- public String getInterface() {
- return mIface;
- }
-
- /** Get the names of the interfaces underlying this network. */
- @NonNull
- public List<String> getUnderlyingInterfaces() {
- return mUnderlyingIfaces;
- }
-
- @Override
- public String toString() {
- return "UnderlyingNetworkInfo{"
- + "ownerUid=" + mOwnerUid
- + ", iface='" + mIface + '\''
- + ", underlyingIfaces='" + mUnderlyingIfaces.toString() + '\''
- + '}';
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mOwnerUid);
- dest.writeString(mIface);
- dest.writeList(mUnderlyingIfaces);
- }
-
- @NonNull
- public static final Parcelable.Creator<UnderlyingNetworkInfo> CREATOR =
- new Parcelable.Creator<UnderlyingNetworkInfo>() {
- @NonNull
- @Override
- public UnderlyingNetworkInfo createFromParcel(@NonNull Parcel in) {
- return new UnderlyingNetworkInfo(in);
- }
-
- @NonNull
- @Override
- public UnderlyingNetworkInfo[] newArray(int size) {
- return new UnderlyingNetworkInfo[size];
- }
- };
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof UnderlyingNetworkInfo)) return false;
- final UnderlyingNetworkInfo that = (UnderlyingNetworkInfo) o;
- return mOwnerUid == that.getOwnerUid()
- && Objects.equals(mIface, that.getInterface())
- && Objects.equals(mUnderlyingIfaces, that.getUnderlyingInterfaces());
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mOwnerUid, mIface, mUnderlyingIfaces);
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/netstats/IUsageCallback.aidl b/packages/ConnectivityT/framework-t/src/android/net/netstats/IUsageCallback.aidl
deleted file mode 100644
index 4e8a5b2..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/netstats/IUsageCallback.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.netstats;
-
-import android.net.DataUsageRequest;
-
-/**
- * Interface for NetworkStatsService to notify events to the callers of registerUsageCallback.
- *
- * @hide
- */
-oneway interface IUsageCallback {
- void onThresholdReached(in DataUsageRequest request);
- void onCallbackReleased(in DataUsageRequest request);
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/INetworkStatsProvider.aidl b/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/INetworkStatsProvider.aidl
deleted file mode 100644
index 74c3ba4..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/INetworkStatsProvider.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2020 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.net.netstats.provider;
-
-/**
- * Interface for NetworkStatsService to query network statistics and set data limits.
- *
- * @hide
- */
-oneway interface INetworkStatsProvider {
- void onRequestStatsUpdate(int token);
- void onSetAlert(long quotaBytes);
- void onSetWarningAndLimit(String iface, long warningBytes, long limitBytes);
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
deleted file mode 100644
index 01ff02d..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 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.net.netstats.provider;
-
-import android.net.NetworkStats;
-
-/**
- * Interface for implementor of {@link INetworkStatsProviderCallback} to push events
- * such as network statistics update or notify limit reached.
- * @hide
- */
-oneway interface INetworkStatsProviderCallback {
- void notifyStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats);
- void notifyAlertReached();
- void notifyWarningReached();
- void notifyLimitReached();
- void unregister();
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/NetworkStatsProvider.java b/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/NetworkStatsProvider.java
deleted file mode 100644
index d37a53d..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/NetworkStatsProvider.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2020 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.net.netstats.provider;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.net.NetworkStats;
-import android.os.RemoteException;
-
-/**
- * A base class that allows external modules to implement a custom network statistics provider.
- * @hide
- */
-@SystemApi
-public abstract class NetworkStatsProvider {
- /**
- * A value used by {@link #onSetLimit}, {@link #onSetAlert} and {@link #onSetWarningAndLimit}
- * indicates there is no limit.
- */
- public static final int QUOTA_UNLIMITED = -1;
-
- @NonNull private final INetworkStatsProvider mProviderBinder =
- new INetworkStatsProvider.Stub() {
-
- @Override
- public void onRequestStatsUpdate(int token) {
- NetworkStatsProvider.this.onRequestStatsUpdate(token);
- }
-
- @Override
- public void onSetAlert(long quotaBytes) {
- NetworkStatsProvider.this.onSetAlert(quotaBytes);
- }
-
- @Override
- public void onSetWarningAndLimit(String iface, long warningBytes, long limitBytes) {
- NetworkStatsProvider.this.onSetWarningAndLimit(iface, warningBytes, limitBytes);
- }
- };
-
- // The binder given by the service when successfully registering. Only null before registering,
- // never null once non-null.
- @Nullable
- private INetworkStatsProviderCallback mProviderCbBinder;
-
- /**
- * Return the binder invoked by the service and redirect function calls to the overridden
- * methods.
- * @hide
- */
- @NonNull
- public INetworkStatsProvider getProviderBinder() {
- return mProviderBinder;
- }
-
- /**
- * Store the binder that was returned by the service when successfully registering. Note that
- * the provider cannot be re-registered. Hence this method can only be called once per provider.
- *
- * @hide
- */
- public void setProviderCallbackBinder(@NonNull INetworkStatsProviderCallback binder) {
- if (mProviderCbBinder != null) {
- throw new IllegalArgumentException("provider is already registered");
- }
- mProviderCbBinder = binder;
- }
-
- /**
- * Get the binder that was returned by the service when successfully registering. Or null if the
- * provider was never registered.
- *
- * @hide
- */
- @Nullable
- public INetworkStatsProviderCallback getProviderCallbackBinder() {
- return mProviderCbBinder;
- }
-
- /**
- * Get the binder that was returned by the service when successfully registering. Throw an
- * {@link IllegalStateException} if the provider is not registered.
- *
- * @hide
- */
- @NonNull
- public INetworkStatsProviderCallback getProviderCallbackBinderOrThrow() {
- if (mProviderCbBinder == null) {
- throw new IllegalStateException("the provider is not registered");
- }
- return mProviderCbBinder;
- }
-
- /**
- * Notify the system of new network statistics.
- *
- * Send the network statistics recorded since the last call to {@link #notifyStatsUpdated}. Must
- * be called as soon as possible after {@link NetworkStatsProvider#onRequestStatsUpdate(int)}
- * being called. Responding later increases the probability stats will be dropped. The
- * provider can also call this whenever it wants to reports new stats for any reason.
- * Note that the system will not necessarily immediately propagate the statistics to
- * reflect the update.
- *
- * @param token the token under which these stats were gathered. Providers can call this method
- * with the current token as often as they want, until the token changes.
- * {@see NetworkStatsProvider#onRequestStatsUpdate()}
- * @param ifaceStats the {@link NetworkStats} per interface to be reported.
- * The provider should not include any traffic that is already counted by
- * kernel interface counters.
- * @param uidStats the same stats as above, but counts {@link NetworkStats}
- * per uid.
- */
- public void notifyStatsUpdated(int token, @NonNull NetworkStats ifaceStats,
- @NonNull NetworkStats uidStats) {
- try {
- getProviderCallbackBinderOrThrow().notifyStatsUpdated(token, ifaceStats, uidStats);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Notify system that the quota set by {@code onSetAlert} has been reached.
- */
- public void notifyAlertReached() {
- try {
- getProviderCallbackBinderOrThrow().notifyAlertReached();
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Notify system that the warning set by {@link #onSetWarningAndLimit} has been reached.
- */
- public void notifyWarningReached() {
- try {
- // Reuse the code path to notify warning reached with limit reached
- // since framework handles them in the same way.
- getProviderCallbackBinderOrThrow().notifyWarningReached();
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Notify system that the limit set by {@link #onSetLimit} or limit set by
- * {@link #onSetWarningAndLimit} has been reached.
- */
- public void notifyLimitReached() {
- try {
- getProviderCallbackBinderOrThrow().notifyLimitReached();
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Called by {@code NetworkStatsService} when it requires to know updated stats.
- * The provider MUST respond by calling {@link #notifyStatsUpdated} as soon as possible.
- * Responding later increases the probability stats will be dropped. Memory allowing, the
- * system will try to take stats into account up to one minute after calling
- * {@link #onRequestStatsUpdate}.
- *
- * @param token a positive number identifying the new state of the system under which
- * {@link NetworkStats} have to be gathered from now on. When this is called,
- * custom implementations of providers MUST tally and report the latest stats with
- * the previous token, under which stats were being gathered so far.
- */
- public abstract void onRequestStatsUpdate(int token);
-
- /**
- * Called by {@code NetworkStatsService} when setting the interface quota for the specified
- * upstream interface. When this is called, the custom implementation should block all egress
- * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have
- * been reached, and MUST respond to it by calling
- * {@link NetworkStatsProvider#notifyLimitReached()}.
- *
- * @param iface the interface requiring the operation.
- * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
- * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit.
- */
- public abstract void onSetLimit(@NonNull String iface, long quotaBytes);
-
- /**
- * Called by {@code NetworkStatsService} when setting the interface quotas for the specified
- * upstream interface. If a provider implements {@link #onSetWarningAndLimit}, the system
- * will not call {@link #onSetLimit}. When this method is called, the implementation
- * should behave as follows:
- * 1. If {@code warningBytes} is reached on {@code iface}, block all further traffic on
- * {@code iface} and call {@link NetworkStatsProvider@notifyWarningReached()}.
- * 2. If {@code limitBytes} is reached on {@code iface}, block all further traffic on
- * {@code iface} and call {@link NetworkStatsProvider#notifyLimitReached()}.
- *
- * @param iface the interface requiring the operation.
- * @param warningBytes the warning defined as the number of bytes, starting from zero and
- * counting from now. A value of {@link #QUOTA_UNLIMITED} indicates
- * there is no warning.
- * @param limitBytes the limit defined as the number of bytes, starting from zero and counting
- * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit.
- */
- public void onSetWarningAndLimit(@NonNull String iface, long warningBytes, long limitBytes) {
- // Backward compatibility for those who didn't override this function.
- onSetLimit(iface, limitBytes);
- }
-
- /**
- * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations
- * MUST call {@link NetworkStatsProvider#notifyAlertReached()} when {@code quotaBytes} bytes
- * have been reached. Unlike {@link #onSetLimit(String, long)}, the custom implementation should
- * not block all egress packets.
- *
- * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
- * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert.
- */
- public abstract void onSetAlert(long quotaBytes);
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/nsd/INsdManager.aidl b/packages/ConnectivityT/framework-t/src/android/net/nsd/INsdManager.aidl
deleted file mode 100644
index 89e9cdb..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/nsd/INsdManager.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.nsd;
-
-import android.net.nsd.INsdManagerCallback;
-import android.net.nsd.INsdServiceConnector;
-import android.os.Messenger;
-
-/**
- * Interface that NsdService implements to connect NsdManager clients.
- *
- * {@hide}
- */
-interface INsdManager {
- INsdServiceConnector connect(INsdManagerCallback cb);
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/nsd/INsdManagerCallback.aidl b/packages/ConnectivityT/framework-t/src/android/net/nsd/INsdManagerCallback.aidl
deleted file mode 100644
index 1a262ec..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/nsd/INsdManagerCallback.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.nsd;
-
-import android.os.Messenger;
-import android.net.nsd.NsdServiceInfo;
-
-/**
- * Callbacks from NsdService to NsdManager
- * @hide
- */
-oneway interface INsdManagerCallback {
- void onDiscoverServicesStarted(int listenerKey, in NsdServiceInfo info);
- void onDiscoverServicesFailed(int listenerKey, int error);
- void onServiceFound(int listenerKey, in NsdServiceInfo info);
- void onServiceLost(int listenerKey, in NsdServiceInfo info);
- void onStopDiscoveryFailed(int listenerKey, int error);
- void onStopDiscoverySucceeded(int listenerKey);
- void onRegisterServiceFailed(int listenerKey, int error);
- void onRegisterServiceSucceeded(int listenerKey, in NsdServiceInfo info);
- void onUnregisterServiceFailed(int listenerKey, int error);
- void onUnregisterServiceSucceeded(int listenerKey);
- void onResolveServiceFailed(int listenerKey, int error);
- void onResolveServiceSucceeded(int listenerKey, in NsdServiceInfo info);
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/nsd/INsdServiceConnector.aidl b/packages/ConnectivityT/framework-t/src/android/net/nsd/INsdServiceConnector.aidl
deleted file mode 100644
index b06ae55..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/nsd/INsdServiceConnector.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.nsd;
-
-import android.net.nsd.INsdManagerCallback;
-import android.net.nsd.NsdServiceInfo;
-import android.os.Messenger;
-
-/**
- * Interface that NsdService implements for each NsdManager client.
- *
- * {@hide}
- */
-interface INsdServiceConnector {
- void registerService(int listenerKey, in NsdServiceInfo serviceInfo);
- void unregisterService(int listenerKey);
- void discoverServices(int listenerKey, in NsdServiceInfo serviceInfo);
- void stopDiscovery(int listenerKey);
- void resolveService(int listenerKey, in NsdServiceInfo serviceInfo);
- void startDaemon();
-}
\ No newline at end of file
diff --git a/packages/ConnectivityT/framework-t/src/android/net/nsd/NsdManager.java b/packages/ConnectivityT/framework-t/src/android/net/nsd/NsdManager.java
deleted file mode 100644
index 209f372..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/nsd/NsdManager.java
+++ /dev/null
@@ -1,1083 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.nsd;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemService;
-import android.app.compat.CompatChanges;
-import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledSince;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.net.NetworkRequest;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * The Network Service Discovery Manager class provides the API to discover services
- * on a network. As an example, if device A and device B are connected over a Wi-Fi
- * network, a game registered on device A can be discovered by a game on device
- * B. Another example use case is an application discovering printers on the network.
- *
- * <p> The API currently supports DNS based service discovery and discovery is currently
- * limited to a local network over Multicast DNS. DNS service discovery is described at
- * http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
- *
- * <p> The API is asynchronous, and responses to requests from an application are on listener
- * callbacks on a separate internal thread.
- *
- * <p> There are three main operations the API supports - registration, discovery and resolution.
- * <pre>
- * Application start
- * |
- * |
- * | onServiceRegistered()
- * Register any local services /
- * to be advertised with \
- * registerService() onRegistrationFailed()
- * |
- * |
- * discoverServices()
- * |
- * Maintain a list to track
- * discovered services
- * |
- * |--------->
- * | |
- * | onServiceFound()
- * | |
- * | add service to list
- * | |
- * |<----------
- * |
- * |--------->
- * | |
- * | onServiceLost()
- * | |
- * | remove service from list
- * | |
- * |<----------
- * |
- * |
- * | Connect to a service
- * | from list ?
- * |
- * resolveService()
- * |
- * onServiceResolved()
- * |
- * Establish connection to service
- * with the host and port information
- *
- * </pre>
- * An application that needs to advertise itself over a network for other applications to
- * discover it can do so with a call to {@link #registerService}. If Example is a http based
- * application that can provide HTML data to peer services, it can register a name "Example"
- * with service type "_http._tcp". A successful registration is notified with a callback to
- * {@link RegistrationListener#onServiceRegistered} and a failure to register is notified
- * over {@link RegistrationListener#onRegistrationFailed}
- *
- * <p> A peer application looking for http services can initiate a discovery for "_http._tcp"
- * with a call to {@link #discoverServices}. A service found is notified with a callback
- * to {@link DiscoveryListener#onServiceFound} and a service lost is notified on
- * {@link DiscoveryListener#onServiceLost}.
- *
- * <p> Once the peer application discovers the "Example" http service, and either needs to read the
- * attributes of the service or wants to receive data from the "Example" application, it can
- * initiate a resolve with {@link #resolveService} to resolve the attributes, host, and port
- * details. A successful resolve is notified on {@link ResolveListener#onServiceResolved} and a
- * failure is notified on {@link ResolveListener#onResolveFailed}.
- *
- * Applications can reserve for a service type at
- * http://www.iana.org/form/ports-service. Existing services can be found at
- * http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml
- *
- * {@see NsdServiceInfo}
- */
-@SystemService(Context.NSD_SERVICE)
-public final class NsdManager {
- private static final String TAG = NsdManager.class.getSimpleName();
- private static final boolean DBG = false;
-
- /**
- * When enabled, apps targeting < Android 12 are considered legacy for
- * the NSD native daemon.
- * The platform will only keep the daemon running as long as there are
- * any legacy apps connected.
- *
- * After Android 12, directly communicate with native daemon might not
- * work since the native damon won't always stay alive.
- * Use the NSD APIs from NsdManager as the replacement is recommended.
- * An another alternative could be bundling your own mdns solutions instead of
- * depending on the system mdns native daemon.
- *
- * @hide
- */
- @ChangeId
- @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.S)
- public static final long RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS = 191844585L;
-
- /**
- * Broadcast intent action to indicate whether network service discovery is
- * enabled or disabled. An extra {@link #EXTRA_NSD_STATE} provides the state
- * information as int.
- *
- * @see #EXTRA_NSD_STATE
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
-
- /**
- * The lookup key for an int that indicates whether network service discovery is enabled
- * or disabled. Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
- *
- * @see #NSD_STATE_DISABLED
- * @see #NSD_STATE_ENABLED
- */
- public static final String EXTRA_NSD_STATE = "nsd_state";
-
- /**
- * Network service discovery is disabled
- *
- * @see #ACTION_NSD_STATE_CHANGED
- */
- public static final int NSD_STATE_DISABLED = 1;
-
- /**
- * Network service discovery is enabled
- *
- * @see #ACTION_NSD_STATE_CHANGED
- */
- public static final int NSD_STATE_ENABLED = 2;
-
- /** @hide */
- public static final int DISCOVER_SERVICES = 1;
- /** @hide */
- public static final int DISCOVER_SERVICES_STARTED = 2;
- /** @hide */
- public static final int DISCOVER_SERVICES_FAILED = 3;
- /** @hide */
- public static final int SERVICE_FOUND = 4;
- /** @hide */
- public static final int SERVICE_LOST = 5;
-
- /** @hide */
- public static final int STOP_DISCOVERY = 6;
- /** @hide */
- public static final int STOP_DISCOVERY_FAILED = 7;
- /** @hide */
- public static final int STOP_DISCOVERY_SUCCEEDED = 8;
-
- /** @hide */
- public static final int REGISTER_SERVICE = 9;
- /** @hide */
- public static final int REGISTER_SERVICE_FAILED = 10;
- /** @hide */
- public static final int REGISTER_SERVICE_SUCCEEDED = 11;
-
- /** @hide */
- public static final int UNREGISTER_SERVICE = 12;
- /** @hide */
- public static final int UNREGISTER_SERVICE_FAILED = 13;
- /** @hide */
- public static final int UNREGISTER_SERVICE_SUCCEEDED = 14;
-
- /** @hide */
- public static final int RESOLVE_SERVICE = 15;
- /** @hide */
- public static final int RESOLVE_SERVICE_FAILED = 16;
- /** @hide */
- public static final int RESOLVE_SERVICE_SUCCEEDED = 17;
-
- /** @hide */
- public static final int DAEMON_CLEANUP = 18;
-
- /** @hide */
- public static final int DAEMON_STARTUP = 19;
-
- /** @hide */
- public static final int ENABLE = 20;
- /** @hide */
- public static final int DISABLE = 21;
-
- /** @hide */
- public static final int NATIVE_DAEMON_EVENT = 22;
-
- /** @hide */
- public static final int REGISTER_CLIENT = 23;
- /** @hide */
- public static final int UNREGISTER_CLIENT = 24;
-
- /** Dns based service discovery protocol */
- public static final int PROTOCOL_DNS_SD = 0x0001;
-
- private static final SparseArray<String> EVENT_NAMES = new SparseArray<>();
- static {
- EVENT_NAMES.put(DISCOVER_SERVICES, "DISCOVER_SERVICES");
- EVENT_NAMES.put(DISCOVER_SERVICES_STARTED, "DISCOVER_SERVICES_STARTED");
- EVENT_NAMES.put(DISCOVER_SERVICES_FAILED, "DISCOVER_SERVICES_FAILED");
- EVENT_NAMES.put(SERVICE_FOUND, "SERVICE_FOUND");
- EVENT_NAMES.put(SERVICE_LOST, "SERVICE_LOST");
- EVENT_NAMES.put(STOP_DISCOVERY, "STOP_DISCOVERY");
- EVENT_NAMES.put(STOP_DISCOVERY_FAILED, "STOP_DISCOVERY_FAILED");
- EVENT_NAMES.put(STOP_DISCOVERY_SUCCEEDED, "STOP_DISCOVERY_SUCCEEDED");
- EVENT_NAMES.put(REGISTER_SERVICE, "REGISTER_SERVICE");
- EVENT_NAMES.put(REGISTER_SERVICE_FAILED, "REGISTER_SERVICE_FAILED");
- EVENT_NAMES.put(REGISTER_SERVICE_SUCCEEDED, "REGISTER_SERVICE_SUCCEEDED");
- EVENT_NAMES.put(UNREGISTER_SERVICE, "UNREGISTER_SERVICE");
- EVENT_NAMES.put(UNREGISTER_SERVICE_FAILED, "UNREGISTER_SERVICE_FAILED");
- EVENT_NAMES.put(UNREGISTER_SERVICE_SUCCEEDED, "UNREGISTER_SERVICE_SUCCEEDED");
- EVENT_NAMES.put(RESOLVE_SERVICE, "RESOLVE_SERVICE");
- EVENT_NAMES.put(RESOLVE_SERVICE_FAILED, "RESOLVE_SERVICE_FAILED");
- EVENT_NAMES.put(RESOLVE_SERVICE_SUCCEEDED, "RESOLVE_SERVICE_SUCCEEDED");
- EVENT_NAMES.put(DAEMON_CLEANUP, "DAEMON_CLEANUP");
- EVENT_NAMES.put(DAEMON_STARTUP, "DAEMON_STARTUP");
- EVENT_NAMES.put(ENABLE, "ENABLE");
- EVENT_NAMES.put(DISABLE, "DISABLE");
- EVENT_NAMES.put(NATIVE_DAEMON_EVENT, "NATIVE_DAEMON_EVENT");
- }
-
- /** @hide */
- public static String nameOf(int event) {
- String name = EVENT_NAMES.get(event);
- if (name == null) {
- return Integer.toString(event);
- }
- return name;
- }
-
- private static final int FIRST_LISTENER_KEY = 1;
-
- private final INsdServiceConnector mService;
- private final Context mContext;
-
- private int mListenerKey = FIRST_LISTENER_KEY;
- @GuardedBy("mMapLock")
- private final SparseArray mListenerMap = new SparseArray();
- @GuardedBy("mMapLock")
- private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<>();
- @GuardedBy("mMapLock")
- private final SparseArray<Executor> mExecutorMap = new SparseArray<>();
- private final Object mMapLock = new Object();
- // Map of listener key sent by client -> per-network discovery tracker
- @GuardedBy("mPerNetworkDiscoveryMap")
- private final ArrayMap<Integer, PerNetworkDiscoveryTracker>
- mPerNetworkDiscoveryMap = new ArrayMap<>();
-
- private final ServiceHandler mHandler;
-
- private class PerNetworkDiscoveryTracker {
- final String mServiceType;
- final int mProtocolType;
- final DiscoveryListener mBaseListener;
- final Executor mBaseExecutor;
- final ArrayMap<Network, DelegatingDiscoveryListener> mPerNetworkListeners =
- new ArrayMap<>();
-
- final NetworkCallback mNetworkCb = new NetworkCallback() {
- @Override
- public void onAvailable(@NonNull Network network) {
- final DelegatingDiscoveryListener wrappedListener = new DelegatingDiscoveryListener(
- network, mBaseListener);
- mPerNetworkListeners.put(network, wrappedListener);
- discoverServices(mServiceType, mProtocolType, network, mBaseExecutor,
- wrappedListener);
- }
-
- @Override
- public void onLost(@NonNull Network network) {
- final DelegatingDiscoveryListener listener = mPerNetworkListeners.get(network);
- if (listener == null) return;
- listener.notifyAllServicesLost();
- // Listener will be removed from map in discovery stopped callback
- stopServiceDiscovery(listener);
- }
- };
-
- // Accessed from mHandler
- private boolean mStopRequested;
-
- public void start(@NonNull NetworkRequest request) {
- final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
- cm.registerNetworkCallback(request, mNetworkCb, mHandler);
- mHandler.post(() -> mBaseListener.onDiscoveryStarted(mServiceType));
- }
-
- /**
- * Stop discovery on all networks tracked by this class.
- *
- * This will request all underlying listeners to stop, and the last one to stop will call
- * onDiscoveryStopped or onStopDiscoveryFailed.
- *
- * Must be called on the handler thread.
- */
- public void requestStop() {
- mHandler.post(() -> {
- mStopRequested = true;
- final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
- cm.unregisterNetworkCallback(mNetworkCb);
- if (mPerNetworkListeners.size() == 0) {
- mBaseListener.onDiscoveryStopped(mServiceType);
- return;
- }
- for (int i = 0; i < mPerNetworkListeners.size(); i++) {
- final DelegatingDiscoveryListener listener = mPerNetworkListeners.valueAt(i);
- stopServiceDiscovery(listener);
- }
- });
- }
-
- private PerNetworkDiscoveryTracker(String serviceType, int protocolType,
- Executor baseExecutor, DiscoveryListener baseListener) {
- mServiceType = serviceType;
- mProtocolType = protocolType;
- mBaseExecutor = baseExecutor;
- mBaseListener = baseListener;
- }
-
- /**
- * Subset of NsdServiceInfo that is tracked to generate service lost notifications when a
- * network is lost.
- *
- * Service lost notifications only contain service name, type and network, so only track
- * that information (Network is known from the listener). This also implements
- * equals/hashCode for usage in maps.
- */
- private class TrackedNsdInfo {
- private final String mServiceName;
- private final String mServiceType;
- TrackedNsdInfo(NsdServiceInfo info) {
- mServiceName = info.getServiceName();
- mServiceType = info.getServiceType();
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mServiceName, mServiceType);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof TrackedNsdInfo)) return false;
- final TrackedNsdInfo other = (TrackedNsdInfo) obj;
- return Objects.equals(mServiceName, other.mServiceName)
- && Objects.equals(mServiceType, other.mServiceType);
- }
- }
-
- private class DelegatingDiscoveryListener implements DiscoveryListener {
- private final Network mNetwork;
- private final DiscoveryListener mWrapped;
- private final ArraySet<TrackedNsdInfo> mFoundInfo = new ArraySet<>();
-
- private DelegatingDiscoveryListener(Network network, DiscoveryListener listener) {
- mNetwork = network;
- mWrapped = listener;
- }
-
- void notifyAllServicesLost() {
- for (int i = 0; i < mFoundInfo.size(); i++) {
- final TrackedNsdInfo trackedInfo = mFoundInfo.valueAt(i);
- final NsdServiceInfo serviceInfo = new NsdServiceInfo(
- trackedInfo.mServiceName, trackedInfo.mServiceType);
- serviceInfo.setNetwork(mNetwork);
- mWrapped.onServiceLost(serviceInfo);
- }
- }
-
- @Override
- public void onStartDiscoveryFailed(String serviceType, int errorCode) {
- // The delegated listener is used when NsdManager takes care of starting/stopping
- // discovery on multiple networks. Failure to start on one network is not a global
- // failure to be reported up, as other networks may succeed: just log.
- Log.e(TAG, "Failed to start discovery for " + serviceType + " on " + mNetwork
- + " with code " + errorCode);
- mPerNetworkListeners.remove(mNetwork);
- }
-
- @Override
- public void onDiscoveryStarted(String serviceType) {
- // Wrapped listener was called upon registration, it is not called for discovery
- // on each network
- }
-
- @Override
- public void onStopDiscoveryFailed(String serviceType, int errorCode) {
- Log.e(TAG, "Failed to stop discovery for " + serviceType + " on " + mNetwork
- + " with code " + errorCode);
- mPerNetworkListeners.remove(mNetwork);
- if (mStopRequested && mPerNetworkListeners.size() == 0) {
- // Do not report onStopDiscoveryFailed when some underlying listeners failed:
- // this does not mean that all listeners did, and onStopDiscoveryFailed is not
- // actionable anyway. Just report that discovery stopped.
- mWrapped.onDiscoveryStopped(serviceType);
- }
- }
-
- @Override
- public void onDiscoveryStopped(String serviceType) {
- mPerNetworkListeners.remove(mNetwork);
- if (mStopRequested && mPerNetworkListeners.size() == 0) {
- mWrapped.onDiscoveryStopped(serviceType);
- }
- }
-
- @Override
- public void onServiceFound(NsdServiceInfo serviceInfo) {
- mFoundInfo.add(new TrackedNsdInfo(serviceInfo));
- mWrapped.onServiceFound(serviceInfo);
- }
-
- @Override
- public void onServiceLost(NsdServiceInfo serviceInfo) {
- mFoundInfo.remove(new TrackedNsdInfo(serviceInfo));
- mWrapped.onServiceLost(serviceInfo);
- }
- }
- }
-
- /**
- * Create a new Nsd instance. Applications use
- * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
- * {@link android.content.Context#NSD_SERVICE Context.NSD_SERVICE}.
- * @param service the Binder interface
- * @hide - hide this because it takes in a parameter of type INsdManager, which
- * is a system private class.
- */
- public NsdManager(Context context, INsdManager service) {
- mContext = context;
-
- HandlerThread t = new HandlerThread("NsdManager");
- t.start();
- mHandler = new ServiceHandler(t.getLooper());
-
- try {
- mService = service.connect(new NsdCallbackImpl(mHandler));
- } catch (RemoteException e) {
- throw new RuntimeException("Failed to connect to NsdService");
- }
-
- // Only proactively start the daemon if the target SDK < S, otherwise the internal service
- // would automatically start/stop the native daemon as needed.
- if (!CompatChanges.isChangeEnabled(RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS)) {
- try {
- mService.startDaemon();
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to proactively start daemon");
- // Continue: the daemon can still be started on-demand later
- }
- }
- }
-
- private static class NsdCallbackImpl extends INsdManagerCallback.Stub {
- private final Handler mServHandler;
-
- NsdCallbackImpl(Handler serviceHandler) {
- mServHandler = serviceHandler;
- }
-
- private void sendInfo(int message, int listenerKey, NsdServiceInfo info) {
- mServHandler.sendMessage(mServHandler.obtainMessage(message, 0, listenerKey, info));
- }
-
- private void sendError(int message, int listenerKey, int error) {
- mServHandler.sendMessage(mServHandler.obtainMessage(message, error, listenerKey));
- }
-
- private void sendNoArg(int message, int listenerKey) {
- mServHandler.sendMessage(mServHandler.obtainMessage(message, 0, listenerKey));
- }
-
- @Override
- public void onDiscoverServicesStarted(int listenerKey, NsdServiceInfo info) {
- sendInfo(DISCOVER_SERVICES_STARTED, listenerKey, info);
- }
-
- @Override
- public void onDiscoverServicesFailed(int listenerKey, int error) {
- sendError(DISCOVER_SERVICES_FAILED, listenerKey, error);
- }
-
- @Override
- public void onServiceFound(int listenerKey, NsdServiceInfo info) {
- sendInfo(SERVICE_FOUND, listenerKey, info);
- }
-
- @Override
- public void onServiceLost(int listenerKey, NsdServiceInfo info) {
- sendInfo(SERVICE_LOST, listenerKey, info);
- }
-
- @Override
- public void onStopDiscoveryFailed(int listenerKey, int error) {
- sendError(STOP_DISCOVERY_FAILED, listenerKey, error);
- }
-
- @Override
- public void onStopDiscoverySucceeded(int listenerKey) {
- sendNoArg(STOP_DISCOVERY_SUCCEEDED, listenerKey);
- }
-
- @Override
- public void onRegisterServiceFailed(int listenerKey, int error) {
- sendError(REGISTER_SERVICE_FAILED, listenerKey, error);
- }
-
- @Override
- public void onRegisterServiceSucceeded(int listenerKey, NsdServiceInfo info) {
- sendInfo(REGISTER_SERVICE_SUCCEEDED, listenerKey, info);
- }
-
- @Override
- public void onUnregisterServiceFailed(int listenerKey, int error) {
- sendError(UNREGISTER_SERVICE_FAILED, listenerKey, error);
- }
-
- @Override
- public void onUnregisterServiceSucceeded(int listenerKey) {
- sendNoArg(UNREGISTER_SERVICE_SUCCEEDED, listenerKey);
- }
-
- @Override
- public void onResolveServiceFailed(int listenerKey, int error) {
- sendError(RESOLVE_SERVICE_FAILED, listenerKey, error);
- }
-
- @Override
- public void onResolveServiceSucceeded(int listenerKey, NsdServiceInfo info) {
- sendInfo(RESOLVE_SERVICE_SUCCEEDED, listenerKey, info);
- }
- }
-
- /**
- * Failures are passed with {@link RegistrationListener#onRegistrationFailed},
- * {@link RegistrationListener#onUnregistrationFailed},
- * {@link DiscoveryListener#onStartDiscoveryFailed},
- * {@link DiscoveryListener#onStopDiscoveryFailed} or {@link ResolveListener#onResolveFailed}.
- *
- * Indicates that the operation failed due to an internal error.
- */
- public static final int FAILURE_INTERNAL_ERROR = 0;
-
- /**
- * Indicates that the operation failed because it is already active.
- */
- public static final int FAILURE_ALREADY_ACTIVE = 3;
-
- /**
- * Indicates that the operation failed because the maximum outstanding
- * requests from the applications have reached.
- */
- public static final int FAILURE_MAX_LIMIT = 4;
-
- /** Interface for callback invocation for service discovery */
- public interface DiscoveryListener {
-
- public void onStartDiscoveryFailed(String serviceType, int errorCode);
-
- public void onStopDiscoveryFailed(String serviceType, int errorCode);
-
- public void onDiscoveryStarted(String serviceType);
-
- public void onDiscoveryStopped(String serviceType);
-
- public void onServiceFound(NsdServiceInfo serviceInfo);
-
- public void onServiceLost(NsdServiceInfo serviceInfo);
- }
-
- /** Interface for callback invocation for service registration */
- public interface RegistrationListener {
-
- public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
-
- public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
-
- public void onServiceRegistered(NsdServiceInfo serviceInfo);
-
- public void onServiceUnregistered(NsdServiceInfo serviceInfo);
- }
-
- /** Interface for callback invocation for service resolution */
- public interface ResolveListener {
-
- public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode);
-
- public void onServiceResolved(NsdServiceInfo serviceInfo);
- }
-
- @VisibleForTesting
- class ServiceHandler extends Handler {
- ServiceHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message message) {
- final int what = message.what;
- final int key = message.arg2;
- final Object listener;
- final NsdServiceInfo ns;
- final Executor executor;
- synchronized (mMapLock) {
- listener = mListenerMap.get(key);
- ns = mServiceMap.get(key);
- executor = mExecutorMap.get(key);
- }
- if (listener == null) {
- Log.d(TAG, "Stale key " + message.arg2);
- return;
- }
- if (DBG) {
- Log.d(TAG, "received " + nameOf(what) + " for key " + key + ", service " + ns);
- }
- switch (what) {
- case DISCOVER_SERVICES_STARTED:
- final String s = getNsdServiceInfoType((NsdServiceInfo) message.obj);
- executor.execute(() -> ((DiscoveryListener) listener).onDiscoveryStarted(s));
- break;
- case DISCOVER_SERVICES_FAILED:
- removeListener(key);
- executor.execute(() -> ((DiscoveryListener) listener).onStartDiscoveryFailed(
- getNsdServiceInfoType(ns), message.arg1));
- break;
- case SERVICE_FOUND:
- executor.execute(() -> ((DiscoveryListener) listener).onServiceFound(
- (NsdServiceInfo) message.obj));
- break;
- case SERVICE_LOST:
- executor.execute(() -> ((DiscoveryListener) listener).onServiceLost(
- (NsdServiceInfo) message.obj));
- break;
- case STOP_DISCOVERY_FAILED:
- // TODO: failure to stop discovery should be internal and retried internally, as
- // the effect for the client is indistinguishable from STOP_DISCOVERY_SUCCEEDED
- removeListener(key);
- executor.execute(() -> ((DiscoveryListener) listener).onStopDiscoveryFailed(
- getNsdServiceInfoType(ns), message.arg1));
- break;
- case STOP_DISCOVERY_SUCCEEDED:
- removeListener(key);
- executor.execute(() -> ((DiscoveryListener) listener).onDiscoveryStopped(
- getNsdServiceInfoType(ns)));
- break;
- case REGISTER_SERVICE_FAILED:
- removeListener(key);
- executor.execute(() -> ((RegistrationListener) listener).onRegistrationFailed(
- ns, message.arg1));
- break;
- case REGISTER_SERVICE_SUCCEEDED:
- executor.execute(() -> ((RegistrationListener) listener).onServiceRegistered(
- (NsdServiceInfo) message.obj));
- break;
- case UNREGISTER_SERVICE_FAILED:
- removeListener(key);
- executor.execute(() -> ((RegistrationListener) listener).onUnregistrationFailed(
- ns, message.arg1));
- break;
- case UNREGISTER_SERVICE_SUCCEEDED:
- // TODO: do not unregister listener until service is unregistered, or provide
- // alternative way for unregistering ?
- removeListener(message.arg2);
- executor.execute(() -> ((RegistrationListener) listener).onServiceUnregistered(
- ns));
- break;
- case RESOLVE_SERVICE_FAILED:
- removeListener(key);
- executor.execute(() -> ((ResolveListener) listener).onResolveFailed(
- ns, message.arg1));
- break;
- case RESOLVE_SERVICE_SUCCEEDED:
- removeListener(key);
- executor.execute(() -> ((ResolveListener) listener).onServiceResolved(
- (NsdServiceInfo) message.obj));
- break;
- default:
- Log.d(TAG, "Ignored " + message);
- break;
- }
- }
- }
-
- private int nextListenerKey() {
- // Ensure mListenerKey >= FIRST_LISTENER_KEY;
- mListenerKey = Math.max(FIRST_LISTENER_KEY, mListenerKey + 1);
- return mListenerKey;
- }
-
- // Assert that the listener is not in the map, then add it and returns its key
- private int putListener(Object listener, Executor e, NsdServiceInfo s) {
- checkListener(listener);
- final int key;
- synchronized (mMapLock) {
- int valueIndex = mListenerMap.indexOfValue(listener);
- if (valueIndex != -1) {
- throw new IllegalArgumentException("listener already in use");
- }
- key = nextListenerKey();
- mListenerMap.put(key, listener);
- mServiceMap.put(key, s);
- mExecutorMap.put(key, e);
- }
- return key;
- }
-
- private void removeListener(int key) {
- synchronized (mMapLock) {
- mListenerMap.remove(key);
- mServiceMap.remove(key);
- mExecutorMap.remove(key);
- }
- }
-
- private int getListenerKey(Object listener) {
- checkListener(listener);
- synchronized (mMapLock) {
- int valueIndex = mListenerMap.indexOfValue(listener);
- if (valueIndex == -1) {
- throw new IllegalArgumentException("listener not registered");
- }
- return mListenerMap.keyAt(valueIndex);
- }
- }
-
- private static String getNsdServiceInfoType(NsdServiceInfo s) {
- if (s == null) return "?";
- return s.getServiceType();
- }
-
- /**
- * Register a service to be discovered by other services.
- *
- * <p> The function call immediately returns after sending a request to register service
- * to the framework. The application is notified of a successful registration
- * through the callback {@link RegistrationListener#onServiceRegistered} or a failure
- * through {@link RegistrationListener#onRegistrationFailed}.
- *
- * <p> The application should call {@link #unregisterService} when the service
- * registration is no longer required, and/or whenever the application is stopped.
- *
- * @param serviceInfo The service being registered
- * @param protocolType The service discovery protocol
- * @param listener The listener notifies of a successful registration and is used to
- * unregister this service through a call on {@link #unregisterService}. Cannot be null.
- * Cannot be in use for an active service registration.
- */
- public void registerService(NsdServiceInfo serviceInfo, int protocolType,
- RegistrationListener listener) {
- registerService(serviceInfo, protocolType, Runnable::run, listener);
- }
-
- /**
- * Register a service to be discovered by other services.
- *
- * <p> The function call immediately returns after sending a request to register service
- * to the framework. The application is notified of a successful registration
- * through the callback {@link RegistrationListener#onServiceRegistered} or a failure
- * through {@link RegistrationListener#onRegistrationFailed}.
- *
- * <p> The application should call {@link #unregisterService} when the service
- * registration is no longer required, and/or whenever the application is stopped.
- * @param serviceInfo The service being registered
- * @param protocolType The service discovery protocol
- * @param executor Executor to run listener callbacks with
- * @param listener The listener notifies of a successful registration and is used to
- * unregister this service through a call on {@link #unregisterService}. Cannot be null.
- */
- public void registerService(@NonNull NsdServiceInfo serviceInfo, int protocolType,
- @NonNull Executor executor, @NonNull RegistrationListener listener) {
- if (serviceInfo.getPort() <= 0) {
- throw new IllegalArgumentException("Invalid port number");
- }
- checkServiceInfo(serviceInfo);
- checkProtocol(protocolType);
- int key = putListener(listener, executor, serviceInfo);
- try {
- mService.registerService(key, serviceInfo);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Unregister a service registered through {@link #registerService}. A successful
- * unregister is notified to the application with a call to
- * {@link RegistrationListener#onServiceUnregistered}.
- *
- * @param listener This should be the listener object that was passed to
- * {@link #registerService}. It identifies the service that should be unregistered
- * and notifies of a successful or unsuccessful unregistration via the listener
- * callbacks. In API versions 20 and above, the listener object may be used for
- * another service registration once the callback has been called. In API versions <= 19,
- * there is no entirely reliable way to know when a listener may be re-used, and a new
- * listener should be created for each service registration request.
- */
- public void unregisterService(RegistrationListener listener) {
- int id = getListenerKey(listener);
- try {
- mService.unregisterService(id);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Initiate service discovery to browse for instances of a service type. Service discovery
- * consumes network bandwidth and will continue until the application calls
- * {@link #stopServiceDiscovery}.
- *
- * <p> The function call immediately returns after sending a request to start service
- * discovery to the framework. The application is notified of a success to initiate
- * discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure
- * through {@link DiscoveryListener#onStartDiscoveryFailed}.
- *
- * <p> Upon successful start, application is notified when a service is found with
- * {@link DiscoveryListener#onServiceFound} or when a service is lost with
- * {@link DiscoveryListener#onServiceLost}.
- *
- * <p> Upon failure to start, service discovery is not active and application does
- * not need to invoke {@link #stopServiceDiscovery}
- *
- * <p> The application should call {@link #stopServiceDiscovery} when discovery of this
- * service type is no longer required, and/or whenever the application is paused or
- * stopped.
- *
- * @param serviceType The service type being discovered. Examples include "_http._tcp" for
- * http services or "_ipp._tcp" for printers
- * @param protocolType The service discovery protocol
- * @param listener The listener notifies of a successful discovery and is used
- * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}.
- * Cannot be null. Cannot be in use for an active service discovery.
- */
- public void discoverServices(String serviceType, int protocolType, DiscoveryListener listener) {
- discoverServices(serviceType, protocolType, (Network) null, Runnable::run, listener);
- }
-
- /**
- * Initiate service discovery to browse for instances of a service type. Service discovery
- * consumes network bandwidth and will continue until the application calls
- * {@link #stopServiceDiscovery}.
- *
- * <p> The function call immediately returns after sending a request to start service
- * discovery to the framework. The application is notified of a success to initiate
- * discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure
- * through {@link DiscoveryListener#onStartDiscoveryFailed}.
- *
- * <p> Upon successful start, application is notified when a service is found with
- * {@link DiscoveryListener#onServiceFound} or when a service is lost with
- * {@link DiscoveryListener#onServiceLost}.
- *
- * <p> Upon failure to start, service discovery is not active and application does
- * not need to invoke {@link #stopServiceDiscovery}
- *
- * <p> The application should call {@link #stopServiceDiscovery} when discovery of this
- * service type is no longer required, and/or whenever the application is paused or
- * stopped.
- * @param serviceType The service type being discovered. Examples include "_http._tcp" for
- * http services or "_ipp._tcp" for printers
- * @param protocolType The service discovery protocol
- * @param network Network to discover services on, or null to discover on all available networks
- * @param executor Executor to run listener callbacks with
- * @param listener The listener notifies of a successful discovery and is used
- * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}.
- */
- public void discoverServices(@NonNull String serviceType, int protocolType,
- @Nullable Network network, @NonNull Executor executor,
- @NonNull DiscoveryListener listener) {
- if (TextUtils.isEmpty(serviceType)) {
- throw new IllegalArgumentException("Service type cannot be empty");
- }
- checkProtocol(protocolType);
-
- NsdServiceInfo s = new NsdServiceInfo();
- s.setServiceType(serviceType);
- s.setNetwork(network);
-
- int key = putListener(listener, executor, s);
- try {
- mService.discoverServices(key, s);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Initiate service discovery to browse for instances of a service type. Service discovery
- * consumes network bandwidth and will continue until the application calls
- * {@link #stopServiceDiscovery}.
- *
- * <p> The function call immediately returns after sending a request to start service
- * discovery to the framework. The application is notified of a success to initiate
- * discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure
- * through {@link DiscoveryListener#onStartDiscoveryFailed}.
- *
- * <p> Upon successful start, application is notified when a service is found with
- * {@link DiscoveryListener#onServiceFound} or when a service is lost with
- * {@link DiscoveryListener#onServiceLost}.
- *
- * <p> Upon failure to start, service discovery is not active and application does
- * not need to invoke {@link #stopServiceDiscovery}
- *
- * <p> The application should call {@link #stopServiceDiscovery} when discovery of this
- * service type is no longer required, and/or whenever the application is paused or
- * stopped.
- *
- * <p> During discovery, new networks may connect or existing networks may disconnect - for
- * example if wifi is reconnected. When a service was found on a network that disconnects,
- * {@link DiscoveryListener#onServiceLost} will be called. If a new network connects that
- * matches the {@link NetworkRequest}, {@link DiscoveryListener#onServiceFound} will be called
- * for services found on that network. Applications that do not want to track networks
- * themselves are encouraged to use this method instead of other overloads of
- * {@code discoverServices}, as they will receive proper notifications when a service becomes
- * available or unavailable due to network changes.
- * @param serviceType The service type being discovered. Examples include "_http._tcp" for
- * http services or "_ipp._tcp" for printers
- * @param protocolType The service discovery protocol
- * @param networkRequest Request specifying networks that should be considered when discovering
- * @param executor Executor to run listener callbacks with
- * @param listener The listener notifies of a successful discovery and is used
- * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}.
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- public void discoverServices(@NonNull String serviceType, int protocolType,
- @NonNull NetworkRequest networkRequest, @NonNull Executor executor,
- @NonNull DiscoveryListener listener) {
- if (TextUtils.isEmpty(serviceType)) {
- throw new IllegalArgumentException("Service type cannot be empty");
- }
- Objects.requireNonNull(networkRequest, "NetworkRequest cannot be null");
- checkProtocol(protocolType);
-
- NsdServiceInfo s = new NsdServiceInfo();
- s.setServiceType(serviceType);
-
- final int baseListenerKey = putListener(listener, executor, s);
-
- final PerNetworkDiscoveryTracker discoveryInfo = new PerNetworkDiscoveryTracker(
- serviceType, protocolType, executor, listener);
-
- synchronized (mPerNetworkDiscoveryMap) {
- mPerNetworkDiscoveryMap.put(baseListenerKey, discoveryInfo);
- discoveryInfo.start(networkRequest);
- }
- }
-
- /**
- * Stop service discovery initiated with {@link #discoverServices}. An active service
- * discovery is notified to the application with {@link DiscoveryListener#onDiscoveryStarted}
- * and it stays active until the application invokes a stop service discovery. A successful
- * stop is notified to with a call to {@link DiscoveryListener#onDiscoveryStopped}.
- *
- * <p> Upon failure to stop service discovery, application is notified through
- * {@link DiscoveryListener#onStopDiscoveryFailed}.
- *
- * @param listener This should be the listener object that was passed to {@link #discoverServices}.
- * It identifies the discovery that should be stopped and notifies of a successful or
- * unsuccessful stop. In API versions 20 and above, the listener object may be used for
- * another service discovery once the callback has been called. In API versions <= 19,
- * there is no entirely reliable way to know when a listener may be re-used, and a new
- * listener should be created for each service discovery request.
- */
- public void stopServiceDiscovery(DiscoveryListener listener) {
- int id = getListenerKey(listener);
- // If this is a PerNetworkDiscovery request, handle it as such
- synchronized (mPerNetworkDiscoveryMap) {
- final PerNetworkDiscoveryTracker info = mPerNetworkDiscoveryMap.get(id);
- if (info != null) {
- info.requestStop();
- return;
- }
- }
- try {
- mService.stopDiscovery(id);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Resolve a discovered service. An application can resolve a service right before
- * establishing a connection to fetch the IP and port details on which to setup
- * the connection.
- *
- * @param serviceInfo service to be resolved
- * @param listener to receive callback upon success or failure. Cannot be null.
- * Cannot be in use for an active service resolution.
- */
- public void resolveService(NsdServiceInfo serviceInfo, ResolveListener listener) {
- resolveService(serviceInfo, Runnable::run, listener);
- }
-
- /**
- * Resolve a discovered service. An application can resolve a service right before
- * establishing a connection to fetch the IP and port details on which to setup
- * the connection.
- * @param serviceInfo service to be resolved
- * @param executor Executor to run listener callbacks with
- * @param listener to receive callback upon success or failure.
- */
- public void resolveService(@NonNull NsdServiceInfo serviceInfo,
- @NonNull Executor executor, @NonNull ResolveListener listener) {
- checkServiceInfo(serviceInfo);
- int key = putListener(listener, executor, serviceInfo);
- try {
- mService.resolveService(key, serviceInfo);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- }
-
- private static void checkListener(Object listener) {
- Objects.requireNonNull(listener, "listener cannot be null");
- }
-
- private static void checkProtocol(int protocolType) {
- if (protocolType != PROTOCOL_DNS_SD) {
- throw new IllegalArgumentException("Unsupported protocol");
- }
- }
-
- private static void checkServiceInfo(NsdServiceInfo serviceInfo) {
- Objects.requireNonNull(serviceInfo, "NsdServiceInfo cannot be null");
- if (TextUtils.isEmpty(serviceInfo.getServiceName())) {
- throw new IllegalArgumentException("Service name cannot be empty");
- }
- if (TextUtils.isEmpty(serviceInfo.getServiceType())) {
- throw new IllegalArgumentException("Service type cannot be empty");
- }
- }
-}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/nsd/NsdServiceInfo.java b/packages/ConnectivityT/framework-t/src/android/net/nsd/NsdServiceInfo.java
deleted file mode 100644
index 8506db1..0000000
--- a/packages/ConnectivityT/framework-t/src/android/net/nsd/NsdServiceInfo.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2012 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.net.nsd;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.net.Network;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Base64;
-import android.util.Log;
-
-import java.io.UnsupportedEncodingException;
-import java.net.InetAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * A class representing service information for network service discovery
- * {@see NsdManager}
- */
-public final class NsdServiceInfo implements Parcelable {
-
- private static final String TAG = "NsdServiceInfo";
-
- private String mServiceName;
-
- private String mServiceType;
-
- private final ArrayMap<String, byte[]> mTxtRecord = new ArrayMap<>();
-
- private InetAddress mHost;
-
- private int mPort;
-
- @Nullable
- private Network mNetwork;
-
- public NsdServiceInfo() {
- }
-
- /** @hide */
- public NsdServiceInfo(String sn, String rt) {
- mServiceName = sn;
- mServiceType = rt;
- }
-
- /** Get the service name */
- public String getServiceName() {
- return mServiceName;
- }
-
- /** Set the service name */
- public void setServiceName(String s) {
- mServiceName = s;
- }
-
- /** Get the service type */
- public String getServiceType() {
- return mServiceType;
- }
-
- /** Set the service type */
- public void setServiceType(String s) {
- mServiceType = s;
- }
-
- /** Get the host address. The host address is valid for a resolved service. */
- public InetAddress getHost() {
- return mHost;
- }
-
- /** Set the host address */
- public void setHost(InetAddress s) {
- mHost = s;
- }
-
- /** Get port number. The port number is valid for a resolved service. */
- public int getPort() {
- return mPort;
- }
-
- /** Set port number */
- public void setPort(int p) {
- mPort = p;
- }
-
- /**
- * Unpack txt information from a base-64 encoded byte array.
- *
- * @param rawRecords The raw base64 encoded records string read from netd.
- *
- * @hide
- */
- public void setTxtRecords(@NonNull String rawRecords) {
- byte[] txtRecordsRawBytes = Base64.decode(rawRecords, Base64.DEFAULT);
-
- // There can be multiple TXT records after each other. Each record has to following format:
- //
- // byte type required meaning
- // ------------------- ------------------- -------- ----------------------------------
- // 0 unsigned 8 bit yes size of record excluding this byte
- // 1 - n ASCII but not '=' yes key
- // n + 1 '=' optional separator of key and value
- // n + 2 - record size uninterpreted bytes optional value
- //
- // Example legal records:
- // [11, 'm', 'y', 'k', 'e', 'y', '=', 0x0, 0x4, 0x65, 0x7, 0xff]
- // [17, 'm', 'y', 'K', 'e', 'y', 'W', 'i', 't', 'h', 'N', 'o', 'V', 'a', 'l', 'u', 'e', '=']
- // [12, 'm', 'y', 'B', 'o', 'o', 'l', 'e', 'a', 'n', 'K', 'e', 'y']
- //
- // Example corrupted records
- // [3, =, 1, 2] <- key is empty
- // [3, 0, =, 2] <- key contains non-ASCII character. We handle this by replacing the
- // invalid characters instead of skipping the record.
- // [30, 'a', =, 2] <- length exceeds total left over bytes in the TXT records array, we
- // handle this by reducing the length of the record as needed.
- int pos = 0;
- while (pos < txtRecordsRawBytes.length) {
- // recordLen is an unsigned 8 bit value
- int recordLen = txtRecordsRawBytes[pos] & 0xff;
- pos += 1;
-
- try {
- if (recordLen == 0) {
- throw new IllegalArgumentException("Zero sized txt record");
- } else if (pos + recordLen > txtRecordsRawBytes.length) {
- Log.w(TAG, "Corrupt record length (pos = " + pos + "): " + recordLen);
- recordLen = txtRecordsRawBytes.length - pos;
- }
-
- // Decode key-value records
- String key = null;
- byte[] value = null;
- int valueLen = 0;
- for (int i = pos; i < pos + recordLen; i++) {
- if (key == null) {
- if (txtRecordsRawBytes[i] == '=') {
- key = new String(txtRecordsRawBytes, pos, i - pos,
- StandardCharsets.US_ASCII);
- }
- } else {
- if (value == null) {
- value = new byte[recordLen - key.length() - 1];
- }
- value[valueLen] = txtRecordsRawBytes[i];
- valueLen++;
- }
- }
-
- // If '=' was not found we have a boolean record
- if (key == null) {
- key = new String(txtRecordsRawBytes, pos, recordLen, StandardCharsets.US_ASCII);
- }
-
- if (TextUtils.isEmpty(key)) {
- // Empty keys are not allowed (RFC6763 6.4)
- throw new IllegalArgumentException("Invalid txt record (key is empty)");
- }
-
- if (getAttributes().containsKey(key)) {
- // When we have a duplicate record, the later ones are ignored (RFC6763 6.4)
- throw new IllegalArgumentException("Invalid txt record (duplicate key \"" + key + "\")");
- }
-
- setAttribute(key, value);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "While parsing txt records (pos = " + pos + "): " + e.getMessage());
- }
-
- pos += recordLen;
- }
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public void setAttribute(String key, byte[] value) {
- if (TextUtils.isEmpty(key)) {
- throw new IllegalArgumentException("Key cannot be empty");
- }
-
- // Key must be printable US-ASCII, excluding =.
- for (int i = 0; i < key.length(); ++i) {
- char character = key.charAt(i);
- if (character < 0x20 || character > 0x7E) {
- throw new IllegalArgumentException("Key strings must be printable US-ASCII");
- } else if (character == 0x3D) {
- throw new IllegalArgumentException("Key strings must not include '='");
- }
- }
-
- // Key length + value length must be < 255.
- if (key.length() + (value == null ? 0 : value.length) >= 255) {
- throw new IllegalArgumentException("Key length + value length must be < 255 bytes");
- }
-
- // Warn if key is > 9 characters, as recommended by RFC 6763 section 6.4.
- if (key.length() > 9) {
- Log.w(TAG, "Key lengths > 9 are discouraged: " + key);
- }
-
- // Check against total TXT record size limits.
- // Arbitrary 400 / 1300 byte limits taken from RFC 6763 section 6.2.
- int txtRecordSize = getTxtRecordSize();
- int futureSize = txtRecordSize + key.length() + (value == null ? 0 : value.length) + 2;
- if (futureSize > 1300) {
- throw new IllegalArgumentException("Total length of attributes must be < 1300 bytes");
- } else if (futureSize > 400) {
- Log.w(TAG, "Total length of all attributes exceeds 400 bytes; truncation may occur");
- }
-
- mTxtRecord.put(key, value);
- }
-
- /**
- * Add a service attribute as a key/value pair.
- *
- * <p> Service attributes are included as DNS-SD TXT record pairs.
- *
- * <p> The key must be US-ASCII printable characters, excluding the '=' character. Values may
- * be UTF-8 strings or null. The total length of key + value must be less than 255 bytes.
- *
- * <p> Keys should be short, ideally no more than 9 characters, and unique per instance of
- * {@link NsdServiceInfo}. Calling {@link #setAttribute} twice with the same key will overwrite
- * first value.
- */
- public void setAttribute(String key, String value) {
- try {
- setAttribute(key, value == null ? (byte []) null : value.getBytes("UTF-8"));
- } catch (UnsupportedEncodingException e) {
- throw new IllegalArgumentException("Value must be UTF-8");
- }
- }
-
- /** Remove an attribute by key */
- public void removeAttribute(String key) {
- mTxtRecord.remove(key);
- }
-
- /**
- * Retrieve attributes as a map of String keys to byte[] values. The attributes map is only
- * valid for a resolved service.
- *
- * <p> The returned map is unmodifiable; changes must be made through {@link #setAttribute} and
- * {@link #removeAttribute}.
- */
- public Map<String, byte[]> getAttributes() {
- return Collections.unmodifiableMap(mTxtRecord);
- }
-
- private int getTxtRecordSize() {
- int txtRecordSize = 0;
- for (Map.Entry<String, byte[]> entry : mTxtRecord.entrySet()) {
- txtRecordSize += 2; // One for the length byte, one for the = between key and value.
- txtRecordSize += entry.getKey().length();
- byte[] value = entry.getValue();
- txtRecordSize += value == null ? 0 : value.length;
- }
- return txtRecordSize;
- }
-
- /** @hide */
- public @NonNull byte[] getTxtRecord() {
- int txtRecordSize = getTxtRecordSize();
- if (txtRecordSize == 0) {
- return new byte[]{};
- }
-
- byte[] txtRecord = new byte[txtRecordSize];
- int ptr = 0;
- for (Map.Entry<String, byte[]> entry : mTxtRecord.entrySet()) {
- String key = entry.getKey();
- byte[] value = entry.getValue();
-
- // One byte to record the length of this key/value pair.
- txtRecord[ptr++] = (byte) (key.length() + (value == null ? 0 : value.length) + 1);
-
- // The key, in US-ASCII.
- // Note: use the StandardCharsets const here because it doesn't raise exceptions and we
- // already know the key is ASCII at this point.
- System.arraycopy(key.getBytes(StandardCharsets.US_ASCII), 0, txtRecord, ptr,
- key.length());
- ptr += key.length();
-
- // US-ASCII '=' character.
- txtRecord[ptr++] = (byte)'=';
-
- // The value, as any raw bytes.
- if (value != null) {
- System.arraycopy(value, 0, txtRecord, ptr, value.length);
- ptr += value.length;
- }
- }
- return txtRecord;
- }
-
- /**
- * Get the network where the service can be found.
- *
- * This is never null if this {@link NsdServiceInfo} was obtained from
- * {@link NsdManager#discoverServices} or {@link NsdManager#resolveService}.
- */
- @Nullable
- public Network getNetwork() {
- return mNetwork;
- }
-
- /**
- * Set the network where the service can be found.
- * @param network The network, or null to search for, or to announce, the service on all
- * connected networks.
- */
- public void setNetwork(@Nullable Network network) {
- mNetwork = network;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("name: ").append(mServiceName)
- .append(", type: ").append(mServiceType)
- .append(", host: ").append(mHost)
- .append(", port: ").append(mPort)
- .append(", network: ").append(mNetwork);
-
- byte[] txtRecord = getTxtRecord();
- sb.append(", txtRecord: ").append(new String(txtRecord, StandardCharsets.UTF_8));
- return sb.toString();
- }
-
- /** Implement the Parcelable interface */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mServiceName);
- dest.writeString(mServiceType);
- if (mHost != null) {
- dest.writeInt(1);
- dest.writeByteArray(mHost.getAddress());
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(mPort);
-
- // TXT record key/value pairs.
- dest.writeInt(mTxtRecord.size());
- for (String key : mTxtRecord.keySet()) {
- byte[] value = mTxtRecord.get(key);
- if (value != null) {
- dest.writeInt(1);
- dest.writeInt(value.length);
- dest.writeByteArray(value);
- } else {
- dest.writeInt(0);
- }
- dest.writeString(key);
- }
-
- dest.writeParcelable(mNetwork, 0);
- }
-
- /** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<NsdServiceInfo> CREATOR =
- new Creator<NsdServiceInfo>() {
- public NsdServiceInfo createFromParcel(Parcel in) {
- NsdServiceInfo info = new NsdServiceInfo();
- info.mServiceName = in.readString();
- info.mServiceType = in.readString();
-
- if (in.readInt() == 1) {
- try {
- info.mHost = InetAddress.getByAddress(in.createByteArray());
- } catch (java.net.UnknownHostException e) {}
- }
-
- info.mPort = in.readInt();
-
- // TXT record key/value pairs.
- int recordCount = in.readInt();
- for (int i = 0; i < recordCount; ++i) {
- byte[] valueArray = null;
- if (in.readInt() == 1) {
- int valueLength = in.readInt();
- valueArray = new byte[valueLength];
- in.readByteArray(valueArray);
- }
- info.mTxtRecord.put(in.readString(), valueArray);
- }
- info.mNetwork = in.readParcelable(null, Network.class);
- return info;
- }
-
- public NsdServiceInfo[] newArray(int size) {
- return new NsdServiceInfo[size];
- }
- };
-}
diff --git a/packages/ConnectivityT/service/Android.bp b/packages/ConnectivityT/service/Android.bp
deleted file mode 100644
index 4b799c5..0000000
--- a/packages/ConnectivityT/service/Android.bp
+++ /dev/null
@@ -1,156 +0,0 @@
-//
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
- // See: http://go/android-license-faq
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-// NetworkStats related libraries.
-
-filegroup {
- name: "services.connectivity-netstats-sources",
- srcs: [
- "src/com/android/server/net/NetworkIdentity*.java",
- "src/com/android/server/net/NetworkStats*.java",
- "src/com/android/server/net/BpfInterfaceMapUpdater.java",
- "src/com/android/server/net/InterfaceMapValue.java",
- "src/com/android/server/net/CookieTagMapKey.java",
- "src/com/android/server/net/CookieTagMapValue.java",
- "src/com/android/server/net/StatsMapKey.java",
- "src/com/android/server/net/StatsMapValue.java",
- "src/com/android/server/net/UidStatsMapKey.java",
- ],
- path: "src",
- visibility: [
- "//visibility:private",
- ],
-}
-
-// For test code only.
-filegroup {
- name: "lib_networkStatsFactory_native",
- srcs: [
- "jni/com_android_server_net_NetworkStatsFactory.cpp",
- ],
- path: "jni",
- visibility: [
- "//packages/modules/Connectivity:__subpackages__",
- ],
-}
-
-filegroup {
- name: "services.connectivity-netstats-jni-sources",
- srcs: [
- "jni/com_android_server_net_NetworkStatsFactory.cpp",
- "jni/com_android_server_net_NetworkStatsService.cpp",
- ],
- path: "jni",
- visibility: [
- "//packages/modules/Connectivity:__subpackages__",
- ],
-}
-
-// Nsd related libraries.
-
-filegroup {
- name: "services.connectivity-nsd-sources",
- srcs: [
- "src/com/android/server/INativeDaemon*.java",
- "src/com/android/server/NativeDaemon*.java",
- "src/com/android/server/Nsd*.java",
- ],
- path: "src",
- visibility: [
- "//visibility:private",
- ],
-}
-
-// IpSec related libraries.
-
-filegroup {
- name: "services.connectivity-ipsec-sources",
- srcs: [
- "src/com/android/server/IpSecService.java",
- ],
- path: "src",
- visibility: [
- "//visibility:private",
- ],
-}
-
-// Ethernet related libraries.
-
-filegroup {
- name: "services.connectivity-ethernet-sources",
- srcs: [
- "src/com/android/server/net/DelayedDiskWrite.java",
- "src/com/android/server/net/IpConfigStore.java",
- ],
- path: "src",
- visibility: [
- "//frameworks/opt/net/ethernet/tests",
- ],
-}
-
-// Connectivity-T common libraries.
-
-// TODO: remove this empty filegroup.
-filegroup {
- name: "services.connectivity-tiramisu-sources",
- srcs: [],
- path: "src",
- visibility: ["//frameworks/base/services/core"],
-}
-
-filegroup {
- name: "services.connectivity-tiramisu-updatable-sources",
- srcs: [
- ":services.connectivity-ethernet-sources",
- ":services.connectivity-ipsec-sources",
- ":services.connectivity-netstats-sources",
- ":services.connectivity-nsd-sources",
- ],
- path: "src",
- visibility: [
- "//packages/modules/Connectivity:__subpackages__",
- ],
-}
-
-cc_library_shared {
- name: "libcom_android_net_module_util_jni",
- min_sdk_version: "30",
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- "-Wthread-safety",
- ],
- srcs: [
- "jni/onload.cpp",
- ],
- stl: "libc++_static",
- static_libs: [
- "libnet_utils_device_common_bpfjni",
- ],
- shared_libs: [
- "liblog",
- "libnativehelper",
- ],
- apex_available: [
- "//apex_available:platform",
- ],
-}
diff --git a/packages/ConnectivityT/service/jni/com_android_server_net_NetworkStatsFactory.cpp b/packages/ConnectivityT/service/jni/com_android_server_net_NetworkStatsFactory.cpp
deleted file mode 100644
index 8b6526ff..0000000
--- a/packages/ConnectivityT/service/jni/com_android_server_net_NetworkStatsFactory.cpp
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Copyright (C) 2013 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 "NetworkStats"
-
-#include <errno.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <vector>
-
-#include <jni.h>
-
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedUtfChars.h>
-#include <nativehelper/ScopedLocalRef.h>
-#include <nativehelper/ScopedPrimitiveArray.h>
-
-#include <utils/Log.h>
-#include <utils/misc.h>
-
-#include "android-base/unique_fd.h"
-#include "bpf/BpfUtils.h"
-#include "netdbpf/BpfNetworkStats.h"
-
-using android::bpf::parseBpfNetworkStatsDetail;
-using android::bpf::stats_line;
-
-namespace android {
-
-static jclass gStringClass;
-
-static struct {
- jfieldID size;
- jfieldID capacity;
- jfieldID iface;
- jfieldID uid;
- jfieldID set;
- jfieldID tag;
- jfieldID metered;
- jfieldID roaming;
- jfieldID defaultNetwork;
- jfieldID rxBytes;
- jfieldID rxPackets;
- jfieldID txBytes;
- jfieldID txPackets;
- jfieldID operations;
-} gNetworkStatsClassInfo;
-
-static jobjectArray get_string_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
-{
- if (!grow) {
- jobjectArray array = (jobjectArray)env->GetObjectField(obj, field);
- if (array != NULL) {
- return array;
- }
- }
- return env->NewObjectArray(size, gStringClass, NULL);
-}
-
-static jintArray get_int_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
-{
- if (!grow) {
- jintArray array = (jintArray)env->GetObjectField(obj, field);
- if (array != NULL) {
- return array;
- }
- }
- return env->NewIntArray(size);
-}
-
-static jlongArray get_long_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
-{
- if (!grow) {
- jlongArray array = (jlongArray)env->GetObjectField(obj, field);
- if (array != NULL) {
- return array;
- }
- }
- return env->NewLongArray(size);
-}
-
-static int legacyReadNetworkStatsDetail(std::vector<stats_line>* lines,
- const std::vector<std::string>& limitIfaces,
- int limitTag, int limitUid, const char* path) {
- FILE* fp = fopen(path, "re");
- if (fp == NULL) {
- return -1;
- }
-
- int lastIdx = 1;
- int idx;
- char buffer[384];
- while (fgets(buffer, sizeof(buffer), fp) != NULL) {
- stats_line s;
- int64_t rawTag;
- char* pos = buffer;
- char* endPos;
- // First field is the index.
- idx = (int)strtol(pos, &endPos, 10);
- //ALOGI("Index #%d: %s", idx, buffer);
- if (pos == endPos) {
- // Skip lines that don't start with in index. In particular,
- // this will skip the initial header line.
- continue;
- }
- if (idx != lastIdx + 1) {
- ALOGE("inconsistent idx=%d after lastIdx=%d: %s", idx, lastIdx, buffer);
- fclose(fp);
- return -1;
- }
- lastIdx = idx;
- pos = endPos;
- // Skip whitespace.
- while (*pos == ' ') {
- pos++;
- }
- // Next field is iface.
- int ifaceIdx = 0;
- while (*pos != ' ' && *pos != 0 && ifaceIdx < (int)(sizeof(s.iface)-1)) {
- s.iface[ifaceIdx] = *pos;
- ifaceIdx++;
- pos++;
- }
- if (*pos != ' ') {
- ALOGE("bad iface: %s", buffer);
- fclose(fp);
- return -1;
- }
- s.iface[ifaceIdx] = 0;
- if (limitIfaces.size() > 0) {
- // Is this an iface the caller is interested in?
- int i = 0;
- while (i < (int)limitIfaces.size()) {
- if (limitIfaces[i] == s.iface) {
- break;
- }
- i++;
- }
- if (i >= (int)limitIfaces.size()) {
- // Nothing matched; skip this line.
- //ALOGI("skipping due to iface: %s", buffer);
- continue;
- }
- }
-
- // Ignore whitespace
- while (*pos == ' ') pos++;
-
- // Find end of tag field
- endPos = pos;
- while (*endPos != ' ') endPos++;
-
- // Three digit field is always 0x0, otherwise parse
- if (endPos - pos == 3) {
- rawTag = 0;
- } else {
- if (sscanf(pos, "%" PRIx64, &rawTag) != 1) {
- ALOGE("bad tag: %s", pos);
- fclose(fp);
- return -1;
- }
- }
- s.tag = rawTag >> 32;
- if (limitTag != -1 && s.tag != static_cast<uint32_t>(limitTag)) {
- //ALOGI("skipping due to tag: %s", buffer);
- continue;
- }
- pos = endPos;
-
- // Ignore whitespace
- while (*pos == ' ') pos++;
-
- // Parse remaining fields.
- if (sscanf(pos, "%u %u %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64,
- &s.uid, &s.set, &s.rxBytes, &s.rxPackets,
- &s.txBytes, &s.txPackets) == 6) {
- if (limitUid != -1 && static_cast<uint32_t>(limitUid) != s.uid) {
- //ALOGI("skipping due to uid: %s", buffer);
- continue;
- }
- lines->push_back(s);
- } else {
- //ALOGI("skipping due to bad remaining fields: %s", pos);
- }
- }
-
- if (fclose(fp) != 0) {
- ALOGE("Failed to close netstats file");
- return -1;
- }
- return 0;
-}
-
-static int statsLinesToNetworkStats(JNIEnv* env, jclass clazz, jobject stats,
- std::vector<stats_line>& lines) {
- int size = lines.size();
-
- bool grow = size > env->GetIntField(stats, gNetworkStatsClassInfo.capacity);
-
- ScopedLocalRef<jobjectArray> iface(env, get_string_array(env, stats,
- gNetworkStatsClassInfo.iface, size, grow));
- if (iface.get() == NULL) return -1;
- ScopedIntArrayRW uid(env, get_int_array(env, stats,
- gNetworkStatsClassInfo.uid, size, grow));
- if (uid.get() == NULL) return -1;
- ScopedIntArrayRW set(env, get_int_array(env, stats,
- gNetworkStatsClassInfo.set, size, grow));
- if (set.get() == NULL) return -1;
- ScopedIntArrayRW tag(env, get_int_array(env, stats,
- gNetworkStatsClassInfo.tag, size, grow));
- if (tag.get() == NULL) return -1;
- ScopedIntArrayRW metered(env, get_int_array(env, stats,
- gNetworkStatsClassInfo.metered, size, grow));
- if (metered.get() == NULL) return -1;
- ScopedIntArrayRW roaming(env, get_int_array(env, stats,
- gNetworkStatsClassInfo.roaming, size, grow));
- if (roaming.get() == NULL) return -1;
- ScopedIntArrayRW defaultNetwork(env, get_int_array(env, stats,
- gNetworkStatsClassInfo.defaultNetwork, size, grow));
- if (defaultNetwork.get() == NULL) return -1;
- ScopedLongArrayRW rxBytes(env, get_long_array(env, stats,
- gNetworkStatsClassInfo.rxBytes, size, grow));
- if (rxBytes.get() == NULL) return -1;
- ScopedLongArrayRW rxPackets(env, get_long_array(env, stats,
- gNetworkStatsClassInfo.rxPackets, size, grow));
- if (rxPackets.get() == NULL) return -1;
- ScopedLongArrayRW txBytes(env, get_long_array(env, stats,
- gNetworkStatsClassInfo.txBytes, size, grow));
- if (txBytes.get() == NULL) return -1;
- ScopedLongArrayRW txPackets(env, get_long_array(env, stats,
- gNetworkStatsClassInfo.txPackets, size, grow));
- if (txPackets.get() == NULL) return -1;
- ScopedLongArrayRW operations(env, get_long_array(env, stats,
- gNetworkStatsClassInfo.operations, size, grow));
- if (operations.get() == NULL) return -1;
-
- for (int i = 0; i < size; i++) {
- ScopedLocalRef<jstring> ifaceString(env, env->NewStringUTF(lines[i].iface));
- env->SetObjectArrayElement(iface.get(), i, ifaceString.get());
-
- uid[i] = lines[i].uid;
- set[i] = lines[i].set;
- tag[i] = lines[i].tag;
- // Metered, roaming and defaultNetwork are populated in Java-land.
- rxBytes[i] = lines[i].rxBytes;
- rxPackets[i] = lines[i].rxPackets;
- txBytes[i] = lines[i].txBytes;
- txPackets[i] = lines[i].txPackets;
- }
-
- env->SetIntField(stats, gNetworkStatsClassInfo.size, size);
- if (grow) {
- env->SetIntField(stats, gNetworkStatsClassInfo.capacity, size);
- env->SetObjectField(stats, gNetworkStatsClassInfo.iface, iface.get());
- env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray());
- env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray());
- env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray());
- env->SetObjectField(stats, gNetworkStatsClassInfo.metered, metered.getJavaArray());
- env->SetObjectField(stats, gNetworkStatsClassInfo.roaming, roaming.getJavaArray());
- env->SetObjectField(stats, gNetworkStatsClassInfo.defaultNetwork,
- defaultNetwork.getJavaArray());
- env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray());
- env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray());
- env->SetObjectField(stats, gNetworkStatsClassInfo.txBytes, txBytes.getJavaArray());
- env->SetObjectField(stats, gNetworkStatsClassInfo.txPackets, txPackets.getJavaArray());
- env->SetObjectField(stats, gNetworkStatsClassInfo.operations, operations.getJavaArray());
- }
- return 0;
-}
-
-static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstring path,
- jint limitUid, jobjectArray limitIfacesObj, jint limitTag,
- jboolean useBpfStats) {
-
- std::vector<std::string> limitIfaces;
- if (limitIfacesObj != NULL && env->GetArrayLength(limitIfacesObj) > 0) {
- int num = env->GetArrayLength(limitIfacesObj);
- for (int i = 0; i < num; i++) {
- jstring string = (jstring)env->GetObjectArrayElement(limitIfacesObj, i);
- ScopedUtfChars string8(env, string);
- if (string8.c_str() != NULL) {
- limitIfaces.push_back(std::string(string8.c_str()));
- }
- }
- }
- std::vector<stats_line> lines;
-
-
- if (useBpfStats) {
- if (parseBpfNetworkStatsDetail(&lines, limitIfaces, limitTag, limitUid) < 0)
- return -1;
- } else {
- ScopedUtfChars path8(env, path);
- if (path8.c_str() == NULL) {
- ALOGE("the qtaguid legacy path is invalid: %s", path8.c_str());
- return -1;
- }
- if (legacyReadNetworkStatsDetail(&lines, limitIfaces, limitTag,
- limitUid, path8.c_str()) < 0)
- return -1;
- }
-
- return statsLinesToNetworkStats(env, clazz, stats, lines);
-}
-
-static int readNetworkStatsDev(JNIEnv* env, jclass clazz, jobject stats) {
- std::vector<stats_line> lines;
-
- if (parseBpfNetworkStatsDev(&lines) < 0)
- return -1;
-
- return statsLinesToNetworkStats(env, clazz, stats, lines);
-}
-
-static const JNINativeMethod gMethods[] = {
- { "nativeReadNetworkStatsDetail",
- "(Landroid/net/NetworkStats;Ljava/lang/String;I[Ljava/lang/String;IZ)I",
- (void*) readNetworkStatsDetail },
- { "nativeReadNetworkStatsDev", "(Landroid/net/NetworkStats;)I",
- (void*) readNetworkStatsDev },
-};
-
-int register_android_server_net_NetworkStatsFactory(JNIEnv* env) {
- int err = jniRegisterNativeMethods(env, "com/android/server/net/NetworkStatsFactory", gMethods,
- NELEM(gMethods));
- gStringClass = env->FindClass("java/lang/String");
- gStringClass = static_cast<jclass>(env->NewGlobalRef(gStringClass));
-
- jclass clazz = env->FindClass("android/net/NetworkStats");
- gNetworkStatsClassInfo.size = env->GetFieldID(clazz, "size", "I");
- gNetworkStatsClassInfo.capacity = env->GetFieldID(clazz, "capacity", "I");
- gNetworkStatsClassInfo.iface = env->GetFieldID(clazz, "iface", "[Ljava/lang/String;");
- gNetworkStatsClassInfo.uid = env->GetFieldID(clazz, "uid", "[I");
- gNetworkStatsClassInfo.set = env->GetFieldID(clazz, "set", "[I");
- gNetworkStatsClassInfo.tag = env->GetFieldID(clazz, "tag", "[I");
- gNetworkStatsClassInfo.metered = env->GetFieldID(clazz, "metered", "[I");
- gNetworkStatsClassInfo.roaming = env->GetFieldID(clazz, "roaming", "[I");
- gNetworkStatsClassInfo.defaultNetwork = env->GetFieldID(clazz, "defaultNetwork", "[I");
- gNetworkStatsClassInfo.rxBytes = env->GetFieldID(clazz, "rxBytes", "[J");
- gNetworkStatsClassInfo.rxPackets = env->GetFieldID(clazz, "rxPackets", "[J");
- gNetworkStatsClassInfo.txBytes = env->GetFieldID(clazz, "txBytes", "[J");
- gNetworkStatsClassInfo.txPackets = env->GetFieldID(clazz, "txPackets", "[J");
- gNetworkStatsClassInfo.operations = env->GetFieldID(clazz, "operations", "[J");
-
- return err;
-}
-
-}
diff --git a/packages/ConnectivityT/service/jni/com_android_server_net_NetworkStatsService.cpp b/packages/ConnectivityT/service/jni/com_android_server_net_NetworkStatsService.cpp
deleted file mode 100644
index 39cbaf7..0000000
--- a/packages/ConnectivityT/service/jni/com_android_server_net_NetworkStatsService.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2010 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 "NetworkStatsNative"
-
-#include <cutils/qtaguid.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <jni.h>
-#include <nativehelper/ScopedUtfChars.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <utils/Log.h>
-#include <utils/misc.h>
-
-#include "bpf/BpfUtils.h"
-#include "netdbpf/BpfNetworkStats.h"
-
-using android::bpf::bpfGetUidStats;
-using android::bpf::bpfGetIfaceStats;
-
-namespace android {
-
-// NOTE: keep these in sync with TrafficStats.java
-static const uint64_t UNKNOWN = -1;
-
-enum StatsType {
- RX_BYTES = 0,
- RX_PACKETS = 1,
- TX_BYTES = 2,
- TX_PACKETS = 3,
- TCP_RX_PACKETS = 4,
- TCP_TX_PACKETS = 5
-};
-
-static uint64_t getStatsType(Stats* stats, StatsType type) {
- switch (type) {
- case RX_BYTES:
- return stats->rxBytes;
- case RX_PACKETS:
- return stats->rxPackets;
- case TX_BYTES:
- return stats->txBytes;
- case TX_PACKETS:
- return stats->txPackets;
- case TCP_RX_PACKETS:
- return stats->tcpRxPackets;
- case TCP_TX_PACKETS:
- return stats->tcpTxPackets;
- default:
- return UNKNOWN;
- }
-}
-
-static jlong getTotalStat(JNIEnv* env, jclass clazz, jint type) {
- Stats stats = {};
-
- if (bpfGetIfaceStats(NULL, &stats) == 0) {
- return getStatsType(&stats, (StatsType) type);
- } else {
- return UNKNOWN;
- }
-}
-
-static jlong getIfaceStat(JNIEnv* env, jclass clazz, jstring iface, jint type) {
- ScopedUtfChars iface8(env, iface);
- if (iface8.c_str() == NULL) {
- return UNKNOWN;
- }
-
- Stats stats = {};
-
- if (bpfGetIfaceStats(iface8.c_str(), &stats) == 0) {
- return getStatsType(&stats, (StatsType) type);
- } else {
- return UNKNOWN;
- }
-}
-
-static jlong getUidStat(JNIEnv* env, jclass clazz, jint uid, jint type) {
- Stats stats = {};
-
- if (bpfGetUidStats(uid, &stats) == 0) {
- return getStatsType(&stats, (StatsType) type);
- } else {
- return UNKNOWN;
- }
-}
-
-static const JNINativeMethod gMethods[] = {
- {"nativeGetTotalStat", "(I)J", (void*)getTotalStat},
- {"nativeGetIfaceStat", "(Ljava/lang/String;I)J", (void*)getIfaceStat},
- {"nativeGetUidStat", "(II)J", (void*)getUidStat},
-};
-
-int register_android_server_net_NetworkStatsService(JNIEnv* env) {
- return jniRegisterNativeMethods(env, "com/android/server/net/NetworkStatsService", gMethods,
- NELEM(gMethods));
-}
-
-}
diff --git a/packages/ConnectivityT/service/jni/onload.cpp b/packages/ConnectivityT/service/jni/onload.cpp
deleted file mode 100644
index bca4697..0000000
--- a/packages/ConnectivityT/service/jni/onload.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <nativehelper/JNIHelp.h>
-#include <log/log.h>
-
-namespace android {
-
-int register_com_android_net_module_util_BpfMap(JNIEnv* env, char const* class_name);
-
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
- JNIEnv *env;
- if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
- ALOGE("GetEnv failed");
- return JNI_ERR;
- }
-
- if (register_com_android_net_module_util_BpfMap(env,
- "com/android/net/module/util/BpfMap") < 0) return JNI_ERR;
-
- return JNI_VERSION_1_6;
-}
-
-};
-
diff --git a/packages/ConnectivityT/service/src/com/android/server/INativeDaemonConnectorCallbacks.java b/packages/ConnectivityT/service/src/com/android/server/INativeDaemonConnectorCallbacks.java
deleted file mode 100644
index 0cf9dcd..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/INativeDaemonConnectorCallbacks.java
+++ /dev/null
@@ -1,25 +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 com.android.server;
-
-interface INativeDaemonConnectorCallbacks {
-
- void onDaemonConnected();
- boolean onCheckHoldWakeLock(int code);
- boolean onEvent(int code, String raw, String[] cooked);
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/IpSecService.java b/packages/ConnectivityT/service/src/com/android/server/IpSecService.java
deleted file mode 100644
index 4bc40ea..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/IpSecService.java
+++ /dev/null
@@ -1,1878 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static android.Manifest.permission.DUMP;
-import static android.net.IpSecManager.INVALID_RESOURCE_ID;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-import static android.system.OsConstants.AF_UNSPEC;
-import static android.system.OsConstants.EINVAL;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-
-import android.annotation.NonNull;
-import android.app.AppOpsManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.IIpSecService;
-import android.net.INetd;
-import android.net.InetAddresses;
-import android.net.IpSecAlgorithm;
-import android.net.IpSecConfig;
-import android.net.IpSecManager;
-import android.net.IpSecSpiResponse;
-import android.net.IpSecTransform;
-import android.net.IpSecTransformResponse;
-import android.net.IpSecTunnelInterfaceResponse;
-import android.net.IpSecUdpEncapResponse;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.TrafficStats;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Range;
-import android.util.SparseArray;
-import android.util.SparseBooleanArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
-import com.android.net.module.util.BinderUtils;
-import com.android.net.module.util.NetdUtils;
-import com.android.net.module.util.PermissionUtils;
-
-import libcore.io.IoUtils;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * A service to manage multiple clients that want to access the IpSec API. The service is
- * responsible for maintaining a list of clients and managing the resources (and related quotas)
- * that each of them own.
- *
- * <p>Synchronization in IpSecService is done on all entrypoints due to potential race conditions at
- * the kernel/xfrm level. Further, this allows the simplifying assumption to be made that only one
- * thread is ever running at a time.
- *
- * @hide
- */
-public class IpSecService extends IIpSecService.Stub {
- private static final String TAG = "IpSecService";
- private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
- private static final int[] ADDRESS_FAMILIES =
- new int[] {OsConstants.AF_INET, OsConstants.AF_INET6};
-
- private static final int NETD_FETCH_TIMEOUT_MS = 5000; // ms
- private static final InetAddress INADDR_ANY;
-
- @VisibleForTesting static final int MAX_PORT_BIND_ATTEMPTS = 10;
-
- private final INetd mNetd;
-
- static {
- try {
- INADDR_ANY = InetAddress.getByAddress(new byte[] {0, 0, 0, 0});
- } catch (UnknownHostException e) {
- throw new RuntimeException(e);
- }
- }
-
- static final int FREE_PORT_MIN = 1024; // ports 1-1023 are reserved
- static final int PORT_MAX = 0xFFFF; // ports are an unsigned 16-bit integer
-
- /* Binder context for this service */
- private final Context mContext;
- private final Dependencies mDeps;
-
- /**
- * The next non-repeating global ID for tracking resources between users, this service, and
- * kernel data structures. Accessing this variable is not thread safe, so it is only read or
- * modified within blocks synchronized on IpSecService.this. We want to avoid -1
- * (INVALID_RESOURCE_ID) and 0 (we probably forgot to initialize it).
- */
- @GuardedBy("IpSecService.this")
- private int mNextResourceId = 1;
-
- /**
- * Dependencies of IpSecService, for injection in tests.
- */
- @VisibleForTesting
- public static class Dependencies {
- /**
- * Get a reference to INetd.
- */
- public INetd getNetdInstance(Context context) throws RemoteException {
- final INetd netd = INetd.Stub.asInterface((IBinder)
- context.getSystemService(Context.NETD_SERVICE));
- if (netd == null) {
- throw new RemoteException("Failed to Get Netd Instance");
- }
- return netd;
- }
- }
-
- final UidFdTagger mUidFdTagger;
-
- /**
- * Interface for user-reference and kernel-resource cleanup.
- *
- * <p>This interface must be implemented for a resource to be reference counted.
- */
- @VisibleForTesting
- public interface IResource {
- /**
- * Invalidates a IResource object, ensuring it is invalid for the purposes of allocating new
- * objects dependent on it.
- *
- * <p>Implementations of this method are expected to remove references to the IResource
- * object from the IpSecService's tracking arrays. The removal from the arrays ensures that
- * the resource is considered invalid for user access or allocation or use in other
- * resources.
- *
- * <p>References to the IResource object may be held by other RefcountedResource objects,
- * and as such, the underlying resources and quota may not be cleaned up.
- */
- void invalidate() throws RemoteException;
-
- /**
- * Releases underlying resources and related quotas.
- *
- * <p>Implementations of this method are expected to remove all system resources that are
- * tracked by the IResource object. Due to other RefcountedResource objects potentially
- * having references to the IResource object, freeUnderlyingResources may not always be
- * called from releaseIfUnreferencedRecursively().
- */
- void freeUnderlyingResources() throws RemoteException;
- }
-
- /**
- * RefcountedResource manages references and dependencies in an exclusively acyclic graph.
- *
- * <p>RefcountedResource implements both explicit and implicit resource management. Creating a
- * RefcountedResource object creates an explicit reference that must be freed by calling
- * userRelease(). Additionally, adding this object as a child of another RefcountedResource
- * object will add an implicit reference.
- *
- * <p>Resources are cleaned up when all references, both implicit and explicit, are released
- * (ie, when userRelease() is called and when all parents have called releaseReference() on this
- * object.)
- */
- @VisibleForTesting
- public class RefcountedResource<T extends IResource> implements IBinder.DeathRecipient {
- private final T mResource;
- private final List<RefcountedResource> mChildren;
- int mRefCount = 1; // starts at 1 for user's reference.
- IBinder mBinder;
-
- RefcountedResource(T resource, IBinder binder, RefcountedResource... children) {
- synchronized (IpSecService.this) {
- this.mResource = resource;
- this.mChildren = new ArrayList<>(children.length);
- this.mBinder = binder;
-
- for (RefcountedResource child : children) {
- mChildren.add(child);
- child.mRefCount++;
- }
-
- try {
- mBinder.linkToDeath(this, 0);
- } catch (RemoteException e) {
- binderDied();
- e.rethrowFromSystemServer();
- }
- }
- }
-
- /**
- * If the Binder object dies, this function is called to free the system resources that are
- * being tracked by this record and to subsequently release this record for garbage
- * collection
- */
- @Override
- public void binderDied() {
- synchronized (IpSecService.this) {
- try {
- userRelease();
- } catch (Exception e) {
- Log.e(TAG, "Failed to release resource: " + e);
- }
- }
- }
-
- public T getResource() {
- return mResource;
- }
-
- /**
- * Unlinks from binder and performs IpSecService resource cleanup (removes from resource
- * arrays)
- *
- * <p>If this method has been previously called, the RefcountedResource's binder field will
- * be null, and the method will return without performing the cleanup a second time.
- *
- * <p>Note that calling this function does not imply that kernel resources will be freed at
- * this time, or that the related quota will be returned. Such actions will only be
- * performed upon the reference count reaching zero.
- */
- @GuardedBy("IpSecService.this")
- public void userRelease() throws RemoteException {
- // Prevent users from putting reference counts into a bad state by calling
- // userRelease() multiple times.
- if (mBinder == null) {
- return;
- }
-
- mBinder.unlinkToDeath(this, 0);
- mBinder = null;
-
- mResource.invalidate();
-
- releaseReference();
- }
-
- /**
- * Removes a reference to this resource. If the resultant reference count is zero, the
- * underlying resources are freed, and references to all child resources are also dropped
- * recursively (resulting in them freeing their resources and children, etcetera)
- *
- * <p>This method also sets the reference count to an invalid value (-1) to signify that it
- * has been fully released. Any subsequent calls to this method will result in an
- * IllegalStateException being thrown due to resource already having been previously
- * released
- */
- @VisibleForTesting
- @GuardedBy("IpSecService.this")
- public void releaseReference() throws RemoteException {
- mRefCount--;
-
- if (mRefCount > 0) {
- return;
- } else if (mRefCount < 0) {
- throw new IllegalStateException(
- "Invalid operation - resource has already been released.");
- }
-
- // Cleanup own resources
- mResource.freeUnderlyingResources();
-
- // Cleanup child resources as needed
- for (RefcountedResource<? extends IResource> child : mChildren) {
- child.releaseReference();
- }
-
- // Enforce that resource cleanup can only be called once
- // By decrementing the refcount (from 0 to -1), the next call will throw an
- // IllegalStateException - it has already been released fully.
- mRefCount--;
- }
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("{mResource=")
- .append(mResource)
- .append(", mRefCount=")
- .append(mRefCount)
- .append(", mChildren=")
- .append(mChildren)
- .append("}")
- .toString();
- }
- }
-
- /**
- * Very simple counting class that looks much like a counting semaphore
- *
- * <p>This class is not thread-safe, and expects that that users of this class will ensure
- * synchronization and thread safety by holding the IpSecService.this instance lock.
- */
- @VisibleForTesting
- static class ResourceTracker {
- private final int mMax;
- int mCurrent;
-
- ResourceTracker(int max) {
- mMax = max;
- mCurrent = 0;
- }
-
- boolean isAvailable() {
- return (mCurrent < mMax);
- }
-
- void take() {
- if (!isAvailable()) {
- Log.wtf(TAG, "Too many resources allocated!");
- }
- mCurrent++;
- }
-
- void give() {
- if (mCurrent <= 0) {
- Log.wtf(TAG, "We've released this resource too many times");
- }
- mCurrent--;
- }
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("{mCurrent=")
- .append(mCurrent)
- .append(", mMax=")
- .append(mMax)
- .append("}")
- .toString();
- }
- }
-
- @VisibleForTesting
- static final class UserRecord {
- /* Maximum number of each type of resource that a single UID may possess */
-
- // Up to 4 active VPNs/IWLAN with potential soft handover.
- public static final int MAX_NUM_TUNNEL_INTERFACES = 8;
- public static final int MAX_NUM_ENCAP_SOCKETS = 16;
-
- // SPIs and Transforms are both cheap, and are 1:1 correlated.
- public static final int MAX_NUM_TRANSFORMS = 64;
- public static final int MAX_NUM_SPIS = 64;
-
- /**
- * Store each of the OwnedResource types in an (thinly wrapped) sparse array for indexing
- * and explicit (user) reference management.
- *
- * <p>These are stored in separate arrays to improve debuggability and dump output clarity.
- *
- * <p>Resources are removed from this array when the user releases their explicit reference
- * by calling one of the releaseResource() methods.
- */
- final RefcountedResourceArray<SpiRecord> mSpiRecords =
- new RefcountedResourceArray<>(SpiRecord.class.getSimpleName());
- final RefcountedResourceArray<TransformRecord> mTransformRecords =
- new RefcountedResourceArray<>(TransformRecord.class.getSimpleName());
- final RefcountedResourceArray<EncapSocketRecord> mEncapSocketRecords =
- new RefcountedResourceArray<>(EncapSocketRecord.class.getSimpleName());
- final RefcountedResourceArray<TunnelInterfaceRecord> mTunnelInterfaceRecords =
- new RefcountedResourceArray<>(TunnelInterfaceRecord.class.getSimpleName());
-
- /**
- * Trackers for quotas for each of the OwnedResource types.
- *
- * <p>These trackers are separate from the resource arrays, since they are incremented and
- * decremented at different points in time. Specifically, quota is only returned upon final
- * resource deallocation (after all explicit and implicit references are released). Note
- * that it is possible that calls to releaseResource() will not return the used quota if
- * there are other resources that depend on (are parents of) the resource being released.
- */
- final ResourceTracker mSpiQuotaTracker = new ResourceTracker(MAX_NUM_SPIS);
- final ResourceTracker mTransformQuotaTracker = new ResourceTracker(MAX_NUM_TRANSFORMS);
- final ResourceTracker mSocketQuotaTracker = new ResourceTracker(MAX_NUM_ENCAP_SOCKETS);
- final ResourceTracker mTunnelQuotaTracker = new ResourceTracker(MAX_NUM_TUNNEL_INTERFACES);
-
- void removeSpiRecord(int resourceId) {
- mSpiRecords.remove(resourceId);
- }
-
- void removeTransformRecord(int resourceId) {
- mTransformRecords.remove(resourceId);
- }
-
- void removeTunnelInterfaceRecord(int resourceId) {
- mTunnelInterfaceRecords.remove(resourceId);
- }
-
- void removeEncapSocketRecord(int resourceId) {
- mEncapSocketRecords.remove(resourceId);
- }
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("{mSpiQuotaTracker=")
- .append(mSpiQuotaTracker)
- .append(", mTransformQuotaTracker=")
- .append(mTransformQuotaTracker)
- .append(", mSocketQuotaTracker=")
- .append(mSocketQuotaTracker)
- .append(", mTunnelQuotaTracker=")
- .append(mTunnelQuotaTracker)
- .append(", mSpiRecords=")
- .append(mSpiRecords)
- .append(", mTransformRecords=")
- .append(mTransformRecords)
- .append(", mEncapSocketRecords=")
- .append(mEncapSocketRecords)
- .append(", mTunnelInterfaceRecords=")
- .append(mTunnelInterfaceRecords)
- .append("}")
- .toString();
- }
- }
-
- /**
- * This class is not thread-safe, and expects that that users of this class will ensure
- * synchronization and thread safety by holding the IpSecService.this instance lock.
- */
- @VisibleForTesting
- static final class UserResourceTracker {
- private final SparseArray<UserRecord> mUserRecords = new SparseArray<>();
-
- /** Lazy-initialization/getter that populates or retrieves the UserRecord as needed */
- public UserRecord getUserRecord(int uid) {
- checkCallerUid(uid);
-
- UserRecord r = mUserRecords.get(uid);
- if (r == null) {
- r = new UserRecord();
- mUserRecords.put(uid, r);
- }
- return r;
- }
-
- /** Safety method; guards against access of other user's UserRecords */
- private void checkCallerUid(int uid) {
- if (uid != Binder.getCallingUid() && Process.SYSTEM_UID != Binder.getCallingUid()) {
- throw new SecurityException("Attempted access of unowned resources");
- }
- }
-
- @Override
- public String toString() {
- return mUserRecords.toString();
- }
- }
-
- @VisibleForTesting final UserResourceTracker mUserResourceTracker = new UserResourceTracker();
-
- /**
- * The OwnedResourceRecord class provides a facility to cleanly and reliably track system
- * resources. It relies on a provided resourceId that should uniquely identify the kernel
- * resource. To use this class, the user should implement the invalidate() and
- * freeUnderlyingResources() methods that are responsible for cleaning up IpSecService resource
- * tracking arrays and kernel resources, respectively.
- *
- * <p>This class associates kernel resources with the UID that owns and controls them.
- */
- private abstract class OwnedResourceRecord implements IResource {
- final int mPid;
- final int mUid;
- protected final int mResourceId;
-
- OwnedResourceRecord(int resourceId) {
- super();
- if (resourceId == INVALID_RESOURCE_ID) {
- throw new IllegalArgumentException("Resource ID must not be INVALID_RESOURCE_ID");
- }
- mResourceId = resourceId;
- mPid = Binder.getCallingPid();
- mUid = Binder.getCallingUid();
-
- getResourceTracker().take();
- }
-
- @Override
- public abstract void invalidate() throws RemoteException;
-
- /** Convenience method; retrieves the user resource record for the stored UID. */
- protected UserRecord getUserRecord() {
- return mUserResourceTracker.getUserRecord(mUid);
- }
-
- @Override
- public abstract void freeUnderlyingResources() throws RemoteException;
-
- /** Get the resource tracker for this resource */
- protected abstract ResourceTracker getResourceTracker();
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("{mResourceId=")
- .append(mResourceId)
- .append(", pid=")
- .append(mPid)
- .append(", uid=")
- .append(mUid)
- .append("}")
- .toString();
- }
- };
-
- /**
- * Thin wrapper over SparseArray to ensure resources exist, and simplify generic typing.
- *
- * <p>RefcountedResourceArray prevents null insertions, and throws an IllegalArgumentException
- * if a key is not found during a retrieval process.
- */
- static class RefcountedResourceArray<T extends IResource> {
- SparseArray<RefcountedResource<T>> mArray = new SparseArray<>();
- private final String mTypeName;
-
- RefcountedResourceArray(String typeName) {
- this.mTypeName = typeName;
- }
-
- /**
- * Accessor method to get inner resource object.
- *
- * @throws IllegalArgumentException if no resource with provided key is found.
- */
- T getResourceOrThrow(int key) {
- return getRefcountedResourceOrThrow(key).getResource();
- }
-
- /**
- * Accessor method to get reference counting wrapper.
- *
- * @throws IllegalArgumentException if no resource with provided key is found.
- */
- RefcountedResource<T> getRefcountedResourceOrThrow(int key) {
- RefcountedResource<T> resource = mArray.get(key);
- if (resource == null) {
- throw new IllegalArgumentException(
- String.format("No such %s found for given id: %d", mTypeName, key));
- }
-
- return resource;
- }
-
- void put(int key, RefcountedResource<T> obj) {
- Objects.requireNonNull(obj, "Null resources cannot be added");
- mArray.put(key, obj);
- }
-
- void remove(int key) {
- mArray.remove(key);
- }
-
- @Override
- public String toString() {
- return mArray.toString();
- }
- }
-
- /**
- * Tracks an SA in the kernel, and manages cleanup paths. Once a TransformRecord is
- * created, the SpiRecord that originally tracked the SAs will reliquish the
- * responsibility of freeing the underlying SA to this class via the mOwnedByTransform flag.
- */
- private final class TransformRecord extends OwnedResourceRecord {
- private final IpSecConfig mConfig;
- private final SpiRecord mSpi;
- private final EncapSocketRecord mSocket;
-
- TransformRecord(
- int resourceId, IpSecConfig config, SpiRecord spi, EncapSocketRecord socket) {
- super(resourceId);
- mConfig = config;
- mSpi = spi;
- mSocket = socket;
-
- spi.setOwnedByTransform();
- }
-
- public IpSecConfig getConfig() {
- return mConfig;
- }
-
- public SpiRecord getSpiRecord() {
- return mSpi;
- }
-
- public EncapSocketRecord getSocketRecord() {
- return mSocket;
- }
-
- /** always guarded by IpSecService#this */
- @Override
- public void freeUnderlyingResources() {
- int spi = mSpi.getSpi();
- try {
- mNetd.ipSecDeleteSecurityAssociation(
- mUid,
- mConfig.getSourceAddress(),
- mConfig.getDestinationAddress(),
- spi,
- mConfig.getMarkValue(),
- mConfig.getMarkMask(),
- mConfig.getXfrmInterfaceId());
- } catch (RemoteException | ServiceSpecificException e) {
- Log.e(TAG, "Failed to delete SA with ID: " + mResourceId, e);
- }
-
- getResourceTracker().give();
- }
-
- @Override
- public void invalidate() throws RemoteException {
- getUserRecord().removeTransformRecord(mResourceId);
- }
-
- @Override
- protected ResourceTracker getResourceTracker() {
- return getUserRecord().mTransformQuotaTracker;
- }
-
- @Override
- public String toString() {
- StringBuilder strBuilder = new StringBuilder();
- strBuilder
- .append("{super=")
- .append(super.toString())
- .append(", mSocket=")
- .append(mSocket)
- .append(", mSpi.mResourceId=")
- .append(mSpi.mResourceId)
- .append(", mConfig=")
- .append(mConfig)
- .append("}");
- return strBuilder.toString();
- }
- }
-
- /**
- * Tracks a single SA in the kernel, and manages cleanup paths. Once used in a Transform, the
- * responsibility for cleaning up underlying resources will be passed to the TransformRecord
- * object
- */
- private final class SpiRecord extends OwnedResourceRecord {
- private final String mSourceAddress;
- private final String mDestinationAddress;
- private int mSpi;
-
- private boolean mOwnedByTransform = false;
-
- SpiRecord(int resourceId, String sourceAddress,
- String destinationAddress, int spi) {
- super(resourceId);
- mSourceAddress = sourceAddress;
- mDestinationAddress = destinationAddress;
- mSpi = spi;
- }
-
- /** always guarded by IpSecService#this */
- @Override
- public void freeUnderlyingResources() {
- try {
- if (!mOwnedByTransform) {
- mNetd.ipSecDeleteSecurityAssociation(
- mUid, mSourceAddress, mDestinationAddress, mSpi, 0 /* mark */,
- 0 /* mask */, 0 /* if_id */);
- }
- } catch (ServiceSpecificException | RemoteException e) {
- Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId, e);
- }
-
- mSpi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
-
- getResourceTracker().give();
- }
-
- public int getSpi() {
- return mSpi;
- }
-
- public String getDestinationAddress() {
- return mDestinationAddress;
- }
-
- public void setOwnedByTransform() {
- if (mOwnedByTransform) {
- // Programming error
- throw new IllegalStateException("Cannot own an SPI twice!");
- }
-
- mOwnedByTransform = true;
- }
-
- public boolean getOwnedByTransform() {
- return mOwnedByTransform;
- }
-
- @Override
- public void invalidate() throws RemoteException {
- getUserRecord().removeSpiRecord(mResourceId);
- }
-
- @Override
- protected ResourceTracker getResourceTracker() {
- return getUserRecord().mSpiQuotaTracker;
- }
-
- @Override
- public String toString() {
- StringBuilder strBuilder = new StringBuilder();
- strBuilder
- .append("{super=")
- .append(super.toString())
- .append(", mSpi=")
- .append(mSpi)
- .append(", mSourceAddress=")
- .append(mSourceAddress)
- .append(", mDestinationAddress=")
- .append(mDestinationAddress)
- .append(", mOwnedByTransform=")
- .append(mOwnedByTransform)
- .append("}");
- return strBuilder.toString();
- }
- }
-
- private final SparseBooleanArray mTunnelNetIds = new SparseBooleanArray();
- final Range<Integer> mNetIdRange = ConnectivityManager.getIpSecNetIdRange();
- private int mNextTunnelNetId = mNetIdRange.getLower();
-
- /**
- * Reserves a netId within the range of netIds allocated for IPsec tunnel interfaces
- *
- * <p>This method should only be called from Binder threads. Do not call this from within the
- * system server as it will crash the system on failure.
- *
- * @return an integer key within the netId range, if successful
- * @throws IllegalStateException if unsuccessful (all netId are currently reserved)
- */
- @VisibleForTesting
- int reserveNetId() {
- final int range = mNetIdRange.getUpper() - mNetIdRange.getLower() + 1;
- synchronized (mTunnelNetIds) {
- for (int i = 0; i < range; i++) {
- final int netId = mNextTunnelNetId;
- if (++mNextTunnelNetId > mNetIdRange.getUpper()) {
- mNextTunnelNetId = mNetIdRange.getLower();
- }
- if (!mTunnelNetIds.get(netId)) {
- mTunnelNetIds.put(netId, true);
- return netId;
- }
- }
- }
- throw new IllegalStateException("No free netIds to allocate");
- }
-
- @VisibleForTesting
- void releaseNetId(int netId) {
- synchronized (mTunnelNetIds) {
- mTunnelNetIds.delete(netId);
- }
- }
-
- /**
- * Tracks an tunnel interface, and manages cleanup paths.
- *
- * <p>This class is not thread-safe, and expects that that users of this class will ensure
- * synchronization and thread safety by holding the IpSecService.this instance lock
- */
- @VisibleForTesting
- final class TunnelInterfaceRecord extends OwnedResourceRecord {
- private final String mInterfaceName;
-
- // outer addresses
- private final String mLocalAddress;
- private final String mRemoteAddress;
-
- private final int mIkey;
- private final int mOkey;
-
- private final int mIfId;
-
- private Network mUnderlyingNetwork;
-
- TunnelInterfaceRecord(
- int resourceId,
- String interfaceName,
- Network underlyingNetwork,
- String localAddr,
- String remoteAddr,
- int ikey,
- int okey,
- int intfId) {
- super(resourceId);
-
- mInterfaceName = interfaceName;
- mUnderlyingNetwork = underlyingNetwork;
- mLocalAddress = localAddr;
- mRemoteAddress = remoteAddr;
- mIkey = ikey;
- mOkey = okey;
- mIfId = intfId;
- }
-
- /** always guarded by IpSecService#this */
- @Override
- public void freeUnderlyingResources() {
- // Calls to netd
- // Teardown VTI
- // Delete global policies
- try {
- mNetd.ipSecRemoveTunnelInterface(mInterfaceName);
-
- for (int selAddrFamily : ADDRESS_FAMILIES) {
- mNetd.ipSecDeleteSecurityPolicy(
- mUid,
- selAddrFamily,
- IpSecManager.DIRECTION_OUT,
- mOkey,
- 0xffffffff,
- mIfId);
- mNetd.ipSecDeleteSecurityPolicy(
- mUid,
- selAddrFamily,
- IpSecManager.DIRECTION_IN,
- mIkey,
- 0xffffffff,
- mIfId);
- }
- } catch (ServiceSpecificException | RemoteException e) {
- Log.e(
- TAG,
- "Failed to delete VTI with interface name: "
- + mInterfaceName
- + " and id: "
- + mResourceId, e);
- }
-
- getResourceTracker().give();
- releaseNetId(mIkey);
- releaseNetId(mOkey);
- }
-
- @GuardedBy("IpSecService.this")
- public void setUnderlyingNetwork(Network underlyingNetwork) {
- // When #applyTunnelModeTransform is called, this new underlying network will be used to
- // update the output mark of the input transform.
- mUnderlyingNetwork = underlyingNetwork;
- }
-
- @GuardedBy("IpSecService.this")
- public Network getUnderlyingNetwork() {
- return mUnderlyingNetwork;
- }
-
- public String getInterfaceName() {
- return mInterfaceName;
- }
-
- /** Returns the local, outer address for the tunnelInterface */
- public String getLocalAddress() {
- return mLocalAddress;
- }
-
- /** Returns the remote, outer address for the tunnelInterface */
- public String getRemoteAddress() {
- return mRemoteAddress;
- }
-
- public int getIkey() {
- return mIkey;
- }
-
- public int getOkey() {
- return mOkey;
- }
-
- public int getIfId() {
- return mIfId;
- }
-
- @Override
- protected ResourceTracker getResourceTracker() {
- return getUserRecord().mTunnelQuotaTracker;
- }
-
- @Override
- public void invalidate() {
- getUserRecord().removeTunnelInterfaceRecord(mResourceId);
- }
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("{super=")
- .append(super.toString())
- .append(", mInterfaceName=")
- .append(mInterfaceName)
- .append(", mUnderlyingNetwork=")
- .append(mUnderlyingNetwork)
- .append(", mLocalAddress=")
- .append(mLocalAddress)
- .append(", mRemoteAddress=")
- .append(mRemoteAddress)
- .append(", mIkey=")
- .append(mIkey)
- .append(", mOkey=")
- .append(mOkey)
- .append("}")
- .toString();
- }
- }
-
- /**
- * Tracks a UDP encap socket, and manages cleanup paths
- *
- * <p>While this class does not manage non-kernel resources, race conditions around socket
- * binding require that the service creates the encap socket, binds it and applies the socket
- * policy before handing it to a user.
- */
- private final class EncapSocketRecord extends OwnedResourceRecord {
- private FileDescriptor mSocket;
- private final int mPort;
-
- EncapSocketRecord(int resourceId, FileDescriptor socket, int port) {
- super(resourceId);
- mSocket = socket;
- mPort = port;
- }
-
- /** always guarded by IpSecService#this */
- @Override
- public void freeUnderlyingResources() {
- Log.d(TAG, "Closing port " + mPort);
- IoUtils.closeQuietly(mSocket);
- mSocket = null;
-
- getResourceTracker().give();
- }
-
- public int getPort() {
- return mPort;
- }
-
- public FileDescriptor getFileDescriptor() {
- return mSocket;
- }
-
- @Override
- protected ResourceTracker getResourceTracker() {
- return getUserRecord().mSocketQuotaTracker;
- }
-
- @Override
- public void invalidate() {
- getUserRecord().removeEncapSocketRecord(mResourceId);
- }
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("{super=")
- .append(super.toString())
- .append(", mSocket=")
- .append(mSocket)
- .append(", mPort=")
- .append(mPort)
- .append("}")
- .toString();
- }
- }
-
- /**
- * Constructs a new IpSecService instance
- *
- * @param context Binder context for this service
- */
- public IpSecService(Context context) {
- this(context, new Dependencies());
- }
-
- @NonNull
- private AppOpsManager getAppOpsManager() {
- AppOpsManager appOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
- if (appOps == null) throw new RuntimeException("System Server couldn't get AppOps");
- return appOps;
- }
-
- /** @hide */
- @VisibleForTesting
- public IpSecService(Context context, Dependencies deps) {
- this(
- context,
- deps,
- (fd, uid) -> {
- try {
- TrafficStats.setThreadStatsUid(uid);
- TrafficStats.tagFileDescriptor(fd);
- } finally {
- TrafficStats.clearThreadStatsUid();
- }
- });
- }
-
- /** @hide */
- @VisibleForTesting
- public IpSecService(Context context, Dependencies deps, UidFdTagger uidFdTagger) {
- mContext = context;
- mDeps = Objects.requireNonNull(deps, "Missing dependencies.");
- mUidFdTagger = uidFdTagger;
- try {
- mNetd = mDeps.getNetdInstance(mContext);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Checks that the provided InetAddress is valid for use in an IPsec SA. The address must not be
- * a wildcard address and must be in a numeric form such as 1.2.3.4 or 2001::1.
- */
- private static void checkInetAddress(String inetAddress) {
- if (TextUtils.isEmpty(inetAddress)) {
- throw new IllegalArgumentException("Unspecified address");
- }
-
- InetAddress checkAddr = InetAddresses.parseNumericAddress(inetAddress);
-
- if (checkAddr.isAnyLocalAddress()) {
- throw new IllegalArgumentException("Inappropriate wildcard address: " + inetAddress);
- }
- }
-
- /**
- * Checks the user-provided direction field and throws an IllegalArgumentException if it is not
- * DIRECTION_IN or DIRECTION_OUT
- */
- private void checkDirection(int direction) {
- switch (direction) {
- case IpSecManager.DIRECTION_OUT:
- case IpSecManager.DIRECTION_IN:
- return;
- case IpSecManager.DIRECTION_FWD:
- // Only NETWORK_STACK or MAINLINE_NETWORK_STACK allowed to use forward policies
- PermissionUtils.enforceNetworkStackPermission(mContext);
- return;
- }
- throw new IllegalArgumentException("Invalid Direction: " + direction);
- }
-
- /** Get a new SPI and maintain the reservation in the system server */
- @Override
- public synchronized IpSecSpiResponse allocateSecurityParameterIndex(
- String destinationAddress, int requestedSpi, IBinder binder) throws RemoteException {
- checkInetAddress(destinationAddress);
- // RFC 4303 Section 2.1 - 0=local, 1-255=reserved.
- if (requestedSpi > 0 && requestedSpi < 256) {
- throw new IllegalArgumentException("ESP SPI must not be in the range of 0-255.");
- }
- Objects.requireNonNull(binder, "Null Binder passed to allocateSecurityParameterIndex");
-
- int callingUid = Binder.getCallingUid();
- UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
- final int resourceId = mNextResourceId++;
-
- int spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
- try {
- if (!userRecord.mSpiQuotaTracker.isAvailable()) {
- return new IpSecSpiResponse(
- IpSecManager.Status.RESOURCE_UNAVAILABLE, INVALID_RESOURCE_ID, spi);
- }
-
- spi = mNetd.ipSecAllocateSpi(callingUid, "", destinationAddress, requestedSpi);
- Log.d(TAG, "Allocated SPI " + spi);
- userRecord.mSpiRecords.put(
- resourceId,
- new RefcountedResource<SpiRecord>(
- new SpiRecord(resourceId, "",
- destinationAddress, spi), binder));
- } catch (ServiceSpecificException e) {
- if (e.errorCode == OsConstants.ENOENT) {
- return new IpSecSpiResponse(
- IpSecManager.Status.SPI_UNAVAILABLE, INVALID_RESOURCE_ID, spi);
- }
- throw e;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- return new IpSecSpiResponse(IpSecManager.Status.OK, resourceId, spi);
- }
-
- /* This method should only be called from Binder threads. Do not call this from
- * within the system server as it will crash the system on failure.
- */
- private void releaseResource(RefcountedResourceArray resArray, int resourceId)
- throws RemoteException {
- resArray.getRefcountedResourceOrThrow(resourceId).userRelease();
- }
-
- /** Release a previously allocated SPI that has been registered with the system server */
- @Override
- public synchronized void releaseSecurityParameterIndex(int resourceId) throws RemoteException {
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
- releaseResource(userRecord.mSpiRecords, resourceId);
- }
-
- /**
- * This function finds and forcibly binds to a random system port, ensuring that the port cannot
- * be unbound.
- *
- * <p>A socket cannot be un-bound from a port if it was bound to that port by number. To select
- * a random open port and then bind by number, this function creates a temp socket, binds to a
- * random port (specifying 0), gets that port number, and then uses is to bind the user's UDP
- * Encapsulation Socket forcibly, so that it cannot be un-bound by the user with the returned
- * FileHandle.
- *
- * <p>The loop in this function handles the inherent race window between un-binding to a port
- * and re-binding, during which the system could *technically* hand that port out to someone
- * else.
- */
- private int bindToRandomPort(FileDescriptor sockFd) throws IOException {
- for (int i = MAX_PORT_BIND_ATTEMPTS; i > 0; i--) {
- try {
- FileDescriptor probeSocket = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- Os.bind(probeSocket, INADDR_ANY, 0);
- int port = ((InetSocketAddress) Os.getsockname(probeSocket)).getPort();
- Os.close(probeSocket);
- Log.v(TAG, "Binding to port " + port);
- Os.bind(sockFd, INADDR_ANY, port);
- return port;
- } catch (ErrnoException e) {
- // Someone miraculously claimed the port just after we closed probeSocket.
- if (e.errno == OsConstants.EADDRINUSE) {
- continue;
- }
- throw e.rethrowAsIOException();
- }
- }
- throw new IOException("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port");
- }
-
- /**
- * Functional interface to do traffic tagging of given sockets to UIDs.
- *
- * <p>Specifically used by openUdpEncapsulationSocket to ensure data usage on the UDP encap
- * sockets are billed to the UID that the UDP encap socket was created on behalf of.
- *
- * <p>Separate class so that the socket tagging logic can be mocked; TrafficStats uses static
- * methods that cannot be easily mocked/tested.
- */
- @VisibleForTesting
- public interface UidFdTagger {
- /**
- * Sets socket tag to assign all traffic to the provided UID.
- *
- * <p>Since the socket is created on behalf of an unprivileged application, all traffic
- * should be accounted to the UID of the unprivileged application.
- */
- void tag(FileDescriptor fd, int uid) throws IOException;
- }
-
- /**
- * Open a socket via the system server and bind it to the specified port (random if port=0).
- * This will return a PFD to the user that represent a bound UDP socket. The system server will
- * cache the socket and a record of its owner so that it can and must be freed when no longer
- * needed.
- */
- @Override
- public synchronized IpSecUdpEncapResponse openUdpEncapsulationSocket(int port, IBinder binder)
- throws RemoteException {
- if (port != 0 && (port < FREE_PORT_MIN || port > PORT_MAX)) {
- throw new IllegalArgumentException(
- "Specified port number must be a valid non-reserved UDP port");
- }
- Objects.requireNonNull(binder, "Null Binder passed to openUdpEncapsulationSocket");
-
- int callingUid = Binder.getCallingUid();
- UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
- final int resourceId = mNextResourceId++;
-
- ParcelFileDescriptor pFd = null;
- try {
- if (!userRecord.mSocketQuotaTracker.isAvailable()) {
- return new IpSecUdpEncapResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
- }
-
- FileDescriptor sockFd = null;
- try {
- sockFd = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- pFd = ParcelFileDescriptor.dup(sockFd);
- } finally {
- IoUtils.closeQuietly(sockFd);
- }
-
- mUidFdTagger.tag(pFd.getFileDescriptor(), callingUid);
- // This code is common to both the unspecified and specified port cases
- Os.setsockoptInt(
- pFd.getFileDescriptor(),
- OsConstants.IPPROTO_UDP,
- OsConstants.UDP_ENCAP,
- OsConstants.UDP_ENCAP_ESPINUDP);
-
- mNetd.ipSecSetEncapSocketOwner(pFd, callingUid);
- if (port != 0) {
- Log.v(TAG, "Binding to port " + port);
- Os.bind(pFd.getFileDescriptor(), INADDR_ANY, port);
- } else {
- port = bindToRandomPort(pFd.getFileDescriptor());
- }
-
- userRecord.mEncapSocketRecords.put(
- resourceId,
- new RefcountedResource<EncapSocketRecord>(
- new EncapSocketRecord(resourceId, pFd.getFileDescriptor(), port),
- binder));
- return new IpSecUdpEncapResponse(IpSecManager.Status.OK, resourceId, port,
- pFd.getFileDescriptor());
- } catch (IOException | ErrnoException e) {
- try {
- if (pFd != null) {
- pFd.close();
- }
- } catch (IOException ex) {
- // Nothing can be done at this point
- Log.e(TAG, "Failed to close pFd.");
- }
- }
- // If we make it to here, then something has gone wrong and we couldn't open a socket.
- // The only reasonable condition that would cause that is resource unavailable.
- return new IpSecUdpEncapResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
- }
-
- /** close a socket that has been been allocated by and registered with the system server */
- @Override
- public synchronized void closeUdpEncapsulationSocket(int resourceId) throws RemoteException {
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
- releaseResource(userRecord.mEncapSocketRecords, resourceId);
- }
-
- /**
- * Create a tunnel interface for use in IPSec tunnel mode. The system server will cache the
- * tunnel interface and a record of its owner so that it can and must be freed when no longer
- * needed.
- */
- @Override
- public synchronized IpSecTunnelInterfaceResponse createTunnelInterface(
- String localAddr, String remoteAddr, Network underlyingNetwork, IBinder binder,
- String callingPackage) {
- enforceTunnelFeatureAndPermissions(callingPackage);
- Objects.requireNonNull(binder, "Null Binder passed to createTunnelInterface");
- Objects.requireNonNull(underlyingNetwork, "No underlying network was specified");
- checkInetAddress(localAddr);
- checkInetAddress(remoteAddr);
-
- // TODO: Check that underlying network exists, and IP addresses not assigned to a different
- // network (b/72316676).
-
- int callerUid = Binder.getCallingUid();
- UserRecord userRecord = mUserResourceTracker.getUserRecord(callerUid);
- if (!userRecord.mTunnelQuotaTracker.isAvailable()) {
- return new IpSecTunnelInterfaceResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
- }
-
- final int resourceId = mNextResourceId++;
- final int ikey = reserveNetId();
- final int okey = reserveNetId();
- String intfName = String.format("%s%d", INetd.IPSEC_INTERFACE_PREFIX, resourceId);
-
- try {
- // Calls to netd:
- // Create VTI
- // Add inbound/outbound global policies
- // (use reqid = 0)
- mNetd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId);
-
- BinderUtils.withCleanCallingIdentity(() -> {
- NetdUtils.setInterfaceUp(mNetd, intfName);
- });
-
- for (int selAddrFamily : ADDRESS_FAMILIES) {
- // Always send down correct local/remote addresses for template.
- mNetd.ipSecAddSecurityPolicy(
- callerUid,
- selAddrFamily,
- IpSecManager.DIRECTION_OUT,
- localAddr,
- remoteAddr,
- 0,
- okey,
- 0xffffffff,
- resourceId);
- mNetd.ipSecAddSecurityPolicy(
- callerUid,
- selAddrFamily,
- IpSecManager.DIRECTION_IN,
- remoteAddr,
- localAddr,
- 0,
- ikey,
- 0xffffffff,
- resourceId);
-
- // Add a forwarding policy on the tunnel interface. In order to support forwarding
- // the IpSecTunnelInterface must have a forwarding policy matching the incoming SA.
- //
- // Unless a IpSecTransform is also applied against this interface in DIRECTION_FWD,
- // forwarding will be blocked by default (as would be the case if this policy was
- // absent).
- //
- // This is necessary only on the tunnel interface, and not any the interface to
- // which traffic will be forwarded to.
- mNetd.ipSecAddSecurityPolicy(
- callerUid,
- selAddrFamily,
- IpSecManager.DIRECTION_FWD,
- remoteAddr,
- localAddr,
- 0,
- ikey,
- 0xffffffff,
- resourceId);
- }
-
- userRecord.mTunnelInterfaceRecords.put(
- resourceId,
- new RefcountedResource<TunnelInterfaceRecord>(
- new TunnelInterfaceRecord(
- resourceId,
- intfName,
- underlyingNetwork,
- localAddr,
- remoteAddr,
- ikey,
- okey,
- resourceId),
- binder));
- return new IpSecTunnelInterfaceResponse(IpSecManager.Status.OK, resourceId, intfName);
- } catch (RemoteException e) {
- // Release keys if we got an error.
- releaseNetId(ikey);
- releaseNetId(okey);
- throw e.rethrowFromSystemServer();
- } catch (Throwable t) {
- // Release keys if we got an error.
- releaseNetId(ikey);
- releaseNetId(okey);
- throw t;
- }
- }
-
- /**
- * Adds a new local address to the tunnel interface. This allows packets to be sent and received
- * from multiple local IP addresses over the same tunnel.
- */
- @Override
- public synchronized void addAddressToTunnelInterface(
- int tunnelResourceId, LinkAddress localAddr, String callingPackage) {
- enforceTunnelFeatureAndPermissions(callingPackage);
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
-
- // Get tunnelInterface record; if no such interface is found, will throw
- // IllegalArgumentException
- TunnelInterfaceRecord tunnelInterfaceInfo =
- userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
-
- try {
- // We can assume general validity of the IP address, since we get them as a
- // LinkAddress, which does some validation.
- mNetd.interfaceAddAddress(
- tunnelInterfaceInfo.mInterfaceName,
- localAddr.getAddress().getHostAddress(),
- localAddr.getPrefixLength());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Remove a new local address from the tunnel interface. After removal, the address will no
- * longer be available to send from, or receive on.
- */
- @Override
- public synchronized void removeAddressFromTunnelInterface(
- int tunnelResourceId, LinkAddress localAddr, String callingPackage) {
- enforceTunnelFeatureAndPermissions(callingPackage);
-
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
- // Get tunnelInterface record; if no such interface is found, will throw
- // IllegalArgumentException
- TunnelInterfaceRecord tunnelInterfaceInfo =
- userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
-
- try {
- // We can assume general validity of the IP address, since we get them as a
- // LinkAddress, which does some validation.
- mNetd.interfaceDelAddress(
- tunnelInterfaceInfo.mInterfaceName,
- localAddr.getAddress().getHostAddress(),
- localAddr.getPrefixLength());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** Set TunnelInterface to use a specific underlying network. */
- @Override
- public synchronized void setNetworkForTunnelInterface(
- int tunnelResourceId, Network underlyingNetwork, String callingPackage) {
- enforceTunnelFeatureAndPermissions(callingPackage);
- Objects.requireNonNull(underlyingNetwork, "No underlying network was specified");
-
- final UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
-
- // Get tunnelInterface record; if no such interface is found, will throw
- // IllegalArgumentException. userRecord.mTunnelInterfaceRecords is never null
- final TunnelInterfaceRecord tunnelInterfaceInfo =
- userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
-
- final ConnectivityManager connectivityManager =
- mContext.getSystemService(ConnectivityManager.class);
- final LinkProperties lp = connectivityManager.getLinkProperties(underlyingNetwork);
- if (tunnelInterfaceInfo.getInterfaceName().equals(lp.getInterfaceName())) {
- throw new IllegalArgumentException(
- "Underlying network cannot be the network being exposed by this tunnel");
- }
-
- // It is meaningless to check if the network exists or is valid because the network might
- // disconnect at any time after it passes the check.
-
- tunnelInterfaceInfo.setUnderlyingNetwork(underlyingNetwork);
- }
-
- /**
- * Delete a TunnelInterface that has been been allocated by and registered with the system
- * server
- */
- @Override
- public synchronized void deleteTunnelInterface(
- int resourceId, String callingPackage) throws RemoteException {
- enforceTunnelFeatureAndPermissions(callingPackage);
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
- releaseResource(userRecord.mTunnelInterfaceRecords, resourceId);
- }
-
- @VisibleForTesting
- void validateAlgorithms(IpSecConfig config) throws IllegalArgumentException {
- IpSecAlgorithm auth = config.getAuthentication();
- IpSecAlgorithm crypt = config.getEncryption();
- IpSecAlgorithm aead = config.getAuthenticatedEncryption();
-
- // Validate the algorithm set
- Preconditions.checkArgument(
- aead != null || crypt != null || auth != null,
- "No Encryption or Authentication algorithms specified");
- Preconditions.checkArgument(
- auth == null || auth.isAuthentication(),
- "Unsupported algorithm for Authentication");
- Preconditions.checkArgument(
- crypt == null || crypt.isEncryption(), "Unsupported algorithm for Encryption");
- Preconditions.checkArgument(
- aead == null || aead.isAead(),
- "Unsupported algorithm for Authenticated Encryption");
- Preconditions.checkArgument(
- aead == null || (auth == null && crypt == null),
- "Authenticated Encryption is mutually exclusive with other Authentication "
- + "or Encryption algorithms");
- }
-
- private int getFamily(String inetAddress) {
- int family = AF_UNSPEC;
- InetAddress checkAddress = InetAddresses.parseNumericAddress(inetAddress);
- if (checkAddress instanceof Inet4Address) {
- family = AF_INET;
- } else if (checkAddress instanceof Inet6Address) {
- family = AF_INET6;
- }
- return family;
- }
-
- /**
- * Checks an IpSecConfig parcel to ensure that the contents are valid and throws an
- * IllegalArgumentException if they are not.
- */
- private void checkIpSecConfig(IpSecConfig config) {
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
-
- switch (config.getEncapType()) {
- case IpSecTransform.ENCAP_NONE:
- break;
- case IpSecTransform.ENCAP_ESPINUDP:
- case IpSecTransform.ENCAP_ESPINUDP_NON_IKE:
- // Retrieve encap socket record; will throw IllegalArgumentException if not found
- userRecord.mEncapSocketRecords.getResourceOrThrow(
- config.getEncapSocketResourceId());
-
- int port = config.getEncapRemotePort();
- if (port <= 0 || port > 0xFFFF) {
- throw new IllegalArgumentException("Invalid remote UDP port: " + port);
- }
- break;
- default:
- throw new IllegalArgumentException("Invalid Encap Type: " + config.getEncapType());
- }
-
- validateAlgorithms(config);
-
- // Retrieve SPI record; will throw IllegalArgumentException if not found
- SpiRecord s = userRecord.mSpiRecords.getResourceOrThrow(config.getSpiResourceId());
-
- // Check to ensure that SPI has not already been used.
- if (s.getOwnedByTransform()) {
- throw new IllegalStateException("SPI already in use; cannot be used in new Transforms");
- }
-
- // If no remote address is supplied, then use one from the SPI.
- if (TextUtils.isEmpty(config.getDestinationAddress())) {
- config.setDestinationAddress(s.getDestinationAddress());
- }
-
- // All remote addresses must match
- if (!config.getDestinationAddress().equals(s.getDestinationAddress())) {
- throw new IllegalArgumentException("Mismatched remote addresseses.");
- }
-
- // This check is technically redundant due to the chain of custody between the SPI and
- // the IpSecConfig, but in the future if the dest is allowed to be set explicitly in
- // the transform, this will prevent us from messing up.
- checkInetAddress(config.getDestinationAddress());
-
- // Require a valid source address for all transforms.
- checkInetAddress(config.getSourceAddress());
-
- // Check to ensure source and destination have the same address family.
- String sourceAddress = config.getSourceAddress();
- String destinationAddress = config.getDestinationAddress();
- int sourceFamily = getFamily(sourceAddress);
- int destinationFamily = getFamily(destinationAddress);
- if (sourceFamily != destinationFamily) {
- throw new IllegalArgumentException(
- "Source address ("
- + sourceAddress
- + ") and destination address ("
- + destinationAddress
- + ") have different address families.");
- }
-
- // Throw an error if UDP Encapsulation is not used in IPv4.
- if (config.getEncapType() != IpSecTransform.ENCAP_NONE && sourceFamily != AF_INET) {
- throw new IllegalArgumentException(
- "UDP Encapsulation is not supported for this address family");
- }
-
- switch (config.getMode()) {
- case IpSecTransform.MODE_TRANSPORT:
- break;
- case IpSecTransform.MODE_TUNNEL:
- break;
- default:
- throw new IllegalArgumentException(
- "Invalid IpSecTransform.mode: " + config.getMode());
- }
-
- config.setMarkValue(0);
- config.setMarkMask(0);
- }
-
- private static final String TUNNEL_OP = AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS;
-
- private void enforceTunnelFeatureAndPermissions(String callingPackage) {
- if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)) {
- throw new UnsupportedOperationException(
- "IPsec Tunnel Mode requires PackageManager.FEATURE_IPSEC_TUNNELS");
- }
-
- Objects.requireNonNull(callingPackage, "Null calling package cannot create IpSec tunnels");
-
- // OP_MANAGE_IPSEC_TUNNELS will return MODE_ERRORED by default, including for the system
- // server. If the appop is not granted, require that the caller has the MANAGE_IPSEC_TUNNELS
- // permission or is the System Server.
- if (AppOpsManager.MODE_ALLOWED == getAppOpsManager().noteOpNoThrow(
- TUNNEL_OP, Binder.getCallingUid(), callingPackage)) {
- return;
- }
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService");
- }
-
- private void createOrUpdateTransform(
- IpSecConfig c, int resourceId, SpiRecord spiRecord, EncapSocketRecord socketRecord)
- throws RemoteException {
-
- int encapType = c.getEncapType(), encapLocalPort = 0, encapRemotePort = 0;
- if (encapType != IpSecTransform.ENCAP_NONE) {
- encapLocalPort = socketRecord.getPort();
- encapRemotePort = c.getEncapRemotePort();
- }
-
- IpSecAlgorithm auth = c.getAuthentication();
- IpSecAlgorithm crypt = c.getEncryption();
- IpSecAlgorithm authCrypt = c.getAuthenticatedEncryption();
-
- String cryptName;
- if (crypt == null) {
- cryptName = (authCrypt == null) ? IpSecAlgorithm.CRYPT_NULL : "";
- } else {
- cryptName = crypt.getName();
- }
-
- mNetd.ipSecAddSecurityAssociation(
- Binder.getCallingUid(),
- c.getMode(),
- c.getSourceAddress(),
- c.getDestinationAddress(),
- (c.getNetwork() != null) ? c.getNetwork().getNetId() : 0,
- spiRecord.getSpi(),
- c.getMarkValue(),
- c.getMarkMask(),
- (auth != null) ? auth.getName() : "",
- (auth != null) ? auth.getKey() : new byte[] {},
- (auth != null) ? auth.getTruncationLengthBits() : 0,
- cryptName,
- (crypt != null) ? crypt.getKey() : new byte[] {},
- (crypt != null) ? crypt.getTruncationLengthBits() : 0,
- (authCrypt != null) ? authCrypt.getName() : "",
- (authCrypt != null) ? authCrypt.getKey() : new byte[] {},
- (authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0,
- encapType,
- encapLocalPort,
- encapRemotePort,
- c.getXfrmInterfaceId());
- }
-
- /**
- * Create a IPsec transform, which represents a single security association in the kernel. The
- * transform will be cached by the system server and must be freed when no longer needed. It is
- * possible to free one, deleting the SA from underneath sockets that are using it, which will
- * result in all of those sockets becoming unable to send or receive data.
- */
- @Override
- public synchronized IpSecTransformResponse createTransform(
- IpSecConfig c, IBinder binder, String callingPackage) throws RemoteException {
- Objects.requireNonNull(c);
- if (c.getMode() == IpSecTransform.MODE_TUNNEL) {
- enforceTunnelFeatureAndPermissions(callingPackage);
- }
- checkIpSecConfig(c);
- Objects.requireNonNull(binder, "Null Binder passed to createTransform");
- final int resourceId = mNextResourceId++;
-
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
- List<RefcountedResource> dependencies = new ArrayList<>();
-
- if (!userRecord.mTransformQuotaTracker.isAvailable()) {
- return new IpSecTransformResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
- }
-
- EncapSocketRecord socketRecord = null;
- if (c.getEncapType() != IpSecTransform.ENCAP_NONE) {
- RefcountedResource<EncapSocketRecord> refcountedSocketRecord =
- userRecord.mEncapSocketRecords.getRefcountedResourceOrThrow(
- c.getEncapSocketResourceId());
- dependencies.add(refcountedSocketRecord);
- socketRecord = refcountedSocketRecord.getResource();
- }
-
- RefcountedResource<SpiRecord> refcountedSpiRecord =
- userRecord.mSpiRecords.getRefcountedResourceOrThrow(c.getSpiResourceId());
- dependencies.add(refcountedSpiRecord);
- SpiRecord spiRecord = refcountedSpiRecord.getResource();
-
- createOrUpdateTransform(c, resourceId, spiRecord, socketRecord);
-
- // SA was created successfully, time to construct a record and lock it away
- userRecord.mTransformRecords.put(
- resourceId,
- new RefcountedResource<TransformRecord>(
- new TransformRecord(resourceId, c, spiRecord, socketRecord),
- binder,
- dependencies.toArray(new RefcountedResource[dependencies.size()])));
- return new IpSecTransformResponse(IpSecManager.Status.OK, resourceId);
- }
-
- /**
- * Delete a transport mode transform that was previously allocated by + registered with the
- * system server. If this is called on an inactive (or non-existent) transform, it will not
- * return an error. It's safe to de-allocate transforms that may have already been deleted for
- * other reasons.
- */
- @Override
- public synchronized void deleteTransform(int resourceId) throws RemoteException {
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
- releaseResource(userRecord.mTransformRecords, resourceId);
- }
-
- /**
- * Apply an active transport mode transform to a socket, which will apply the IPsec security
- * association as a correspondent policy to the provided socket
- */
- @Override
- public synchronized void applyTransportModeTransform(
- ParcelFileDescriptor socket, int direction, int resourceId) throws RemoteException {
- int callingUid = Binder.getCallingUid();
- UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
- checkDirection(direction);
- // Get transform record; if no transform is found, will throw IllegalArgumentException
- TransformRecord info = userRecord.mTransformRecords.getResourceOrThrow(resourceId);
-
- // TODO: make this a function.
- if (info.mPid != getCallingPid() || info.mUid != callingUid) {
- throw new SecurityException("Only the owner of an IpSec Transform may apply it!");
- }
-
- // Get config and check that to-be-applied transform has the correct mode
- IpSecConfig c = info.getConfig();
- Preconditions.checkArgument(
- c.getMode() == IpSecTransform.MODE_TRANSPORT,
- "Transform mode was not Transport mode; cannot be applied to a socket");
-
- mNetd.ipSecApplyTransportModeTransform(
- socket,
- callingUid,
- direction,
- c.getSourceAddress(),
- c.getDestinationAddress(),
- info.getSpiRecord().getSpi());
- }
-
- /**
- * Remove transport mode transforms from a socket, applying the default (empty) policy. This
- * ensures that NO IPsec policy is applied to the socket (would be the equivalent of applying a
- * policy that performs no IPsec). Today the resourceId parameter is passed but not used:
- * reserved for future improved input validation.
- */
- @Override
- public synchronized void removeTransportModeTransforms(ParcelFileDescriptor socket)
- throws RemoteException {
- mNetd.ipSecRemoveTransportModeTransform(socket);
- }
-
- /**
- * Apply an active tunnel mode transform to a TunnelInterface, which will apply the IPsec
- * security association as a correspondent policy to the provided interface
- */
- @Override
- public synchronized void applyTunnelModeTransform(
- int tunnelResourceId, int direction,
- int transformResourceId, String callingPackage) throws RemoteException {
- enforceTunnelFeatureAndPermissions(callingPackage);
- checkDirection(direction);
-
- int callingUid = Binder.getCallingUid();
- UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
-
- // Get transform record; if no transform is found, will throw IllegalArgumentException
- TransformRecord transformInfo =
- userRecord.mTransformRecords.getResourceOrThrow(transformResourceId);
-
- // Get tunnelInterface record; if no such interface is found, will throw
- // IllegalArgumentException
- TunnelInterfaceRecord tunnelInterfaceInfo =
- userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
-
- // Get config and check that to-be-applied transform has the correct mode
- IpSecConfig c = transformInfo.getConfig();
- Preconditions.checkArgument(
- c.getMode() == IpSecTransform.MODE_TUNNEL,
- "Transform mode was not Tunnel mode; cannot be applied to a tunnel interface");
-
- EncapSocketRecord socketRecord = null;
- if (c.getEncapType() != IpSecTransform.ENCAP_NONE) {
- socketRecord =
- userRecord.mEncapSocketRecords.getResourceOrThrow(c.getEncapSocketResourceId());
- }
- SpiRecord spiRecord = transformInfo.getSpiRecord();
-
- int mark =
- (direction == IpSecManager.DIRECTION_OUT)
- ? tunnelInterfaceInfo.getOkey()
- : tunnelInterfaceInfo.getIkey(); // Ikey also used for FWD policies
-
- try {
- // Default to using the invalid SPI of 0 for inbound SAs. This allows policies to skip
- // SPI matching as part of the template resolution.
- int spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
- c.setXfrmInterfaceId(tunnelInterfaceInfo.getIfId());
-
- // TODO: enable this when UPDSA supports updating marks. Adding kernel support upstream
- // (and backporting) would allow us to narrow the mark space, and ensure that the SA
- // and SPs have matching marks (as VTI are meant to be built).
- // Currently update does nothing with marks. Leave empty (defaulting to 0) to ensure the
- // config matches the actual allocated resources in the kernel.
- // All SAs will have zero marks (from creation time), and any policy that matches the
- // same src/dst could match these SAs. Non-IpSecService governed processes that
- // establish floating policies with the same src/dst may result in undefined
- // behavior. This is generally limited to vendor code due to the permissions
- // (CAP_NET_ADMIN) required.
- //
- // c.setMarkValue(mark);
- // c.setMarkMask(0xffffffff);
-
- if (direction == IpSecManager.DIRECTION_OUT) {
- // Set output mark via underlying network (output only)
- c.setNetwork(tunnelInterfaceInfo.getUnderlyingNetwork());
-
- // Set outbound SPI only. We want inbound to use any valid SA (old, new) on rekeys,
- // but want to guarantee outbound packets are sent over the new SA.
- spi = spiRecord.getSpi();
- }
-
- // Always update the policy with the relevant XFRM_IF_ID
- for (int selAddrFamily : ADDRESS_FAMILIES) {
- mNetd.ipSecUpdateSecurityPolicy(
- callingUid,
- selAddrFamily,
- direction,
- transformInfo.getConfig().getSourceAddress(),
- transformInfo.getConfig().getDestinationAddress(),
- spi, // If outbound, also add SPI to the policy.
- mark, // Must always set policy mark; ikey/okey for VTIs
- 0xffffffff,
- c.getXfrmInterfaceId());
- }
-
- // Update SA with tunnel mark (ikey or okey based on direction)
- createOrUpdateTransform(c, transformResourceId, spiRecord, socketRecord);
- } catch (ServiceSpecificException e) {
- if (e.errorCode == EINVAL) {
- throw new IllegalArgumentException(e.toString());
- } else {
- throw e;
- }
- }
- }
-
- @Override
- protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(DUMP, TAG);
-
- pw.println("IpSecService dump:");
- pw.println();
-
- pw.println("mUserResourceTracker:");
- pw.println(mUserResourceTracker);
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/NativeDaemonConnector.java b/packages/ConnectivityT/service/src/com/android/server/NativeDaemonConnector.java
deleted file mode 100644
index ec8d779..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/NativeDaemonConnector.java
+++ /dev/null
@@ -1,704 +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 com.android.server;
-
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.os.Build;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.util.LocalLog;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.Objects;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Generic connector class for interfacing with a native daemon which uses the
- * {@code libsysutils} FrameworkListener protocol.
- */
-final class NativeDaemonConnector implements Runnable, Handler.Callback {
- private final static boolean VDBG = false;
-
- private final String TAG;
-
- private String mSocket;
- private OutputStream mOutputStream;
- private LocalLog mLocalLog;
-
- private volatile boolean mDebug = false;
- private volatile Object mWarnIfHeld;
-
- private final ResponseQueue mResponseQueue;
-
- private final PowerManager.WakeLock mWakeLock;
-
- private final Looper mLooper;
-
- private INativeDaemonConnectorCallbacks mCallbacks;
- private Handler mCallbackHandler;
-
- private AtomicInteger mSequenceNumber;
-
- private static final long DEFAULT_TIMEOUT = 1 * 60 * 1000; /* 1 minute */
- private static final long WARN_EXECUTE_DELAY_MS = 500; /* .5 sec */
-
- /** Lock held whenever communicating with native daemon. */
- private final Object mDaemonLock = new Object();
-
- private final int BUFFER_SIZE = 4096;
-
- NativeDaemonConnector(INativeDaemonConnectorCallbacks callbacks, String socket,
- int responseQueueSize, String logTag, int maxLogSize, PowerManager.WakeLock wl) {
- mCallbacks = callbacks;
- mSocket = socket;
- mResponseQueue = new ResponseQueue(responseQueueSize);
- mWakeLock = wl;
- if (mWakeLock != null) {
- mWakeLock.setReferenceCounted(true);
- }
- mSequenceNumber = new AtomicInteger(0);
- TAG = logTag != null ? logTag : "NativeDaemonConnector";
- mLocalLog = new LocalLog(maxLogSize);
- final HandlerThread thread = new HandlerThread(TAG);
- thread.start();
- mLooper = thread.getLooper();
- }
-
- /**
- * Enable Set debugging mode, which causes messages to also be written to both
- * {@link Log} in addition to internal log.
- */
- public void setDebug(boolean debug) {
- mDebug = debug;
- }
-
- /**
- * Like SystemClock.uptimeMillis, except truncated to an int so it will fit in a message arg.
- * Inaccurate across 49.7 days of uptime, but only used for debugging.
- */
- private int uptimeMillisInt() {
- return (int) SystemClock.uptimeMillis() & Integer.MAX_VALUE;
- }
-
- /**
- * Yell loudly if someone tries making future {@link #execute(Command)}
- * calls while holding a lock on the given object.
- */
- public void setWarnIfHeld(Object warnIfHeld) {
- if (mWarnIfHeld != null) {
- throw new IllegalStateException("warnIfHeld is already set.");
- }
- mWarnIfHeld = Objects.requireNonNull(warnIfHeld);
- }
-
- @Override
- public void run() {
- mCallbackHandler = new Handler(mLooper, this);
-
- while (true) {
- try {
- listenToSocket();
- } catch (Exception e) {
- loge("Error in NativeDaemonConnector: " + e);
- SystemClock.sleep(5000);
- }
- }
- }
-
- @Override
- public boolean handleMessage(Message msg) {
- final String event = (String) msg.obj;
- final int start = uptimeMillisInt();
- final int sent = msg.arg1;
- try {
- if (!mCallbacks.onEvent(msg.what, event, NativeDaemonEvent.unescapeArgs(event))) {
- log(String.format("Unhandled event '%s'", event));
- }
- } catch (Exception e) {
- loge("Error handling '" + event + "': " + e);
- } finally {
- if (mCallbacks.onCheckHoldWakeLock(msg.what) && mWakeLock != null) {
- mWakeLock.release();
- }
- final int end = uptimeMillisInt();
- if (start > sent && start - sent > WARN_EXECUTE_DELAY_MS) {
- loge(String.format("NDC event {%s} processed too late: %dms", event, start - sent));
- }
- if (end > start && end - start > WARN_EXECUTE_DELAY_MS) {
- loge(String.format("NDC event {%s} took too long: %dms", event, end - start));
- }
- }
- return true;
- }
-
- private LocalSocketAddress determineSocketAddress() {
- // If we're testing, set up a socket in a namespace that's accessible to test code.
- // In order to ensure that unprivileged apps aren't able to impersonate native daemons on
- // production devices, even if said native daemons ill-advisedly pick a socket name that
- // starts with __test__, only allow this on debug builds.
- if (mSocket.startsWith("__test__") && Build.isDebuggable()) {
- return new LocalSocketAddress(mSocket);
- } else {
- return new LocalSocketAddress(mSocket, LocalSocketAddress.Namespace.RESERVED);
- }
- }
-
- private void listenToSocket() throws IOException {
- LocalSocket socket = null;
-
- try {
- socket = new LocalSocket();
- LocalSocketAddress address = determineSocketAddress();
-
- socket.connect(address);
-
- InputStream inputStream = socket.getInputStream();
- synchronized (mDaemonLock) {
- mOutputStream = socket.getOutputStream();
- }
-
- mCallbacks.onDaemonConnected();
-
- FileDescriptor[] fdList = null;
- byte[] buffer = new byte[BUFFER_SIZE];
- int start = 0;
-
- while (true) {
- int count = inputStream.read(buffer, start, BUFFER_SIZE - start);
- if (count < 0) {
- loge("got " + count + " reading with start = " + start);
- break;
- }
- fdList = socket.getAncillaryFileDescriptors();
-
- // Add our starting point to the count and reset the start.
- count += start;
- start = 0;
-
- for (int i = 0; i < count; i++) {
- if (buffer[i] == 0) {
- // Note - do not log this raw message since it may contain
- // sensitive data
- final String rawEvent = new String(
- buffer, start, i - start, StandardCharsets.UTF_8);
-
- boolean releaseWl = false;
- try {
- final NativeDaemonEvent event =
- NativeDaemonEvent.parseRawEvent(rawEvent, fdList);
-
- log("RCV <- {" + event + "}");
-
- if (event.isClassUnsolicited()) {
- // TODO: migrate to sending NativeDaemonEvent instances
- if (mCallbacks.onCheckHoldWakeLock(event.getCode())
- && mWakeLock != null) {
- mWakeLock.acquire();
- releaseWl = true;
- }
- Message msg = mCallbackHandler.obtainMessage(
- event.getCode(), uptimeMillisInt(), 0, event.getRawEvent());
- if (mCallbackHandler.sendMessage(msg)) {
- releaseWl = false;
- }
- } else {
- mResponseQueue.add(event.getCmdNumber(), event);
- }
- } catch (IllegalArgumentException e) {
- log("Problem parsing message " + e);
- } finally {
- if (releaseWl) {
- mWakeLock.release();
- }
- }
-
- start = i + 1;
- }
- }
-
- if (start == 0) {
- log("RCV incomplete");
- }
-
- // We should end at the amount we read. If not, compact then
- // buffer and read again.
- if (start != count) {
- final int remaining = BUFFER_SIZE - start;
- System.arraycopy(buffer, start, buffer, 0, remaining);
- start = remaining;
- } else {
- start = 0;
- }
- }
- } catch (IOException ex) {
- loge("Communications error: " + ex);
- throw ex;
- } finally {
- synchronized (mDaemonLock) {
- if (mOutputStream != null) {
- try {
- loge("closing stream for " + mSocket);
- mOutputStream.close();
- } catch (IOException e) {
- loge("Failed closing output stream: " + e);
- }
- mOutputStream = null;
- }
- }
-
- try {
- if (socket != null) {
- socket.close();
- }
- } catch (IOException ex) {
- loge("Failed closing socket: " + ex);
- }
- }
- }
-
- /**
- * Wrapper around argument that indicates it's sensitive and shouldn't be
- * logged.
- */
- public static class SensitiveArg {
- private final Object mArg;
-
- public SensitiveArg(Object arg) {
- mArg = arg;
- }
-
- @Override
- public String toString() {
- return String.valueOf(mArg);
- }
- }
-
- /**
- * Make command for daemon, escaping arguments as needed.
- */
- @VisibleForTesting
- static void makeCommand(StringBuilder rawBuilder, StringBuilder logBuilder, int sequenceNumber,
- String cmd, Object... args) {
- if (cmd.indexOf('\0') >= 0) {
- throw new IllegalArgumentException("Unexpected command: " + cmd);
- }
- if (cmd.indexOf(' ') >= 0) {
- throw new IllegalArgumentException("Arguments must be separate from command");
- }
-
- rawBuilder.append(sequenceNumber).append(' ').append(cmd);
- logBuilder.append(sequenceNumber).append(' ').append(cmd);
- for (Object arg : args) {
- final String argString = String.valueOf(arg);
- if (argString.indexOf('\0') >= 0) {
- throw new IllegalArgumentException("Unexpected argument: " + arg);
- }
-
- rawBuilder.append(' ');
- logBuilder.append(' ');
-
- appendEscaped(rawBuilder, argString);
- if (arg instanceof SensitiveArg) {
- logBuilder.append("[scrubbed]");
- } else {
- appendEscaped(logBuilder, argString);
- }
- }
-
- rawBuilder.append('\0');
- }
-
- /**
- * Method that waits until all asychronous notifications sent by the native daemon have
- * been processed. This method must not be called on the notification thread or an
- * exception will be thrown.
- */
- public void waitForCallbacks() {
- if (Thread.currentThread() == mLooper.getThread()) {
- throw new IllegalStateException("Must not call this method on callback thread");
- }
-
- final CountDownLatch latch = new CountDownLatch(1);
- mCallbackHandler.post(new Runnable() {
- @Override
- public void run() {
- latch.countDown();
- }
- });
- try {
- latch.await();
- } catch (InterruptedException e) {
- Log.wtf(TAG, "Interrupted while waiting for unsolicited response handling", e);
- }
- }
-
- /**
- * Issue the given command to the native daemon and return a single expected
- * response.
- *
- * @throws NativeDaemonConnectorException when problem communicating with
- * native daemon, or if the response matches
- * {@link NativeDaemonEvent#isClassClientError()} or
- * {@link NativeDaemonEvent#isClassServerError()}.
- */
- public NativeDaemonEvent execute(Command cmd) throws NativeDaemonConnectorException {
- return execute(cmd.mCmd, cmd.mArguments.toArray());
- }
-
- /**
- * Issue the given command to the native daemon and return a single expected
- * response. Any arguments must be separated from base command so they can
- * be properly escaped.
- *
- * @throws NativeDaemonConnectorException when problem communicating with
- * native daemon, or if the response matches
- * {@link NativeDaemonEvent#isClassClientError()} or
- * {@link NativeDaemonEvent#isClassServerError()}.
- */
- public NativeDaemonEvent execute(String cmd, Object... args)
- throws NativeDaemonConnectorException {
- return execute(DEFAULT_TIMEOUT, cmd, args);
- }
-
- public NativeDaemonEvent execute(long timeoutMs, String cmd, Object... args)
- throws NativeDaemonConnectorException {
- final NativeDaemonEvent[] events = executeForList(timeoutMs, cmd, args);
- if (events.length != 1) {
- throw new NativeDaemonConnectorException(
- "Expected exactly one response, but received " + events.length);
- }
- return events[0];
- }
-
- /**
- * Issue the given command to the native daemon and return any
- * {@link NativeDaemonEvent#isClassContinue()} responses, including the
- * final terminal response.
- *
- * @throws NativeDaemonConnectorException when problem communicating with
- * native daemon, or if the response matches
- * {@link NativeDaemonEvent#isClassClientError()} or
- * {@link NativeDaemonEvent#isClassServerError()}.
- */
- public NativeDaemonEvent[] executeForList(Command cmd) throws NativeDaemonConnectorException {
- return executeForList(cmd.mCmd, cmd.mArguments.toArray());
- }
-
- /**
- * Issue the given command to the native daemon and return any
- * {@link NativeDaemonEvent#isClassContinue()} responses, including the
- * final terminal response. Any arguments must be separated from base
- * command so they can be properly escaped.
- *
- * @throws NativeDaemonConnectorException when problem communicating with
- * native daemon, or if the response matches
- * {@link NativeDaemonEvent#isClassClientError()} or
- * {@link NativeDaemonEvent#isClassServerError()}.
- */
- public NativeDaemonEvent[] executeForList(String cmd, Object... args)
- throws NativeDaemonConnectorException {
- return executeForList(DEFAULT_TIMEOUT, cmd, args);
- }
-
- /**
- * Issue the given command to the native daemon and return any {@linke
- * NativeDaemonEvent@isClassContinue()} responses, including the final
- * terminal response. Note that the timeout does not count time in deep
- * sleep. Any arguments must be separated from base command so they can be
- * properly escaped.
- *
- * @throws NativeDaemonConnectorException when problem communicating with
- * native daemon, or if the response matches
- * {@link NativeDaemonEvent#isClassClientError()} or
- * {@link NativeDaemonEvent#isClassServerError()}.
- */
- public NativeDaemonEvent[] executeForList(long timeoutMs, String cmd, Object... args)
- throws NativeDaemonConnectorException {
- if (mWarnIfHeld != null && Thread.holdsLock(mWarnIfHeld)) {
- Log.wtf(TAG, "Calling thread " + Thread.currentThread().getName() + " is holding 0x"
- + Integer.toHexString(System.identityHashCode(mWarnIfHeld)), new Throwable());
- }
-
- final long startTime = SystemClock.elapsedRealtime();
-
- final ArrayList<NativeDaemonEvent> events = new ArrayList<>();
-
- final StringBuilder rawBuilder = new StringBuilder();
- final StringBuilder logBuilder = new StringBuilder();
- final int sequenceNumber = mSequenceNumber.incrementAndGet();
-
- makeCommand(rawBuilder, logBuilder, sequenceNumber, cmd, args);
-
- final String rawCmd = rawBuilder.toString();
- final String logCmd = logBuilder.toString();
-
- log("SND -> {" + logCmd + "}");
-
- synchronized (mDaemonLock) {
- if (mOutputStream == null) {
- throw new NativeDaemonConnectorException("missing output stream");
- } else {
- try {
- mOutputStream.write(rawCmd.getBytes(StandardCharsets.UTF_8));
- } catch (IOException e) {
- throw new NativeDaemonConnectorException("problem sending command", e);
- }
- }
- }
-
- NativeDaemonEvent event = null;
- do {
- event = mResponseQueue.remove(sequenceNumber, timeoutMs, logCmd);
- if (event == null) {
- loge("timed-out waiting for response to " + logCmd);
- throw new NativeDaemonTimeoutException(logCmd, event);
- }
- if (VDBG) log("RMV <- {" + event + "}");
- events.add(event);
- } while (event.isClassContinue());
-
- final long endTime = SystemClock.elapsedRealtime();
- if (endTime - startTime > WARN_EXECUTE_DELAY_MS) {
- loge("NDC Command {" + logCmd + "} took too long (" + (endTime - startTime) + "ms)");
- }
-
- if (event.isClassClientError()) {
- throw new NativeDaemonArgumentException(logCmd, event);
- }
- if (event.isClassServerError()) {
- throw new NativeDaemonFailureException(logCmd, event);
- }
-
- return events.toArray(new NativeDaemonEvent[events.size()]);
- }
-
- /**
- * Append the given argument to {@link StringBuilder}, escaping as needed,
- * and surrounding with quotes when it contains spaces.
- */
- @VisibleForTesting
- static void appendEscaped(StringBuilder builder, String arg) {
- final boolean hasSpaces = arg.indexOf(' ') >= 0;
- if (hasSpaces) {
- builder.append('"');
- }
-
- final int length = arg.length();
- for (int i = 0; i < length; i++) {
- final char c = arg.charAt(i);
-
- if (c == '"') {
- builder.append("\\\"");
- } else if (c == '\\') {
- builder.append("\\\\");
- } else {
- builder.append(c);
- }
- }
-
- if (hasSpaces) {
- builder.append('"');
- }
- }
-
- private static class NativeDaemonArgumentException extends NativeDaemonConnectorException {
- public NativeDaemonArgumentException(String command, NativeDaemonEvent event) {
- super(command, event);
- }
-
- @Override
- public IllegalArgumentException rethrowAsParcelableException() {
- throw new IllegalArgumentException(getMessage(), this);
- }
- }
-
- private static class NativeDaemonFailureException extends NativeDaemonConnectorException {
- public NativeDaemonFailureException(String command, NativeDaemonEvent event) {
- super(command, event);
- }
- }
-
- /**
- * Command builder that handles argument list building. Any arguments must
- * be separated from base command so they can be properly escaped.
- */
- public static class Command {
- private String mCmd;
- private ArrayList<Object> mArguments = new ArrayList<>();
-
- public Command(String cmd, Object... args) {
- mCmd = cmd;
- for (Object arg : args) {
- appendArg(arg);
- }
- }
-
- public Command appendArg(Object arg) {
- mArguments.add(arg);
- return this;
- }
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mLocalLog.dump(fd, pw, args);
- pw.println();
- mResponseQueue.dump(fd, pw, args);
- }
-
- private void log(String logstring) {
- if (mDebug) Log.d(TAG, logstring);
- mLocalLog.log(logstring);
- }
-
- private void loge(String logstring) {
- Log.e(TAG, logstring);
- mLocalLog.log(logstring);
- }
-
- private static class ResponseQueue {
-
- private static class PendingCmd {
- public final int cmdNum;
- public final String logCmd;
-
- public BlockingQueue<NativeDaemonEvent> responses =
- new ArrayBlockingQueue<NativeDaemonEvent>(10);
-
- // The availableResponseCount member is used to track when we can remove this
- // instance from the ResponseQueue.
- // This is used under the protection of a sync of the mPendingCmds object.
- // A positive value means we've had more writers retreive this object while
- // a negative value means we've had more readers. When we've had an equal number
- // (it goes to zero) we can remove this object from the mPendingCmds list.
- // Note that we may have more responses for this command (and more readers
- // coming), but that would result in a new PendingCmd instance being created
- // and added with the same cmdNum.
- // Also note that when this goes to zero it just means a parity of readers and
- // writers have retrieved this object - not that they are done using it. The
- // responses queue may well have more responses yet to be read or may get more
- // responses added to it. But all those readers/writers have retreived and
- // hold references to this instance already so it can be removed from
- // mPendingCmds queue.
- public int availableResponseCount;
-
- public PendingCmd(int cmdNum, String logCmd) {
- this.cmdNum = cmdNum;
- this.logCmd = logCmd;
- }
- }
-
- private final LinkedList<PendingCmd> mPendingCmds;
- private int mMaxCount;
-
- ResponseQueue(int maxCount) {
- mPendingCmds = new LinkedList<PendingCmd>();
- mMaxCount = maxCount;
- }
-
- public void add(int cmdNum, NativeDaemonEvent response) {
- PendingCmd found = null;
- synchronized (mPendingCmds) {
- for (PendingCmd pendingCmd : mPendingCmds) {
- if (pendingCmd.cmdNum == cmdNum) {
- found = pendingCmd;
- break;
- }
- }
- if (found == null) {
- // didn't find it - make sure our queue isn't too big before adding
- while (mPendingCmds.size() >= mMaxCount) {
- Log.e("NativeDaemonConnector.ResponseQueue",
- "more buffered than allowed: " + mPendingCmds.size() +
- " >= " + mMaxCount);
- // let any waiter timeout waiting for this
- PendingCmd pendingCmd = mPendingCmds.remove();
- Log.e("NativeDaemonConnector.ResponseQueue",
- "Removing request: " + pendingCmd.logCmd + " (" +
- pendingCmd.cmdNum + ")");
- }
- found = new PendingCmd(cmdNum, null);
- mPendingCmds.add(found);
- }
- found.availableResponseCount++;
- // if a matching remove call has already retrieved this we can remove this
- // instance from our list
- if (found.availableResponseCount == 0) mPendingCmds.remove(found);
- }
- try {
- found.responses.put(response);
- } catch (InterruptedException e) { }
- }
-
- // note that the timeout does not count time in deep sleep. If you don't want
- // the device to sleep, hold a wakelock
- public NativeDaemonEvent remove(int cmdNum, long timeoutMs, String logCmd) {
- PendingCmd found = null;
- synchronized (mPendingCmds) {
- for (PendingCmd pendingCmd : mPendingCmds) {
- if (pendingCmd.cmdNum == cmdNum) {
- found = pendingCmd;
- break;
- }
- }
- if (found == null) {
- found = new PendingCmd(cmdNum, logCmd);
- mPendingCmds.add(found);
- }
- found.availableResponseCount--;
- // if a matching add call has already retrieved this we can remove this
- // instance from our list
- if (found.availableResponseCount == 0) mPendingCmds.remove(found);
- }
- NativeDaemonEvent result = null;
- try {
- result = found.responses.poll(timeoutMs, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {}
- if (result == null) {
- Log.e("NativeDaemonConnector.ResponseQueue", "Timeout waiting for response");
- }
- return result;
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("Pending requests:");
- synchronized (mPendingCmds) {
- for (PendingCmd pendingCmd : mPendingCmds) {
- pw.println(" Cmd " + pendingCmd.cmdNum + " - " + pendingCmd.logCmd);
- }
- }
- }
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/NativeDaemonConnectorException.java b/packages/ConnectivityT/service/src/com/android/server/NativeDaemonConnectorException.java
deleted file mode 100644
index 4d8881c..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/NativeDaemonConnectorException.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2006 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;
-
-import android.os.Parcel;
-
-/**
- * An exception that indicates there was an error with a
- * {@link NativeDaemonConnector} operation.
- */
-public class NativeDaemonConnectorException extends Exception {
- private String mCmd;
- private NativeDaemonEvent mEvent;
-
- public NativeDaemonConnectorException(String detailMessage) {
- super(detailMessage);
- }
-
- public NativeDaemonConnectorException(String detailMessage, Throwable throwable) {
- super(detailMessage, throwable);
- }
-
- public NativeDaemonConnectorException(String cmd, NativeDaemonEvent event) {
- super("command '" + cmd + "' failed with '" + event + "'");
- mCmd = cmd;
- mEvent = event;
- }
-
- public int getCode() {
- return mEvent != null ? mEvent.getCode() : -1;
- }
-
- public String getCmd() {
- return mCmd;
- }
-
- /**
- * Rethrow as a {@link RuntimeException} subclass that is handled by
- * {@link Parcel#writeException(Exception)}.
- */
- public IllegalArgumentException rethrowAsParcelableException() {
- throw new IllegalStateException(getMessage(), this);
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/NativeDaemonEvent.java b/packages/ConnectivityT/service/src/com/android/server/NativeDaemonEvent.java
deleted file mode 100644
index 5683694..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/NativeDaemonEvent.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.util.ArrayList;
-
-/**
- * Parsed event from native side of {@link NativeDaemonConnector}.
- */
-public class NativeDaemonEvent {
-
- // TODO: keep class ranges in sync with ResponseCode.h
- // TODO: swap client and server error ranges to roughly mirror HTTP spec
-
- private final int mCmdNumber;
- private final int mCode;
- private final String mMessage;
- private final String mRawEvent;
- private final String mLogMessage;
- private String[] mParsed;
- private FileDescriptor[] mFdList;
-
- private NativeDaemonEvent(int cmdNumber, int code, String message,
- String rawEvent, String logMessage, FileDescriptor[] fdList) {
- mCmdNumber = cmdNumber;
- mCode = code;
- mMessage = message;
- mRawEvent = rawEvent;
- mLogMessage = logMessage;
- mParsed = null;
- mFdList = fdList;
- }
-
- static public final String SENSITIVE_MARKER = "{{sensitive}}";
-
- public int getCmdNumber() {
- return mCmdNumber;
- }
-
- public int getCode() {
- return mCode;
- }
-
- public String getMessage() {
- return mMessage;
- }
-
- public FileDescriptor[] getFileDescriptors() {
- return mFdList;
- }
-
- @Deprecated
- public String getRawEvent() {
- return mRawEvent;
- }
-
- @Override
- public String toString() {
- return mLogMessage;
- }
-
- /**
- * Test if event represents a partial response which is continued in
- * additional subsequent events.
- */
- public boolean isClassContinue() {
- return mCode >= 100 && mCode < 200;
- }
-
- /**
- * Test if event represents a command success.
- */
- public boolean isClassOk() {
- return mCode >= 200 && mCode < 300;
- }
-
- /**
- * Test if event represents a remote native daemon error.
- */
- public boolean isClassServerError() {
- return mCode >= 400 && mCode < 500;
- }
-
- /**
- * Test if event represents a command syntax or argument error.
- */
- public boolean isClassClientError() {
- return mCode >= 500 && mCode < 600;
- }
-
- /**
- * Test if event represents an unsolicited event from native daemon.
- */
- public boolean isClassUnsolicited() {
- return isClassUnsolicited(mCode);
- }
-
- private static boolean isClassUnsolicited(int code) {
- return code >= 600 && code < 700;
- }
-
- /**
- * Verify this event matches the given code.
- *
- * @throws IllegalStateException if {@link #getCode()} doesn't match.
- */
- public void checkCode(int code) {
- if (mCode != code) {
- throw new IllegalStateException("Expected " + code + " but was: " + this);
- }
- }
-
- /**
- * Parse the given raw event into {@link NativeDaemonEvent} instance.
- *
- * @throws IllegalArgumentException when line doesn't match format expected
- * from native side.
- */
- public static NativeDaemonEvent parseRawEvent(String rawEvent, FileDescriptor[] fdList) {
- final String[] parsed = rawEvent.split(" ");
- if (parsed.length < 2) {
- throw new IllegalArgumentException("Insufficient arguments");
- }
-
- int skiplength = 0;
-
- final int code;
- try {
- code = Integer.parseInt(parsed[0]);
- skiplength = parsed[0].length() + 1;
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("problem parsing code", e);
- }
-
- int cmdNumber = -1;
- if (isClassUnsolicited(code) == false) {
- if (parsed.length < 3) {
- throw new IllegalArgumentException("Insufficient arguemnts");
- }
- try {
- cmdNumber = Integer.parseInt(parsed[1]);
- skiplength += parsed[1].length() + 1;
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("problem parsing cmdNumber", e);
- }
- }
-
- String logMessage = rawEvent;
- if (parsed.length > 2 && parsed[2].equals(SENSITIVE_MARKER)) {
- skiplength += parsed[2].length() + 1;
- logMessage = parsed[0] + " " + parsed[1] + " {}";
- }
-
- final String message = rawEvent.substring(skiplength);
-
- return new NativeDaemonEvent(cmdNumber, code, message, rawEvent, logMessage, fdList);
- }
-
- /**
- * Filter the given {@link NativeDaemonEvent} list, returning
- * {@link #getMessage()} for any events matching the requested code.
- */
- public static String[] filterMessageList(NativeDaemonEvent[] events, int matchCode) {
- final ArrayList<String> result = new ArrayList<>();
- for (NativeDaemonEvent event : events) {
- if (event.getCode() == matchCode) {
- result.add(event.getMessage());
- }
- }
- return result.toArray(new String[result.size()]);
- }
-
- /**
- * Find the Nth field of the event.
- *
- * This ignores and code or cmdNum, the first return value is given for N=0.
- * Also understands "\"quoted\" multiword responses" and tries them as a single field
- */
- public String getField(int n) {
- if (mParsed == null) {
- mParsed = unescapeArgs(mRawEvent);
- }
- n += 2; // skip code and command#
- if (n > mParsed.length) return null;
- return mParsed[n];
- }
-
- public static String[] unescapeArgs(String rawEvent) {
- final boolean DEBUG_ROUTINE = false;
- final String LOGTAG = "unescapeArgs";
- final ArrayList<String> parsed = new ArrayList<String>();
- final int length = rawEvent.length();
- int current = 0;
- int wordEnd = -1;
- boolean quoted = false;
-
- if (DEBUG_ROUTINE) Log.e(LOGTAG, "parsing '" + rawEvent + "'");
- if (rawEvent.charAt(current) == '\"') {
- quoted = true;
- current++;
- }
- while (current < length) {
- // find the end of the word
- char terminator = quoted ? '\"' : ' ';
- wordEnd = current;
- while (wordEnd < length && rawEvent.charAt(wordEnd) != terminator) {
- if (rawEvent.charAt(wordEnd) == '\\') {
- // skip the escaped char
- ++wordEnd;
- }
- ++wordEnd;
- }
- if (wordEnd > length) wordEnd = length;
- String word = rawEvent.substring(current, wordEnd);
- current += word.length();
- if (!quoted) {
- word = word.trim();
- } else {
- current++; // skip the trailing quote
- }
- // unescape stuff within the word
- word = word.replace("\\\\", "\\");
- word = word.replace("\\\"", "\"");
-
- if (DEBUG_ROUTINE) Log.e(LOGTAG, "found '" + word + "'");
- parsed.add(word);
-
- // find the beginning of the next word - either of these options
- int nextSpace = rawEvent.indexOf(' ', current);
- int nextQuote = rawEvent.indexOf(" \"", current);
- if (DEBUG_ROUTINE) {
- Log.e(LOGTAG, "nextSpace=" + nextSpace + ", nextQuote=" + nextQuote);
- }
- if (nextQuote > -1 && nextQuote <= nextSpace) {
- quoted = true;
- current = nextQuote + 2;
- } else {
- quoted = false;
- if (nextSpace > -1) {
- current = nextSpace + 1;
- }
- } // else we just start the next word after the current and read til the end
- if (DEBUG_ROUTINE) {
- Log.e(LOGTAG, "next loop - current=" + current
- + ", length=" + length + ", quoted=" + quoted);
- }
- }
- return parsed.toArray(new String[parsed.size()]);
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/NativeDaemonTimeoutException.java b/packages/ConnectivityT/service/src/com/android/server/NativeDaemonTimeoutException.java
deleted file mode 100644
index 658f7d6..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/NativeDaemonTimeoutException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-/**
- * An exception that indicates there was a timeout with a
- * {@link NativeDaemonConnector} operation.
- */
-public class NativeDaemonTimeoutException extends NativeDaemonConnectorException {
- public NativeDaemonTimeoutException(String command, NativeDaemonEvent event) {
- super(command, event);
- }
-}
-
diff --git a/packages/ConnectivityT/service/src/com/android/server/NsdService.java b/packages/ConnectivityT/service/src/com/android/server/NsdService.java
deleted file mode 100644
index ddf6d2c..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/NsdService.java
+++ /dev/null
@@ -1,1146 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.nsd.INsdManager;
-import android.net.nsd.INsdManagerCallback;
-import android.net.nsd.INsdServiceConnector;
-import android.net.nsd.NsdManager;
-import android.net.nsd.NsdServiceInfo;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.Base64;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.net.module.util.DnsSdTxtRecord;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * Network Service Discovery Service handles remote service discovery operation requests by
- * implementing the INsdManager interface.
- *
- * @hide
- */
-public class NsdService extends INsdManager.Stub {
- private static final String TAG = "NsdService";
- private static final String MDNS_TAG = "mDnsConnector";
-
- private static final boolean DBG = true;
- private static final long CLEANUP_DELAY_MS = 10000;
- private static final int IFACE_IDX_ANY = 0;
-
- private final Context mContext;
- private final NsdStateMachine mNsdStateMachine;
- private final DaemonConnection mDaemon;
- private final NativeCallbackReceiver mDaemonCallback;
-
- /**
- * Clients receiving asynchronous messages
- */
- private final HashMap<NsdServiceConnector, ClientInfo> mClients = new HashMap<>();
-
- /* A map from unique id to client info */
- private final SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<>();
-
- private final long mCleanupDelayMs;
-
- private static final int INVALID_ID = 0;
- private int mUniqueId = 1;
- // The count of the connected legacy clients.
- private int mLegacyClientCount = 0;
-
- private class NsdStateMachine extends StateMachine {
-
- private final DefaultState mDefaultState = new DefaultState();
- private final DisabledState mDisabledState = new DisabledState();
- private final EnabledState mEnabledState = new EnabledState();
-
- @Override
- protected String getWhatToString(int what) {
- return NsdManager.nameOf(what);
- }
-
- private void maybeStartDaemon() {
- mDaemon.maybeStart();
- maybeScheduleStop();
- }
-
- private boolean isAnyRequestActive() {
- return mIdToClientInfoMap.size() != 0;
- }
-
- private void scheduleStop() {
- sendMessageDelayed(NsdManager.DAEMON_CLEANUP, mCleanupDelayMs);
- }
- private void maybeScheduleStop() {
- // The native daemon should stay alive and can't be cleanup
- // if any legacy client connected.
- if (!isAnyRequestActive() && mLegacyClientCount == 0) {
- scheduleStop();
- }
- }
-
- private void cancelStop() {
- this.removeMessages(NsdManager.DAEMON_CLEANUP);
- }
-
- NsdStateMachine(String name, Handler handler) {
- super(name, handler);
- addState(mDefaultState);
- addState(mDisabledState, mDefaultState);
- addState(mEnabledState, mDefaultState);
- State initialState = mEnabledState;
- setInitialState(initialState);
- setLogRecSize(25);
- }
-
- class DefaultState extends State {
- @Override
- public boolean processMessage(Message msg) {
- final ClientInfo cInfo;
- final int clientId = msg.arg2;
- switch (msg.what) {
- case NsdManager.REGISTER_CLIENT:
- final Pair<NsdServiceConnector, INsdManagerCallback> arg =
- (Pair<NsdServiceConnector, INsdManagerCallback>) msg.obj;
- final INsdManagerCallback cb = arg.second;
- try {
- cb.asBinder().linkToDeath(arg.first, 0);
- cInfo = new ClientInfo(cb);
- mClients.put(arg.first, cInfo);
- } catch (RemoteException e) {
- Log.w(TAG, "Client " + clientId + " has already died");
- }
- break;
- case NsdManager.UNREGISTER_CLIENT:
- final NsdServiceConnector connector = (NsdServiceConnector) msg.obj;
- cInfo = mClients.remove(connector);
- if (cInfo != null) {
- cInfo.expungeAllRequests();
- if (cInfo.isLegacy()) {
- mLegacyClientCount -= 1;
- }
- }
- maybeScheduleStop();
- break;
- case NsdManager.DISCOVER_SERVICES:
- cInfo = getClientInfoForReply(msg);
- if (cInfo != null) {
- cInfo.onDiscoverServicesFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- }
- break;
- case NsdManager.STOP_DISCOVERY:
- cInfo = getClientInfoForReply(msg);
- if (cInfo != null) {
- cInfo.onStopDiscoveryFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- }
- break;
- case NsdManager.REGISTER_SERVICE:
- cInfo = getClientInfoForReply(msg);
- if (cInfo != null) {
- cInfo.onRegisterServiceFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- }
- break;
- case NsdManager.UNREGISTER_SERVICE:
- cInfo = getClientInfoForReply(msg);
- if (cInfo != null) {
- cInfo.onUnregisterServiceFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- }
- break;
- case NsdManager.RESOLVE_SERVICE:
- cInfo = getClientInfoForReply(msg);
- if (cInfo != null) {
- cInfo.onResolveServiceFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- }
- break;
- case NsdManager.DAEMON_CLEANUP:
- mDaemon.maybeStop();
- break;
- // This event should be only sent by the legacy (target SDK < S) clients.
- // Mark the sending client as legacy.
- case NsdManager.DAEMON_STARTUP:
- cInfo = getClientInfoForReply(msg);
- if (cInfo != null) {
- cancelStop();
- cInfo.setLegacy();
- mLegacyClientCount += 1;
- maybeStartDaemon();
- }
- break;
- case NsdManager.NATIVE_DAEMON_EVENT:
- default:
- Log.e(TAG, "Unhandled " + msg);
- return NOT_HANDLED;
- }
- return HANDLED;
- }
-
- private ClientInfo getClientInfoForReply(Message msg) {
- final ListenerArgs args = (ListenerArgs) msg.obj;
- return mClients.get(args.connector);
- }
- }
-
- class DisabledState extends State {
- @Override
- public void enter() {
- sendNsdStateChangeBroadcast(false);
- }
-
- @Override
- public boolean processMessage(Message msg) {
- switch (msg.what) {
- case NsdManager.ENABLE:
- transitionTo(mEnabledState);
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
- }
-
- class EnabledState extends State {
- @Override
- public void enter() {
- sendNsdStateChangeBroadcast(true);
- }
-
- @Override
- public void exit() {
- // TODO: it is incorrect to stop the daemon without expunging all requests
- // and sending error callbacks to clients.
- scheduleStop();
- }
-
- private boolean requestLimitReached(ClientInfo clientInfo) {
- if (clientInfo.mClientIds.size() >= ClientInfo.MAX_LIMIT) {
- if (DBG) Log.d(TAG, "Exceeded max outstanding requests " + clientInfo);
- return true;
- }
- return false;
- }
-
- private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo, int what) {
- clientInfo.mClientIds.put(clientId, globalId);
- clientInfo.mClientRequests.put(clientId, what);
- mIdToClientInfoMap.put(globalId, clientInfo);
- // Remove the cleanup event because here comes a new request.
- cancelStop();
- }
-
- private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
- clientInfo.mClientIds.delete(clientId);
- clientInfo.mClientRequests.delete(clientId);
- mIdToClientInfoMap.remove(globalId);
- maybeScheduleStop();
- }
-
- @Override
- public boolean processMessage(Message msg) {
- final ClientInfo clientInfo;
- final int id;
- final int clientId = msg.arg2;
- final ListenerArgs args;
- switch (msg.what) {
- case NsdManager.DISABLE:
- //TODO: cleanup clients
- transitionTo(mDisabledState);
- break;
- case NsdManager.DISCOVER_SERVICES:
- if (DBG) Log.d(TAG, "Discover services");
- args = (ListenerArgs) msg.obj;
- clientInfo = mClients.get(args.connector);
-
- if (requestLimitReached(clientInfo)) {
- clientInfo.onDiscoverServicesFailed(
- clientId, NsdManager.FAILURE_MAX_LIMIT);
- break;
- }
-
- maybeStartDaemon();
- id = getUniqueId();
- if (discoverServices(id, args.serviceInfo)) {
- if (DBG) {
- Log.d(TAG, "Discover " + msg.arg2 + " " + id
- + args.serviceInfo.getServiceType());
- }
- storeRequestMap(clientId, id, clientInfo, msg.what);
- clientInfo.onDiscoverServicesStarted(clientId, args.serviceInfo);
- } else {
- stopServiceDiscovery(id);
- clientInfo.onDiscoverServicesFailed(clientId,
- NsdManager.FAILURE_INTERNAL_ERROR);
- }
- break;
- case NsdManager.STOP_DISCOVERY:
- if (DBG) Log.d(TAG, "Stop service discovery");
- args = (ListenerArgs) msg.obj;
- clientInfo = mClients.get(args.connector);
-
- try {
- id = clientInfo.mClientIds.get(clientId);
- } catch (NullPointerException e) {
- clientInfo.onStopDiscoveryFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- break;
- }
- removeRequestMap(clientId, id, clientInfo);
- if (stopServiceDiscovery(id)) {
- clientInfo.onStopDiscoverySucceeded(clientId);
- } else {
- clientInfo.onStopDiscoveryFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- }
- break;
- case NsdManager.REGISTER_SERVICE:
- if (DBG) Log.d(TAG, "Register service");
- args = (ListenerArgs) msg.obj;
- clientInfo = mClients.get(args.connector);
- if (requestLimitReached(clientInfo)) {
- clientInfo.onRegisterServiceFailed(
- clientId, NsdManager.FAILURE_MAX_LIMIT);
- break;
- }
-
- maybeStartDaemon();
- id = getUniqueId();
- if (registerService(id, args.serviceInfo)) {
- if (DBG) Log.d(TAG, "Register " + clientId + " " + id);
- storeRequestMap(clientId, id, clientInfo, msg.what);
- // Return success after mDns reports success
- } else {
- unregisterService(id);
- clientInfo.onRegisterServiceFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- }
- break;
- case NsdManager.UNREGISTER_SERVICE:
- if (DBG) Log.d(TAG, "unregister service");
- args = (ListenerArgs) msg.obj;
- clientInfo = mClients.get(args.connector);
- if (clientInfo == null) {
- Log.e(TAG, "Unknown connector in unregistration");
- break;
- }
- id = clientInfo.mClientIds.get(clientId);
- removeRequestMap(clientId, id, clientInfo);
- if (unregisterService(id)) {
- clientInfo.onUnregisterServiceSucceeded(clientId);
- } else {
- clientInfo.onUnregisterServiceFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- }
- break;
- case NsdManager.RESOLVE_SERVICE:
- if (DBG) Log.d(TAG, "Resolve service");
- args = (ListenerArgs) msg.obj;
- clientInfo = mClients.get(args.connector);
-
- if (clientInfo.mResolvedService != null) {
- clientInfo.onResolveServiceFailed(
- clientId, NsdManager.FAILURE_ALREADY_ACTIVE);
- break;
- }
-
- maybeStartDaemon();
- id = getUniqueId();
- if (resolveService(id, args.serviceInfo)) {
- clientInfo.mResolvedService = new NsdServiceInfo();
- storeRequestMap(clientId, id, clientInfo, msg.what);
- } else {
- clientInfo.onResolveServiceFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- }
- break;
- case NsdManager.NATIVE_DAEMON_EVENT:
- NativeEvent event = (NativeEvent) msg.obj;
- if (!handleNativeEvent(event.code, event.raw, event.cooked)) {
- return NOT_HANDLED;
- }
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
-
- private boolean handleNativeEvent(int code, String raw, String[] cooked) {
- NsdServiceInfo servInfo;
- int id = Integer.parseInt(cooked[1]);
- ClientInfo clientInfo = mIdToClientInfoMap.get(id);
- if (clientInfo == null) {
- String name = NativeResponseCode.nameOf(code);
- Log.e(TAG, String.format("id %d for %s has no client mapping", id, name));
- return false;
- }
-
- /* This goes in response as msg.arg2 */
- int clientId = clientInfo.getClientId(id);
- if (clientId < 0) {
- // This can happen because of race conditions. For example,
- // SERVICE_FOUND may race with STOP_SERVICE_DISCOVERY,
- // and we may get in this situation.
- String name = NativeResponseCode.nameOf(code);
- Log.d(TAG, String.format(
- "Notification %s for listener id %d that is no longer active",
- name, id));
- return false;
- }
- if (DBG) {
- String name = NativeResponseCode.nameOf(code);
- Log.d(TAG, String.format("Native daemon message %s: %s", name, raw));
- }
- switch (code) {
- case NativeResponseCode.SERVICE_FOUND:
- /* NNN uniqueId serviceName regType domain interfaceIdx netId */
- servInfo = new NsdServiceInfo(cooked[2], cooked[3]);
- final int foundNetId;
- try {
- foundNetId = Integer.parseInt(cooked[6]);
- } catch (NumberFormatException e) {
- Log.wtf(TAG, "Invalid network received from mdnsd: " + cooked[6]);
- break;
- }
- if (foundNetId == 0L) {
- // Ignore services that do not have a Network: they are not usable
- // by apps, as they would need privileged permissions to use
- // interfaces that do not have an associated Network.
- break;
- }
- servInfo.setNetwork(new Network(foundNetId));
- clientInfo.onServiceFound(clientId, servInfo);
- break;
- case NativeResponseCode.SERVICE_LOST:
- /* NNN uniqueId serviceName regType domain interfaceIdx netId */
- final int lostNetId;
- try {
- lostNetId = Integer.parseInt(cooked[6]);
- } catch (NumberFormatException e) {
- Log.wtf(TAG, "Invalid network received from mdnsd: " + cooked[6]);
- break;
- }
- servInfo = new NsdServiceInfo(cooked[2], cooked[3]);
- // The network could be null if it was torn down when the service is lost
- // TODO: avoid returning null in that case, possibly by remembering found
- // services on the same interface index and their network at the time
- servInfo.setNetwork(lostNetId == 0 ? null : new Network(lostNetId));
- clientInfo.onServiceLost(clientId, servInfo);
- break;
- case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
- /* NNN uniqueId errorCode */
- clientInfo.onDiscoverServicesFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- break;
- case NativeResponseCode.SERVICE_REGISTERED:
- /* NNN regId serviceName regType */
- servInfo = new NsdServiceInfo(cooked[2], null);
- clientInfo.onRegisterServiceSucceeded(clientId, servInfo);
- break;
- case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
- /* NNN regId errorCode */
- clientInfo.onRegisterServiceFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- break;
- case NativeResponseCode.SERVICE_UPDATED:
- /* NNN regId */
- break;
- case NativeResponseCode.SERVICE_UPDATE_FAILED:
- /* NNN regId errorCode */
- break;
- case NativeResponseCode.SERVICE_RESOLVED:
- /* NNN resolveId fullName hostName port txtlen txtdata interfaceIdx */
- int index = 0;
- while (index < cooked[2].length() && cooked[2].charAt(index) != '.') {
- if (cooked[2].charAt(index) == '\\') {
- ++index;
- }
- ++index;
- }
- if (index >= cooked[2].length()) {
- Log.e(TAG, "Invalid service found " + raw);
- break;
- }
-
- String name = cooked[2].substring(0, index);
- String rest = cooked[2].substring(index);
- String type = rest.replace(".local.", "");
-
- name = unescape(name);
-
- clientInfo.mResolvedService.setServiceName(name);
- clientInfo.mResolvedService.setServiceType(type);
- clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
- clientInfo.mResolvedService.setTxtRecords(cooked[6]);
- // Network will be added after SERVICE_GET_ADDR_SUCCESS
-
- stopResolveService(id);
- removeRequestMap(clientId, id, clientInfo);
-
- int id2 = getUniqueId();
- if (getAddrInfo(id2, cooked[3], cooked[7] /* interfaceIdx */)) {
- storeRequestMap(clientId, id2, clientInfo, NsdManager.RESOLVE_SERVICE);
- } else {
- clientInfo.onResolveServiceFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- clientInfo.mResolvedService = null;
- }
- break;
- case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
- /* NNN resolveId errorCode */
- stopResolveService(id);
- removeRequestMap(clientId, id, clientInfo);
- clientInfo.mResolvedService = null;
- clientInfo.onResolveServiceFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- break;
- case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
- /* NNN resolveId errorCode */
- stopGetAddrInfo(id);
- removeRequestMap(clientId, id, clientInfo);
- clientInfo.mResolvedService = null;
- clientInfo.onResolveServiceFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- break;
- case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
- /* NNN resolveId hostname ttl addr interfaceIdx netId */
- Network network = null;
- try {
- final int netId = Integer.parseInt(cooked[6]);
- network = netId == 0L ? null : new Network(netId);
- } catch (NumberFormatException e) {
- Log.wtf(TAG, "Invalid network in GET_ADDR_SUCCESS: " + cooked[6], e);
- }
-
- InetAddress serviceHost = null;
- try {
- serviceHost = InetAddress.getByName(cooked[4]);
- } catch (UnknownHostException e) {
- Log.wtf(TAG, "Invalid host in GET_ADDR_SUCCESS", e);
- }
-
- // If the resolved service is on an interface without a network, consider it
- // as a failure: it would not be usable by apps as they would need
- // privileged permissions.
- if (network != null && serviceHost != null) {
- clientInfo.mResolvedService.setHost(serviceHost);
- clientInfo.mResolvedService.setNetwork(network);
- clientInfo.onResolveServiceSucceeded(
- clientId, clientInfo.mResolvedService);
- } else {
- clientInfo.onResolveServiceFailed(
- clientId, NsdManager.FAILURE_INTERNAL_ERROR);
- }
- stopGetAddrInfo(id);
- removeRequestMap(clientId, id, clientInfo);
- clientInfo.mResolvedService = null;
- break;
- default:
- return false;
- }
- return true;
- }
- }
- }
-
- private String unescape(String s) {
- StringBuilder sb = new StringBuilder(s.length());
- for (int i = 0; i < s.length(); ++i) {
- char c = s.charAt(i);
- if (c == '\\') {
- if (++i >= s.length()) {
- Log.e(TAG, "Unexpected end of escape sequence in: " + s);
- break;
- }
- c = s.charAt(i);
- if (c != '.' && c != '\\') {
- if (i + 2 >= s.length()) {
- Log.e(TAG, "Unexpected end of escape sequence in: " + s);
- break;
- }
- c = (char) ((c-'0') * 100 + (s.charAt(i+1)-'0') * 10 + (s.charAt(i+2)-'0'));
- i += 2;
- }
- }
- sb.append(c);
- }
- return sb.toString();
- }
-
- @VisibleForTesting
- NsdService(Context ctx, Handler handler, DaemonConnectionSupplier fn, long cleanupDelayMs) {
- mCleanupDelayMs = cleanupDelayMs;
- mContext = ctx;
- mNsdStateMachine = new NsdStateMachine(TAG, handler);
- mNsdStateMachine.start();
- mDaemonCallback = new NativeCallbackReceiver();
- mDaemon = fn.get(mDaemonCallback);
- }
-
- public static NsdService create(Context context) throws InterruptedException {
- HandlerThread thread = new HandlerThread(TAG);
- thread.start();
- Handler handler = new Handler(thread.getLooper());
- NsdService service =
- new NsdService(context, handler, DaemonConnection::new, CLEANUP_DELAY_MS);
- service.mDaemonCallback.awaitConnection();
- return service;
- }
-
- @Override
- public INsdServiceConnector connect(INsdManagerCallback cb) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET, "NsdService");
- final INsdServiceConnector connector = new NsdServiceConnector();
- mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
- NsdManager.REGISTER_CLIENT, new Pair<>(connector, cb)));
- return connector;
- }
-
- private static class ListenerArgs {
- public final NsdServiceConnector connector;
- public final NsdServiceInfo serviceInfo;
- ListenerArgs(NsdServiceConnector connector, NsdServiceInfo serviceInfo) {
- this.connector = connector;
- this.serviceInfo = serviceInfo;
- }
- }
-
- private class NsdServiceConnector extends INsdServiceConnector.Stub
- implements IBinder.DeathRecipient {
- @Override
- public void registerService(int listenerKey, NsdServiceInfo serviceInfo) {
- mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
- NsdManager.REGISTER_SERVICE, 0, listenerKey,
- new ListenerArgs(this, serviceInfo)));
- }
-
- @Override
- public void unregisterService(int listenerKey) {
- mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
- NsdManager.UNREGISTER_SERVICE, 0, listenerKey,
- new ListenerArgs(this, null)));
- }
-
- @Override
- public void discoverServices(int listenerKey, NsdServiceInfo serviceInfo) {
- mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
- NsdManager.DISCOVER_SERVICES, 0, listenerKey,
- new ListenerArgs(this, serviceInfo)));
- }
-
- @Override
- public void stopDiscovery(int listenerKey) {
- mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
- NsdManager.STOP_DISCOVERY, 0, listenerKey, new ListenerArgs(this, null)));
- }
-
- @Override
- public void resolveService(int listenerKey, NsdServiceInfo serviceInfo) {
- mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
- NsdManager.RESOLVE_SERVICE, 0, listenerKey,
- new ListenerArgs(this, serviceInfo)));
- }
-
- @Override
- public void startDaemon() {
- mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(
- NsdManager.DAEMON_STARTUP, new ListenerArgs(this, null)));
- }
-
- @Override
- public void binderDied() {
- mNsdStateMachine.sendMessage(
- mNsdStateMachine.obtainMessage(NsdManager.UNREGISTER_CLIENT, this));
- }
- }
-
- private void sendNsdStateChangeBroadcast(boolean isEnabled) {
- final Intent intent = new Intent(NsdManager.ACTION_NSD_STATE_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- int nsdState = isEnabled ? NsdManager.NSD_STATE_ENABLED : NsdManager.NSD_STATE_DISABLED;
- intent.putExtra(NsdManager.EXTRA_NSD_STATE, nsdState);
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
-
- private int getUniqueId() {
- if (++mUniqueId == INVALID_ID) return ++mUniqueId;
- return mUniqueId;
- }
-
- /* These should be in sync with system/netd/server/ResponseCode.h */
- static final class NativeResponseCode {
- public static final int SERVICE_DISCOVERY_FAILED = 602;
- public static final int SERVICE_FOUND = 603;
- public static final int SERVICE_LOST = 604;
-
- public static final int SERVICE_REGISTRATION_FAILED = 605;
- public static final int SERVICE_REGISTERED = 606;
-
- public static final int SERVICE_RESOLUTION_FAILED = 607;
- public static final int SERVICE_RESOLVED = 608;
-
- public static final int SERVICE_UPDATED = 609;
- public static final int SERVICE_UPDATE_FAILED = 610;
-
- public static final int SERVICE_GET_ADDR_FAILED = 611;
- public static final int SERVICE_GET_ADDR_SUCCESS = 612;
-
- private static final SparseArray<String> CODE_NAMES = new SparseArray<>();
- static {
- CODE_NAMES.put(SERVICE_DISCOVERY_FAILED, "SERVICE_DISCOVERY_FAILED");
- CODE_NAMES.put(SERVICE_FOUND, "SERVICE_FOUND");
- CODE_NAMES.put(SERVICE_LOST, "SERVICE_LOST");
- CODE_NAMES.put(SERVICE_REGISTRATION_FAILED, "SERVICE_REGISTRATION_FAILED");
- CODE_NAMES.put(SERVICE_REGISTERED, "SERVICE_REGISTERED");
- CODE_NAMES.put(SERVICE_RESOLUTION_FAILED, "SERVICE_RESOLUTION_FAILED");
- CODE_NAMES.put(SERVICE_RESOLVED, "SERVICE_RESOLVED");
- CODE_NAMES.put(SERVICE_UPDATED, "SERVICE_UPDATED");
- CODE_NAMES.put(SERVICE_UPDATE_FAILED, "SERVICE_UPDATE_FAILED");
- CODE_NAMES.put(SERVICE_GET_ADDR_FAILED, "SERVICE_GET_ADDR_FAILED");
- CODE_NAMES.put(SERVICE_GET_ADDR_SUCCESS, "SERVICE_GET_ADDR_SUCCESS");
- }
-
- static String nameOf(int code) {
- String name = CODE_NAMES.get(code);
- if (name == null) {
- return Integer.toString(code);
- }
- return name;
- }
- }
-
- private class NativeEvent {
- final int code;
- final String raw;
- final String[] cooked;
-
- NativeEvent(int code, String raw, String[] cooked) {
- this.code = code;
- this.raw = raw;
- this.cooked = cooked;
- }
- }
-
- class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
- private final CountDownLatch connected = new CountDownLatch(1);
-
- public void awaitConnection() throws InterruptedException {
- connected.await();
- }
-
- @Override
- public void onDaemonConnected() {
- connected.countDown();
- }
-
- @Override
- public boolean onCheckHoldWakeLock(int code) {
- return false;
- }
-
- @Override
- public boolean onEvent(int code, String raw, String[] cooked) {
- // TODO: NDC translates a message to a callback, we could enhance NDC to
- // directly interact with a state machine through messages
- NativeEvent event = new NativeEvent(code, raw, cooked);
- mNsdStateMachine.sendMessage(NsdManager.NATIVE_DAEMON_EVENT, event);
- return true;
- }
- }
-
- interface DaemonConnectionSupplier {
- DaemonConnection get(NativeCallbackReceiver callback);
- }
-
- @VisibleForTesting
- public static class DaemonConnection {
- final NativeDaemonConnector mNativeConnector;
- boolean mIsStarted = false;
-
- DaemonConnection(NativeCallbackReceiver callback) {
- mNativeConnector = new NativeDaemonConnector(callback, "mdns", 10, MDNS_TAG, 25, null);
- new Thread(mNativeConnector, MDNS_TAG).start();
- }
-
- /**
- * Executes the specified cmd on the daemon.
- */
- public boolean execute(Object... args) {
- if (DBG) {
- Log.d(TAG, "mdnssd " + Arrays.toString(args));
- }
- try {
- mNativeConnector.execute("mdnssd", args);
- } catch (NativeDaemonConnectorException e) {
- Log.e(TAG, "Failed to execute mdnssd " + Arrays.toString(args), e);
- return false;
- }
- return true;
- }
-
- /**
- * Starts the daemon if it is not already started.
- */
- public void maybeStart() {
- if (mIsStarted) {
- return;
- }
- execute("start-service");
- mIsStarted = true;
- }
-
- /**
- * Stops the daemon if it is started.
- */
- public void maybeStop() {
- if (!mIsStarted) {
- return;
- }
- execute("stop-service");
- mIsStarted = false;
- }
- }
-
- private boolean registerService(int regId, NsdServiceInfo service) {
- if (DBG) {
- Log.d(TAG, "registerService: " + regId + " " + service);
- }
- String name = service.getServiceName();
- String type = service.getServiceType();
- int port = service.getPort();
- byte[] textRecord = service.getTxtRecord();
- String record = Base64.encodeToString(textRecord, Base64.DEFAULT).replace("\n", "");
- return mDaemon.execute("register", regId, name, type, port, record);
- }
-
- private boolean unregisterService(int regId) {
- return mDaemon.execute("stop-register", regId);
- }
-
- private boolean updateService(int regId, DnsSdTxtRecord t) {
- if (t == null) {
- return false;
- }
- return mDaemon.execute("update", regId, t.size(), t.getRawData());
- }
-
- private boolean discoverServices(int discoveryId, NsdServiceInfo serviceInfo) {
- final Network network = serviceInfo.getNetwork();
- final int discoverInterface = getNetworkInterfaceIndex(network);
- if (network != null && discoverInterface == IFACE_IDX_ANY) {
- Log.e(TAG, "Interface to discover service on not found");
- return false;
- }
- return mDaemon.execute("discover", discoveryId, serviceInfo.getServiceType(),
- discoverInterface);
- }
-
- private boolean stopServiceDiscovery(int discoveryId) {
- return mDaemon.execute("stop-discover", discoveryId);
- }
-
- private boolean resolveService(int resolveId, NsdServiceInfo service) {
- final String name = service.getServiceName();
- final String type = service.getServiceType();
- final Network network = service.getNetwork();
- final int resolveInterface = getNetworkInterfaceIndex(network);
- if (network != null && resolveInterface == IFACE_IDX_ANY) {
- Log.e(TAG, "Interface to resolve service on not found");
- return false;
- }
- return mDaemon.execute("resolve", resolveId, name, type, "local.", resolveInterface);
- }
-
- /**
- * Guess the interface to use to resolve or discover a service on a specific network.
- *
- * This is an imperfect guess, as for example the network may be gone or not yet fully
- * registered. This is fine as failing is correct if the network is gone, and a client
- * attempting to resolve/discover on a network not yet setup would have a bad time anyway; also
- * this is to support the legacy mdnsresponder implementation, which historically resolved
- * services on an unspecified network.
- */
- private int getNetworkInterfaceIndex(Network network) {
- if (network == null) return IFACE_IDX_ANY;
-
- final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
- if (cm == null) {
- Log.wtf(TAG, "No ConnectivityManager for resolveService");
- return IFACE_IDX_ANY;
- }
- final LinkProperties lp = cm.getLinkProperties(network);
- if (lp == null) return IFACE_IDX_ANY;
-
- // Only resolve on non-stacked interfaces
- final NetworkInterface iface;
- try {
- iface = NetworkInterface.getByName(lp.getInterfaceName());
- } catch (SocketException e) {
- Log.e(TAG, "Error querying interface", e);
- return IFACE_IDX_ANY;
- }
-
- if (iface == null) {
- Log.e(TAG, "Interface not found: " + lp.getInterfaceName());
- return IFACE_IDX_ANY;
- }
-
- return iface.getIndex();
- }
-
- private boolean stopResolveService(int resolveId) {
- return mDaemon.execute("stop-resolve", resolveId);
- }
-
- private boolean getAddrInfo(int resolveId, String hostname, String interfaceIdx) {
- // interfaceIdx is always obtained (as string) from the service resolved callback
- return mDaemon.execute("getaddrinfo", resolveId, hostname, interfaceIdx);
- }
-
- private boolean stopGetAddrInfo(int resolveId) {
- return mDaemon.execute("stop-getaddrinfo", resolveId);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump " + TAG
- + " due to missing android.permission.DUMP permission");
- return;
- }
-
- for (ClientInfo client : mClients.values()) {
- pw.println("Client Info");
- pw.println(client);
- }
-
- mNsdStateMachine.dump(fd, pw, args);
- }
-
- /* Information tracked per client */
- private class ClientInfo {
-
- private static final int MAX_LIMIT = 10;
- private final INsdManagerCallback mCb;
- /* Remembers a resolved service until getaddrinfo completes */
- private NsdServiceInfo mResolvedService;
-
- /* A map from client id to unique id sent to mDns */
- private final SparseIntArray mClientIds = new SparseIntArray();
-
- /* A map from client id to the type of the request we had received */
- private final SparseIntArray mClientRequests = new SparseIntArray();
-
- // The target SDK of this client < Build.VERSION_CODES.S
- private boolean mIsLegacy = false;
-
- private ClientInfo(INsdManagerCallback cb) {
- mCb = cb;
- if (DBG) Log.d(TAG, "New client");
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("mResolvedService ").append(mResolvedService).append("\n");
- sb.append("mIsLegacy ").append(mIsLegacy).append("\n");
- for(int i = 0; i< mClientIds.size(); i++) {
- int clientID = mClientIds.keyAt(i);
- sb.append("clientId ").append(clientID).
- append(" mDnsId ").append(mClientIds.valueAt(i)).
- append(" type ").append(mClientRequests.get(clientID)).append("\n");
- }
- return sb.toString();
- }
-
- private boolean isLegacy() {
- return mIsLegacy;
- }
-
- private void setLegacy() {
- mIsLegacy = true;
- }
-
- // Remove any pending requests from the global map when we get rid of a client,
- // and send cancellations to the daemon.
- private void expungeAllRequests() {
- int globalId, clientId, i;
- // TODO: to keep handler responsive, do not clean all requests for that client at once.
- for (i = 0; i < mClientIds.size(); i++) {
- clientId = mClientIds.keyAt(i);
- globalId = mClientIds.valueAt(i);
- mIdToClientInfoMap.remove(globalId);
- if (DBG) {
- Log.d(TAG, "Terminating client-ID " + clientId
- + " global-ID " + globalId + " type " + mClientRequests.get(clientId));
- }
- switch (mClientRequests.get(clientId)) {
- case NsdManager.DISCOVER_SERVICES:
- stopServiceDiscovery(globalId);
- break;
- case NsdManager.RESOLVE_SERVICE:
- stopResolveService(globalId);
- break;
- case NsdManager.REGISTER_SERVICE:
- unregisterService(globalId);
- break;
- default:
- break;
- }
- }
- mClientIds.clear();
- mClientRequests.clear();
- }
-
- // mClientIds is a sparse array of listener id -> mDnsClient id. For a given mDnsClient id,
- // return the corresponding listener id. mDnsClient id is also called a global id.
- private int getClientId(final int globalId) {
- int idx = mClientIds.indexOfValue(globalId);
- if (idx < 0) {
- return idx;
- }
- return mClientIds.keyAt(idx);
- }
-
- void onDiscoverServicesStarted(int listenerKey, NsdServiceInfo info) {
- try {
- mCb.onDiscoverServicesStarted(listenerKey, info);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onDiscoverServicesStarted", e);
- }
- }
-
- void onDiscoverServicesFailed(int listenerKey, int error) {
- try {
- mCb.onDiscoverServicesFailed(listenerKey, error);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onDiscoverServicesFailed", e);
- }
- }
-
- void onServiceFound(int listenerKey, NsdServiceInfo info) {
- try {
- mCb.onServiceFound(listenerKey, info);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onServiceFound(", e);
- }
- }
-
- void onServiceLost(int listenerKey, NsdServiceInfo info) {
- try {
- mCb.onServiceLost(listenerKey, info);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onServiceLost(", e);
- }
- }
-
- void onStopDiscoveryFailed(int listenerKey, int error) {
- try {
- mCb.onStopDiscoveryFailed(listenerKey, error);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onStopDiscoveryFailed", e);
- }
- }
-
- void onStopDiscoverySucceeded(int listenerKey) {
- try {
- mCb.onStopDiscoverySucceeded(listenerKey);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onStopDiscoverySucceeded", e);
- }
- }
-
- void onRegisterServiceFailed(int listenerKey, int error) {
- try {
- mCb.onRegisterServiceFailed(listenerKey, error);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onRegisterServiceFailed", e);
- }
- }
-
- void onRegisterServiceSucceeded(int listenerKey, NsdServiceInfo info) {
- try {
- mCb.onRegisterServiceSucceeded(listenerKey, info);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onRegisterServiceSucceeded", e);
- }
- }
-
- void onUnregisterServiceFailed(int listenerKey, int error) {
- try {
- mCb.onUnregisterServiceFailed(listenerKey, error);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onUnregisterServiceFailed", e);
- }
- }
-
- void onUnregisterServiceSucceeded(int listenerKey) {
- try {
- mCb.onUnregisterServiceSucceeded(listenerKey);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onUnregisterServiceSucceeded", e);
- }
- }
-
- void onResolveServiceFailed(int listenerKey, int error) {
- try {
- mCb.onResolveServiceFailed(listenerKey, error);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onResolveServiceFailed", e);
- }
- }
-
- void onResolveServiceSucceeded(int listenerKey, NsdServiceInfo info) {
- try {
- mCb.onResolveServiceSucceeded(listenerKey, info);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling onResolveServiceSucceeded", e);
- }
- }
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/BpfInterfaceMapUpdater.java b/packages/ConnectivityT/service/src/com/android/server/net/BpfInterfaceMapUpdater.java
deleted file mode 100644
index 25c88eb..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/BpfInterfaceMapUpdater.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.net;
-
-import android.content.Context;
-import android.net.INetd;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.system.ErrnoException;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
-import com.android.net.module.util.BpfMap;
-import com.android.net.module.util.IBpfMap;
-import com.android.net.module.util.InterfaceParams;
-import com.android.net.module.util.Struct.U32;
-
-/**
- * Monitor interface added (without removed) and right interface name and its index to bpf map.
- */
-public class BpfInterfaceMapUpdater {
- private static final String TAG = BpfInterfaceMapUpdater.class.getSimpleName();
- // This is current path but may be changed soon.
- private static final String IFACE_INDEX_NAME_MAP_PATH =
- "/sys/fs/bpf/map_netd_iface_index_name_map";
- private final IBpfMap<U32, InterfaceMapValue> mBpfMap;
- private final INetd mNetd;
- private final Handler mHandler;
- private final Dependencies mDeps;
-
- public BpfInterfaceMapUpdater(Context ctx, Handler handler) {
- this(ctx, handler, new Dependencies());
- }
-
- @VisibleForTesting
- public BpfInterfaceMapUpdater(Context ctx, Handler handler, Dependencies deps) {
- mDeps = deps;
- mBpfMap = deps.getInterfaceMap();
- mNetd = deps.getINetd(ctx);
- mHandler = handler;
- }
-
- /**
- * Dependencies of BpfInerfaceMapUpdater, for injection in tests.
- */
- @VisibleForTesting
- public static class Dependencies {
- /** Create BpfMap for updating interface and index mapping. */
- public IBpfMap<U32, InterfaceMapValue> getInterfaceMap() {
- try {
- return new BpfMap<>(IFACE_INDEX_NAME_MAP_PATH, BpfMap.BPF_F_RDWR,
- U32.class, InterfaceMapValue.class);
- } catch (ErrnoException e) {
- Log.e(TAG, "Cannot create interface map: " + e);
- return null;
- }
- }
-
- /** Get InterfaceParams for giving interface name. */
- public InterfaceParams getInterfaceParams(String ifaceName) {
- return InterfaceParams.getByName(ifaceName);
- }
-
- /** Get INetd binder object. */
- public INetd getINetd(Context ctx) {
- return INetd.Stub.asInterface((IBinder) ctx.getSystemService(Context.NETD_SERVICE));
- }
- }
-
- /**
- * Start listening interface update event.
- * Query current interface names before listening.
- */
- public void start() {
- mHandler.post(() -> {
- if (mBpfMap == null) {
- Log.wtf(TAG, "Fail to start: Null bpf map");
- return;
- }
-
- try {
- // TODO: use a NetlinkMonitor and listen for RTM_NEWLINK messages instead.
- mNetd.registerUnsolicitedEventListener(new InterfaceChangeObserver());
- } catch (RemoteException e) {
- Log.wtf(TAG, "Unable to register netd UnsolicitedEventListener, " + e);
- }
-
- final String[] ifaces;
- try {
- // TODO: use a netlink dump to get the current interface list.
- ifaces = mNetd.interfaceGetList();
- } catch (RemoteException | ServiceSpecificException e) {
- Log.wtf(TAG, "Unable to query interface names by netd, " + e);
- return;
- }
-
- for (String ifaceName : ifaces) {
- addInterface(ifaceName);
- }
- });
- }
-
- private void addInterface(String ifaceName) {
- final InterfaceParams iface = mDeps.getInterfaceParams(ifaceName);
- if (iface == null) {
- Log.e(TAG, "Unable to get InterfaceParams for " + ifaceName);
- return;
- }
-
- try {
- mBpfMap.updateEntry(new U32(iface.index), new InterfaceMapValue(ifaceName));
- } catch (ErrnoException e) {
- Log.e(TAG, "Unable to update entry for " + ifaceName + ", " + e);
- }
- }
-
- private class InterfaceChangeObserver extends BaseNetdUnsolicitedEventListener {
- @Override
- public void onInterfaceAdded(String ifName) {
- mHandler.post(() -> addInterface(ifName));
- }
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/CookieTagMapKey.java b/packages/ConnectivityT/service/src/com/android/server/net/CookieTagMapKey.java
deleted file mode 100644
index 443e5b3..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/CookieTagMapKey.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.net;
-
-import com.android.net.module.util.Struct;
-import com.android.net.module.util.Struct.Field;
-import com.android.net.module.util.Struct.Type;
-
-/**
- * Key for cookie tag map.
- */
-public class CookieTagMapKey extends Struct {
- @Field(order = 0, type = Type.S64)
- public final long socketCookie;
-
- public CookieTagMapKey(final long socketCookie) {
- this.socketCookie = socketCookie;
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/CookieTagMapValue.java b/packages/ConnectivityT/service/src/com/android/server/net/CookieTagMapValue.java
deleted file mode 100644
index 93b9195..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/CookieTagMapValue.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.net;
-
-import com.android.net.module.util.Struct;
-import com.android.net.module.util.Struct.Field;
-import com.android.net.module.util.Struct.Type;
-
-/**
- * Value for cookie tag map.
- */
-public class CookieTagMapValue extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long uid;
-
- @Field(order = 1, type = Type.U32)
- public final long tag;
-
- public CookieTagMapValue(final long uid, final long tag) {
- this.uid = uid;
- this.tag = tag;
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/DelayedDiskWrite.java b/packages/ConnectivityT/service/src/com/android/server/net/DelayedDiskWrite.java
deleted file mode 100644
index 35dc455..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/DelayedDiskWrite.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2014 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.net;
-
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.BufferedOutputStream;
-import java.io.DataOutputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-/**
- * This class provides APIs to do a delayed data write to a given {@link OutputStream}.
- */
-public class DelayedDiskWrite {
- private static final String TAG = "DelayedDiskWrite";
-
- private HandlerThread mDiskWriteHandlerThread;
- private Handler mDiskWriteHandler;
- /* Tracks multiple writes on the same thread */
- private int mWriteSequence = 0;
-
- /**
- * Used to do a delayed data write to a given {@link OutputStream}.
- */
- public interface Writer {
- /**
- * write data to a given {@link OutputStream}.
- */
- void onWriteCalled(DataOutputStream out) throws IOException;
- }
-
- /**
- * Do a delayed data write to a given output stream opened from filePath.
- */
- public void write(final String filePath, final Writer w) {
- write(filePath, w, true);
- }
-
- /**
- * Do a delayed data write to a given output stream opened from filePath.
- */
- public void write(final String filePath, final Writer w, final boolean open) {
- if (TextUtils.isEmpty(filePath)) {
- throw new IllegalArgumentException("empty file path");
- }
-
- /* Do a delayed write to disk on a separate handler thread */
- synchronized (this) {
- if (++mWriteSequence == 1) {
- mDiskWriteHandlerThread = new HandlerThread("DelayedDiskWriteThread");
- mDiskWriteHandlerThread.start();
- mDiskWriteHandler = new Handler(mDiskWriteHandlerThread.getLooper());
- }
- }
-
- mDiskWriteHandler.post(new Runnable() {
- @Override
- public void run() {
- doWrite(filePath, w, open);
- }
- });
- }
-
- private void doWrite(String filePath, Writer w, boolean open) {
- DataOutputStream out = null;
- try {
- if (open) {
- out = new DataOutputStream(new BufferedOutputStream(
- new FileOutputStream(filePath)));
- }
- w.onWriteCalled(out);
- } catch (IOException e) {
- loge("Error writing data file " + filePath);
- } finally {
- if (out != null) {
- try {
- out.close();
- } catch (Exception e) { }
- }
-
- // Quit if no more writes sent
- synchronized (this) {
- if (--mWriteSequence == 0) {
- mDiskWriteHandler.getLooper().quit();
- mDiskWriteHandler = null;
- mDiskWriteHandlerThread = null;
- }
- }
- }
- }
-
- private void loge(String s) {
- Log.e(TAG, s);
- }
-}
-
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/InterfaceMapValue.java b/packages/ConnectivityT/service/src/com/android/server/net/InterfaceMapValue.java
deleted file mode 100644
index 42c0044..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/InterfaceMapValue.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.net;
-
-import com.android.net.module.util.Struct;
-import com.android.net.module.util.Struct.Field;
-import com.android.net.module.util.Struct.Type;
-
-/**
- * The value of bpf interface index map which is used for NetworkStatsService.
- */
-public class InterfaceMapValue extends Struct {
- @Field(order = 0, type = Type.ByteArray, arraysize = 16)
- public final byte[] interfaceName;
-
- public InterfaceMapValue(String iface) {
- final byte[] ifaceArray = iface.getBytes();
- interfaceName = new byte[16];
- // All array bytes after the interface name, if any, must be 0.
- System.arraycopy(ifaceArray, 0, interfaceName, 0, ifaceArray.length);
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/IpConfigStore.java b/packages/ConnectivityT/service/src/com/android/server/net/IpConfigStore.java
deleted file mode 100644
index 3a9a544..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/IpConfigStore.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2014 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.net;
-
-import android.net.InetAddresses;
-import android.net.IpConfiguration;
-import android.net.IpConfiguration.IpAssignment;
-import android.net.IpConfiguration.ProxySettings;
-import android.net.LinkAddress;
-import android.net.ProxyInfo;
-import android.net.StaticIpConfiguration;
-import android.net.Uri;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.net.module.util.ProxyUtils;
-
-import java.io.BufferedInputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class provides an API to store and manage L3 network IP configuration.
- */
-public class IpConfigStore {
- private static final String TAG = "IpConfigStore";
- private static final boolean DBG = false;
-
- protected final DelayedDiskWrite mWriter;
-
- /* IP and proxy configuration keys */
- protected static final String ID_KEY = "id";
- protected static final String IP_ASSIGNMENT_KEY = "ipAssignment";
- protected static final String LINK_ADDRESS_KEY = "linkAddress";
- protected static final String GATEWAY_KEY = "gateway";
- protected static final String DNS_KEY = "dns";
- protected static final String PROXY_SETTINGS_KEY = "proxySettings";
- protected static final String PROXY_HOST_KEY = "proxyHost";
- protected static final String PROXY_PORT_KEY = "proxyPort";
- protected static final String PROXY_PAC_FILE = "proxyPac";
- protected static final String EXCLUSION_LIST_KEY = "exclusionList";
- protected static final String EOS = "eos";
-
- protected static final int IPCONFIG_FILE_VERSION = 3;
-
- public IpConfigStore(DelayedDiskWrite writer) {
- mWriter = writer;
- }
-
- public IpConfigStore() {
- this(new DelayedDiskWrite());
- }
-
- private static boolean writeConfig(DataOutputStream out, String configKey,
- IpConfiguration config) throws IOException {
- return writeConfig(out, configKey, config, IPCONFIG_FILE_VERSION);
- }
-
- /**
- * Write the IP configuration with the given parameters to {@link DataOutputStream}.
- */
- @VisibleForTesting
- public static boolean writeConfig(DataOutputStream out, String configKey,
- IpConfiguration config, int version) throws IOException {
- boolean written = false;
-
- try {
- switch (config.getIpAssignment()) {
- case STATIC:
- out.writeUTF(IP_ASSIGNMENT_KEY);
- out.writeUTF(config.getIpAssignment().toString());
- StaticIpConfiguration staticIpConfiguration = config.getStaticIpConfiguration();
- if (staticIpConfiguration != null) {
- if (staticIpConfiguration.getIpAddress() != null) {
- LinkAddress ipAddress = staticIpConfiguration.getIpAddress();
- out.writeUTF(LINK_ADDRESS_KEY);
- out.writeUTF(ipAddress.getAddress().getHostAddress());
- out.writeInt(ipAddress.getPrefixLength());
- }
- if (staticIpConfiguration.getGateway() != null) {
- out.writeUTF(GATEWAY_KEY);
- out.writeInt(0); // Default route.
- out.writeInt(1); // Have a gateway.
- out.writeUTF(staticIpConfiguration.getGateway().getHostAddress());
- }
- for (InetAddress inetAddr : staticIpConfiguration.getDnsServers()) {
- out.writeUTF(DNS_KEY);
- out.writeUTF(inetAddr.getHostAddress());
- }
- }
- written = true;
- break;
- case DHCP:
- out.writeUTF(IP_ASSIGNMENT_KEY);
- out.writeUTF(config.getIpAssignment().toString());
- written = true;
- break;
- case UNASSIGNED:
- /* Ignore */
- break;
- default:
- loge("Ignore invalid ip assignment while writing");
- break;
- }
-
- switch (config.getProxySettings()) {
- case STATIC:
- ProxyInfo proxyProperties = config.getHttpProxy();
- String exclusionList = ProxyUtils.exclusionListAsString(
- proxyProperties.getExclusionList());
- out.writeUTF(PROXY_SETTINGS_KEY);
- out.writeUTF(config.getProxySettings().toString());
- out.writeUTF(PROXY_HOST_KEY);
- out.writeUTF(proxyProperties.getHost());
- out.writeUTF(PROXY_PORT_KEY);
- out.writeInt(proxyProperties.getPort());
- if (exclusionList != null) {
- out.writeUTF(EXCLUSION_LIST_KEY);
- out.writeUTF(exclusionList);
- }
- written = true;
- break;
- case PAC:
- ProxyInfo proxyPacProperties = config.getHttpProxy();
- out.writeUTF(PROXY_SETTINGS_KEY);
- out.writeUTF(config.getProxySettings().toString());
- out.writeUTF(PROXY_PAC_FILE);
- out.writeUTF(proxyPacProperties.getPacFileUrl().toString());
- written = true;
- break;
- case NONE:
- out.writeUTF(PROXY_SETTINGS_KEY);
- out.writeUTF(config.getProxySettings().toString());
- written = true;
- break;
- case UNASSIGNED:
- /* Ignore */
- break;
- default:
- loge("Ignore invalid proxy settings while writing");
- break;
- }
-
- if (written) {
- out.writeUTF(ID_KEY);
- if (version < 3) {
- out.writeInt(Integer.valueOf(configKey));
- } else {
- out.writeUTF(configKey);
- }
- }
- } catch (NullPointerException e) {
- loge("Failure in writing " + config + e);
- }
- out.writeUTF(EOS);
-
- return written;
- }
-
- /**
- * @deprecated use {@link #writeIpConfigurations(String, ArrayMap)} instead.
- * New method uses string as network identifier which could be interface name or MAC address or
- * other token.
- */
- @Deprecated
- public void writeIpAndProxyConfigurationsToFile(String filePath,
- final SparseArray<IpConfiguration> networks) {
- mWriter.write(filePath, out -> {
- out.writeInt(IPCONFIG_FILE_VERSION);
- for (int i = 0; i < networks.size(); i++) {
- writeConfig(out, String.valueOf(networks.keyAt(i)), networks.valueAt(i));
- }
- });
- }
-
- /**
- * Write the IP configuration associated to the target networks to the destination path.
- */
- public void writeIpConfigurations(String filePath,
- ArrayMap<String, IpConfiguration> networks) {
- mWriter.write(filePath, out -> {
- out.writeInt(IPCONFIG_FILE_VERSION);
- for (int i = 0; i < networks.size(); i++) {
- writeConfig(out, networks.keyAt(i), networks.valueAt(i));
- }
- });
- }
-
- /**
- * Read the IP configuration from the destination path to {@link BufferedInputStream}.
- */
- public static ArrayMap<String, IpConfiguration> readIpConfigurations(String filePath) {
- BufferedInputStream bufferedInputStream;
- try {
- bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
- } catch (FileNotFoundException e) {
- // Return an empty array here because callers expect an empty array when the file is
- // not present.
- loge("Error opening configuration file: " + e);
- return new ArrayMap<>(0);
- }
- return readIpConfigurations(bufferedInputStream);
- }
-
- /** @deprecated use {@link #readIpConfigurations(String)} */
- @Deprecated
- public static SparseArray<IpConfiguration> readIpAndProxyConfigurations(String filePath) {
- BufferedInputStream bufferedInputStream;
- try {
- bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
- } catch (FileNotFoundException e) {
- // Return an empty array here because callers expect an empty array when the file is
- // not present.
- loge("Error opening configuration file: " + e);
- return new SparseArray<>();
- }
- return readIpAndProxyConfigurations(bufferedInputStream);
- }
-
- /** @deprecated use {@link #readIpConfigurations(InputStream)} */
- @Deprecated
- public static SparseArray<IpConfiguration> readIpAndProxyConfigurations(
- InputStream inputStream) {
- ArrayMap<String, IpConfiguration> networks = readIpConfigurations(inputStream);
- if (networks == null) {
- return null;
- }
-
- SparseArray<IpConfiguration> networksById = new SparseArray<>();
- for (int i = 0; i < networks.size(); i++) {
- int id = Integer.valueOf(networks.keyAt(i));
- networksById.put(id, networks.valueAt(i));
- }
-
- return networksById;
- }
-
- /** Returns a map of network identity token and {@link IpConfiguration}. */
- public static ArrayMap<String, IpConfiguration> readIpConfigurations(
- InputStream inputStream) {
- ArrayMap<String, IpConfiguration> networks = new ArrayMap<>();
- DataInputStream in = null;
- try {
- in = new DataInputStream(inputStream);
-
- int version = in.readInt();
- if (version != 3 && version != 2 && version != 1) {
- loge("Bad version on IP configuration file, ignore read");
- return null;
- }
-
- while (true) {
- String uniqueToken = null;
- // Default is DHCP with no proxy
- IpAssignment ipAssignment = IpAssignment.DHCP;
- ProxySettings proxySettings = ProxySettings.NONE;
- StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
- LinkAddress linkAddress = null;
- InetAddress gatewayAddress = null;
- String proxyHost = null;
- String pacFileUrl = null;
- int proxyPort = -1;
- String exclusionList = null;
- String key;
- final List<InetAddress> dnsServers = new ArrayList<>();
-
- do {
- key = in.readUTF();
- try {
- if (key.equals(ID_KEY)) {
- if (version < 3) {
- int id = in.readInt();
- uniqueToken = String.valueOf(id);
- } else {
- uniqueToken = in.readUTF();
- }
- } else if (key.equals(IP_ASSIGNMENT_KEY)) {
- ipAssignment = IpAssignment.valueOf(in.readUTF());
- } else if (key.equals(LINK_ADDRESS_KEY)) {
- LinkAddress parsedLinkAddress =
- new LinkAddress(
- InetAddresses.parseNumericAddress(in.readUTF()),
- in.readInt());
- if (parsedLinkAddress.getAddress() instanceof Inet4Address
- && linkAddress == null) {
- linkAddress = parsedLinkAddress;
- } else {
- loge("Non-IPv4 or duplicate address: " + parsedLinkAddress);
- }
- } else if (key.equals(GATEWAY_KEY)) {
- LinkAddress dest = null;
- InetAddress gateway = null;
- if (version == 1) {
- // only supported default gateways - leave the dest/prefix empty
- gateway = InetAddresses.parseNumericAddress(in.readUTF());
- if (gatewayAddress == null) {
- gatewayAddress = gateway;
- } else {
- loge("Duplicate gateway: " + gateway.getHostAddress());
- }
- } else {
- if (in.readInt() == 1) {
- dest =
- new LinkAddress(
- InetAddresses.parseNumericAddress(in.readUTF()),
- in.readInt());
- }
- if (in.readInt() == 1) {
- gateway = InetAddresses.parseNumericAddress(in.readUTF());
- }
- // If the destination is a default IPv4 route, use the gateway
- // address unless already set. If there is no destination, assume
- // it is default route and use the gateway address in all cases.
- if (dest == null) {
- gatewayAddress = gateway;
- } else if (dest.getAddress() instanceof Inet4Address
- && dest.getPrefixLength() == 0 && gatewayAddress == null) {
- gatewayAddress = gateway;
- } else {
- loge("Non-IPv4 default or duplicate route: "
- + dest.getAddress());
- }
- }
- } else if (key.equals(DNS_KEY)) {
- dnsServers.add(InetAddresses.parseNumericAddress(in.readUTF()));
- } else if (key.equals(PROXY_SETTINGS_KEY)) {
- proxySettings = ProxySettings.valueOf(in.readUTF());
- } else if (key.equals(PROXY_HOST_KEY)) {
- proxyHost = in.readUTF();
- } else if (key.equals(PROXY_PORT_KEY)) {
- proxyPort = in.readInt();
- } else if (key.equals(PROXY_PAC_FILE)) {
- pacFileUrl = in.readUTF();
- } else if (key.equals(EXCLUSION_LIST_KEY)) {
- exclusionList = in.readUTF();
- } else if (key.equals(EOS)) {
- break;
- } else {
- loge("Ignore unknown key " + key + "while reading");
- }
- } catch (IllegalArgumentException e) {
- loge("Ignore invalid address while reading" + e);
- }
- } while (true);
-
- staticIpConfiguration = new StaticIpConfiguration.Builder()
- .setIpAddress(linkAddress)
- .setGateway(gatewayAddress)
- .setDnsServers(dnsServers)
- .build();
-
- if (uniqueToken != null) {
- IpConfiguration config = new IpConfiguration();
- networks.put(uniqueToken, config);
-
- switch (ipAssignment) {
- case STATIC:
- config.setStaticIpConfiguration(staticIpConfiguration);
- config.setIpAssignment(ipAssignment);
- break;
- case DHCP:
- config.setIpAssignment(ipAssignment);
- break;
- case UNASSIGNED:
- loge("BUG: Found UNASSIGNED IP on file, use DHCP");
- config.setIpAssignment(IpAssignment.DHCP);
- break;
- default:
- loge("Ignore invalid ip assignment while reading.");
- config.setIpAssignment(IpAssignment.UNASSIGNED);
- break;
- }
-
- switch (proxySettings) {
- case STATIC:
- ProxyInfo proxyInfo = ProxyInfo.buildDirectProxy(proxyHost, proxyPort,
- ProxyUtils.exclusionStringAsList(exclusionList));
- config.setProxySettings(proxySettings);
- config.setHttpProxy(proxyInfo);
- break;
- case PAC:
- ProxyInfo proxyPacProperties =
- ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl));
- config.setProxySettings(proxySettings);
- config.setHttpProxy(proxyPacProperties);
- break;
- case NONE:
- config.setProxySettings(proxySettings);
- break;
- case UNASSIGNED:
- loge("BUG: Found UNASSIGNED proxy on file, use NONE");
- config.setProxySettings(ProxySettings.NONE);
- break;
- default:
- loge("Ignore invalid proxy settings while reading");
- config.setProxySettings(ProxySettings.UNASSIGNED);
- break;
- }
- } else {
- if (DBG) log("Missing id while parsing configuration");
- }
- }
- } catch (EOFException ignore) {
- } catch (IOException e) {
- loge("Error parsing configuration: " + e);
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (Exception e) { }
- }
- }
-
- return networks;
- }
-
- protected static void loge(String s) {
- Log.e(TAG, s);
- }
-
- protected static void log(String s) {
- Log.d(TAG, s);
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
deleted file mode 100644
index 3b93f1a..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright (C) 2011 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.net;
-
-import static android.net.NetworkStats.INTERFACES_ALL;
-import static android.net.NetworkStats.SET_ALL;
-import static android.net.NetworkStats.TAG_ALL;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.NetworkStats;
-import android.net.UnderlyingNetworkInfo;
-import android.os.ServiceSpecificException;
-import android.os.StrictMode;
-import android.os.SystemClock;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ProcFileReader;
-import com.android.net.module.util.CollectionUtils;
-import com.android.server.BpfNetMaps;
-
-import libcore.io.IoUtils;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.ProtocolException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Creates {@link NetworkStats} instances by parsing various {@code /proc/}
- * files as needed.
- *
- * @hide
- */
-public class NetworkStatsFactory {
- static {
- System.loadLibrary("service-connectivity");
- }
-
- private static final String TAG = "NetworkStatsFactory";
-
- private static final boolean USE_NATIVE_PARSING = true;
- private static final boolean VALIDATE_NATIVE_STATS = false;
-
- /** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */
- private final File mStatsXtIfaceAll;
- /** Path to {@code /proc/net/xt_qtaguid/iface_stat_fmt}. */
- private final File mStatsXtIfaceFmt;
- /** Path to {@code /proc/net/xt_qtaguid/stats}. */
- private final File mStatsXtUid;
-
- private final boolean mUseBpfStats;
-
- private final Context mContext;
-
- private final BpfNetMaps mBpfNetMaps;
-
- /**
- * Guards persistent data access in this class
- *
- * <p>In order to prevent deadlocks, critical sections protected by this lock SHALL NOT call out
- * to other code that will acquire other locks within the system server. See b/134244752.
- */
- private final Object mPersistentDataLock = new Object();
-
- /** Set containing info about active VPNs and their underlying networks. */
- private volatile UnderlyingNetworkInfo[] mUnderlyingNetworkInfos = new UnderlyingNetworkInfo[0];
-
- // A persistent snapshot of cumulative stats since device start
- @GuardedBy("mPersistentDataLock")
- private NetworkStats mPersistSnapshot;
-
- // The persistent snapshot of tun and 464xlat adjusted stats since device start
- @GuardedBy("mPersistentDataLock")
- private NetworkStats mTunAnd464xlatAdjustedStats;
-
- /**
- * (Stacked interface) -> (base interface) association for all connected ifaces since boot.
- *
- * Because counters must never roll backwards, once a given interface is stacked on top of an
- * underlying interface, the stacked interface can never be stacked on top of
- * another interface. */
- private final ConcurrentHashMap<String, String> mStackedIfaces
- = new ConcurrentHashMap<>();
-
- /** Informs the factory of a new stacked interface. */
- public void noteStackedIface(String stackedIface, String baseIface) {
- if (stackedIface != null && baseIface != null) {
- mStackedIfaces.put(stackedIface, baseIface);
- }
- }
-
- /**
- * Set active VPN information for data usage migration purposes
- *
- * <p>Traffic on TUN-based VPNs inherently all appear to be originated from the VPN providing
- * app's UID. This method is used to support migration of VPN data usage, ensuring data is
- * accurately billed to the real owner of the traffic.
- *
- * @param vpnArray The snapshot of the currently-running VPNs.
- */
- public void updateUnderlyingNetworkInfos(UnderlyingNetworkInfo[] vpnArray) {
- mUnderlyingNetworkInfos = vpnArray.clone();
- }
-
- /**
- * Get a set of interfaces containing specified ifaces and stacked interfaces.
- *
- * <p>The added stacked interfaces are ifaces stacked on top of the specified ones, or ifaces
- * on which the specified ones are stacked. Stacked interfaces are those noted with
- * {@link #noteStackedIface(String, String)}, but only interfaces noted before this method
- * is called are guaranteed to be included.
- */
- public String[] augmentWithStackedInterfaces(@Nullable String[] requiredIfaces) {
- if (requiredIfaces == NetworkStats.INTERFACES_ALL) {
- return null;
- }
-
- HashSet<String> relatedIfaces = new HashSet<>(Arrays.asList(requiredIfaces));
- // ConcurrentHashMap's EntrySet iterators are "guaranteed to traverse
- // elements as they existed upon construction exactly once, and may
- // (but are not guaranteed to) reflect any modifications subsequent to construction".
- // This is enough here.
- for (Map.Entry<String, String> entry : mStackedIfaces.entrySet()) {
- if (relatedIfaces.contains(entry.getKey())) {
- relatedIfaces.add(entry.getValue());
- } else if (relatedIfaces.contains(entry.getValue())) {
- relatedIfaces.add(entry.getKey());
- }
- }
-
- String[] outArray = new String[relatedIfaces.size()];
- return relatedIfaces.toArray(outArray);
- }
-
- /**
- * Applies 464xlat adjustments with ifaces noted with {@link #noteStackedIface(String, String)}.
- * @see NetworkStats#apply464xlatAdjustments(NetworkStats, NetworkStats, Map)
- */
- public void apply464xlatAdjustments(NetworkStats baseTraffic, NetworkStats stackedTraffic) {
- NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, mStackedIfaces);
- }
-
- public NetworkStatsFactory(@NonNull Context ctx) {
- this(ctx, new File("/proc/"), true);
- }
-
- @VisibleForTesting
- public NetworkStatsFactory(@NonNull Context ctx, File procRoot, boolean useBpfStats) {
- mStatsXtIfaceAll = new File(procRoot, "net/xt_qtaguid/iface_stat_all");
- mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
- mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
- mUseBpfStats = useBpfStats;
- mBpfNetMaps = new BpfNetMaps();
- synchronized (mPersistentDataLock) {
- mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1);
- mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
- }
- mContext = ctx;
- }
-
- public NetworkStats readBpfNetworkStatsDev() throws IOException {
- final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
- if (nativeReadNetworkStatsDev(stats) != 0) {
- throw new IOException("Failed to parse bpf iface stats");
- }
- return stats;
- }
-
- /**
- * Parse and return interface-level summary {@link NetworkStats} measured
- * using {@code /proc/net/dev} style hooks, which may include non IP layer
- * traffic. Values monotonically increase since device boot, and may include
- * details about inactive interfaces.
- *
- * @throws IllegalStateException when problem parsing stats.
- */
- public NetworkStats readNetworkStatsSummaryDev() throws IOException {
-
- // Return xt_bpf stats if switched to bpf module.
- if (mUseBpfStats)
- return readBpfNetworkStatsDev();
-
- final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
-
- final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
- final NetworkStats.Entry entry = new NetworkStats.Entry();
-
- ProcFileReader reader = null;
- try {
- reader = new ProcFileReader(new FileInputStream(mStatsXtIfaceAll));
-
- while (reader.hasMoreData()) {
- entry.iface = reader.nextString();
- entry.uid = UID_ALL;
- entry.set = SET_ALL;
- entry.tag = TAG_NONE;
-
- final boolean active = reader.nextInt() != 0;
-
- // always include snapshot values
- entry.rxBytes = reader.nextLong();
- entry.rxPackets = reader.nextLong();
- entry.txBytes = reader.nextLong();
- entry.txPackets = reader.nextLong();
-
- // fold in active numbers, but only when active
- if (active) {
- entry.rxBytes += reader.nextLong();
- entry.rxPackets += reader.nextLong();
- entry.txBytes += reader.nextLong();
- entry.txPackets += reader.nextLong();
- }
-
- stats.insertEntry(entry);
- reader.finishLine();
- }
- } catch (NullPointerException|NumberFormatException e) {
- throw protocolExceptionWithCause("problem parsing stats", e);
- } finally {
- IoUtils.closeQuietly(reader);
- StrictMode.setThreadPolicy(savedPolicy);
- }
- return stats;
- }
-
- /**
- * Parse and return interface-level summary {@link NetworkStats}. Designed
- * to return only IP layer traffic. Values monotonically increase since
- * device boot, and may include details about inactive interfaces.
- *
- * @throws IllegalStateException when problem parsing stats.
- */
- public NetworkStats readNetworkStatsSummaryXt() throws IOException {
-
- // Return xt_bpf stats if qtaguid module is replaced.
- if (mUseBpfStats)
- return readBpfNetworkStatsDev();
-
- final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
-
- // return null when kernel doesn't support
- if (!mStatsXtIfaceFmt.exists()) return null;
-
- final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
- final NetworkStats.Entry entry = new NetworkStats.Entry();
-
- ProcFileReader reader = null;
- try {
- // open and consume header line
- reader = new ProcFileReader(new FileInputStream(mStatsXtIfaceFmt));
- reader.finishLine();
-
- while (reader.hasMoreData()) {
- entry.iface = reader.nextString();
- entry.uid = UID_ALL;
- entry.set = SET_ALL;
- entry.tag = TAG_NONE;
-
- entry.rxBytes = reader.nextLong();
- entry.rxPackets = reader.nextLong();
- entry.txBytes = reader.nextLong();
- entry.txPackets = reader.nextLong();
-
- stats.insertEntry(entry);
- reader.finishLine();
- }
- } catch (NullPointerException|NumberFormatException e) {
- throw protocolExceptionWithCause("problem parsing stats", e);
- } finally {
- IoUtils.closeQuietly(reader);
- StrictMode.setThreadPolicy(savedPolicy);
- }
- return stats;
- }
-
- public NetworkStats readNetworkStatsDetail() throws IOException {
- return readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
- }
-
- @GuardedBy("mPersistentDataLock")
- private void requestSwapActiveStatsMapLocked() throws IOException {
- try {
- // Do a active map stats swap. Once the swap completes, this code
- // can read and clean the inactive map without races.
- mBpfNetMaps.swapActiveStatsMap();
- } catch (ServiceSpecificException e) {
- throw new IOException(e);
- }
- }
-
- /**
- * Reads the detailed UID stats based on the provided parameters
- *
- * @param limitUid the UID to limit this query to
- * @param limitIfaces the interfaces to limit this query to. Use {@link
- * NetworkStats.INTERFACES_ALL} to select all interfaces
- * @param limitTag the tags to limit this query to
- * @return the NetworkStats instance containing network statistics at the present time.
- */
- public NetworkStats readNetworkStatsDetail(
- int limitUid, String[] limitIfaces, int limitTag) throws IOException {
- // In order to prevent deadlocks, anything protected by this lock MUST NOT call out to other
- // code that will acquire other locks within the system server. See b/134244752.
- synchronized (mPersistentDataLock) {
- // Take a reference. If this gets swapped out, we still have the old reference.
- final UnderlyingNetworkInfo[] vpnArray = mUnderlyingNetworkInfos;
- // Take a defensive copy. mPersistSnapshot is mutated in some cases below
- final NetworkStats prev = mPersistSnapshot.clone();
-
- if (USE_NATIVE_PARSING) {
- final NetworkStats stats =
- new NetworkStats(SystemClock.elapsedRealtime(), 0 /* initialSize */);
- if (mUseBpfStats) {
- requestSwapActiveStatsMapLocked();
- // Stats are always read from the inactive map, so they must be read after the
- // swap
- if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), UID_ALL,
- INTERFACES_ALL, TAG_ALL, mUseBpfStats) != 0) {
- throw new IOException("Failed to parse network stats");
- }
-
- // BPF stats are incremental; fold into mPersistSnapshot.
- mPersistSnapshot.setElapsedRealtime(stats.getElapsedRealtime());
- mPersistSnapshot.combineAllValues(stats);
- } else {
- if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), UID_ALL,
- INTERFACES_ALL, TAG_ALL, mUseBpfStats) != 0) {
- throw new IOException("Failed to parse network stats");
- }
- if (VALIDATE_NATIVE_STATS) {
- final NetworkStats javaStats = javaReadNetworkStatsDetail(mStatsXtUid,
- UID_ALL, INTERFACES_ALL, TAG_ALL);
- assertEquals(javaStats, stats);
- }
-
- mPersistSnapshot = stats;
- }
- } else {
- mPersistSnapshot = javaReadNetworkStatsDetail(mStatsXtUid, UID_ALL, INTERFACES_ALL,
- TAG_ALL);
- }
-
- NetworkStats adjustedStats = adjustForTunAnd464Xlat(mPersistSnapshot, prev, vpnArray);
-
- // Filter return values
- adjustedStats.filter(limitUid, limitIfaces, limitTag);
- return adjustedStats;
- }
- }
-
- @GuardedBy("mPersistentDataLock")
- private NetworkStats adjustForTunAnd464Xlat(NetworkStats uidDetailStats,
- NetworkStats previousStats, UnderlyingNetworkInfo[] vpnArray) {
- // Calculate delta from last snapshot
- final NetworkStats delta = uidDetailStats.subtract(previousStats);
-
- // Apply 464xlat adjustments before VPN adjustments. If VPNs are using v4 on a v6 only
- // network, the overhead is their fault.
- // No locking here: apply464xlatAdjustments behaves fine with an add-only
- // ConcurrentHashMap.
- delta.apply464xlatAdjustments(mStackedIfaces);
-
- // Migrate data usage over a VPN to the TUN network.
- for (UnderlyingNetworkInfo info : vpnArray) {
- delta.migrateTun(info.getOwnerUid(), info.getInterface(),
- info.getUnderlyingInterfaces());
- // Filter out debug entries as that may lead to over counting.
- delta.filterDebugEntries();
- }
-
- // Update mTunAnd464xlatAdjustedStats with migrated delta.
- mTunAnd464xlatAdjustedStats.combineAllValues(delta);
- mTunAnd464xlatAdjustedStats.setElapsedRealtime(uidDetailStats.getElapsedRealtime());
-
- return mTunAnd464xlatAdjustedStats.clone();
- }
-
- /**
- * Parse and return {@link NetworkStats} with UID-level details. Values are
- * expected to monotonically increase since device boot.
- */
- @VisibleForTesting
- public static NetworkStats javaReadNetworkStatsDetail(File detailPath, int limitUid,
- String[] limitIfaces, int limitTag)
- throws IOException {
- final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
-
- final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 24);
- final NetworkStats.Entry entry = new NetworkStats.Entry();
-
- int idx = 1;
- int lastIdx = 1;
-
- ProcFileReader reader = null;
- try {
- // open and consume header line
- reader = new ProcFileReader(new FileInputStream(detailPath));
- reader.finishLine();
-
- while (reader.hasMoreData()) {
- idx = reader.nextInt();
- if (idx != lastIdx + 1) {
- throw new ProtocolException(
- "inconsistent idx=" + idx + " after lastIdx=" + lastIdx);
- }
- lastIdx = idx;
-
- entry.iface = reader.nextString();
- entry.tag = kernelToTag(reader.nextString());
- entry.uid = reader.nextInt();
- entry.set = reader.nextInt();
- entry.rxBytes = reader.nextLong();
- entry.rxPackets = reader.nextLong();
- entry.txBytes = reader.nextLong();
- entry.txPackets = reader.nextLong();
-
- if ((limitIfaces == null || CollectionUtils.contains(limitIfaces, entry.iface))
- && (limitUid == UID_ALL || limitUid == entry.uid)
- && (limitTag == TAG_ALL || limitTag == entry.tag)) {
- stats.insertEntry(entry);
- }
-
- reader.finishLine();
- }
- } catch (NullPointerException|NumberFormatException e) {
- throw protocolExceptionWithCause("problem parsing idx " + idx, e);
- } finally {
- IoUtils.closeQuietly(reader);
- StrictMode.setThreadPolicy(savedPolicy);
- }
-
- return stats;
- }
-
- public void assertEquals(NetworkStats expected, NetworkStats actual) {
- if (expected.size() != actual.size()) {
- throw new AssertionError(
- "Expected size " + expected.size() + ", actual size " + actual.size());
- }
-
- NetworkStats.Entry expectedRow = null;
- NetworkStats.Entry actualRow = null;
- for (int i = 0; i < expected.size(); i++) {
- expectedRow = expected.getValues(i, expectedRow);
- actualRow = actual.getValues(i, actualRow);
- if (!expectedRow.equals(actualRow)) {
- throw new AssertionError(
- "Expected row " + i + ": " + expectedRow + ", actual row " + actualRow);
- }
- }
- }
-
- /**
- * Convert {@code /proc/} tag format to {@link Integer}. Assumes incoming
- * format like {@code 0x7fffffff00000000}.
- */
- public static int kernelToTag(String string) {
- int length = string.length();
- if (length > 10) {
- return Long.decode(string.substring(0, length - 8)).intValue();
- } else {
- return 0;
- }
- }
-
- /**
- * Parse statistics from file into given {@link NetworkStats} object. Values
- * are expected to monotonically increase since device boot.
- */
- @VisibleForTesting
- public static native int nativeReadNetworkStatsDetail(NetworkStats stats, String path,
- int limitUid, String[] limitIfaces, int limitTag, boolean useBpfStats);
-
- @VisibleForTesting
- public static native int nativeReadNetworkStatsDev(NetworkStats stats);
-
- private static ProtocolException protocolExceptionWithCause(String message, Throwable cause) {
- ProtocolException pe = new ProtocolException(message);
- pe.initCause(cause);
- return pe;
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java
deleted file mode 100644
index fdfc893..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.net;
-
-import static android.app.usage.NetworkStatsManager.MIN_THRESHOLD_BYTES;
-
-import android.app.usage.NetworkStatsManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.net.DataUsageRequest;
-import android.net.NetworkIdentitySet;
-import android.net.NetworkStack;
-import android.net.NetworkStats;
-import android.net.NetworkStatsAccess;
-import android.net.NetworkStatsCollection;
-import android.net.NetworkStatsHistory;
-import android.net.NetworkTemplate;
-import android.net.netstats.IUsageCallback;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
-import android.os.RemoteException;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Manages observers of {@link NetworkStats}. Allows observers to be notified when
- * data usage has been reported in {@link NetworkStatsService}. An observer can set
- * a threshold of how much data it cares about to be notified.
- */
-class NetworkStatsObservers {
- private static final String TAG = "NetworkStatsObservers";
- private static final boolean LOGV = false;
-
- private static final int MSG_REGISTER = 1;
- private static final int MSG_UNREGISTER = 2;
- private static final int MSG_UPDATE_STATS = 3;
-
- // All access to this map must be done from the handler thread.
- // indexed by DataUsageRequest#requestId
- private final SparseArray<RequestInfo> mDataUsageRequests = new SparseArray<>();
-
- // Sequence number of DataUsageRequests
- private final AtomicInteger mNextDataUsageRequestId = new AtomicInteger();
-
- // Lazily instantiated when an observer is registered.
- private volatile Handler mHandler;
-
- /**
- * Creates a wrapper that contains the caller context and a normalized request.
- * The request should be returned to the caller app, and the wrapper should be sent to this
- * object through #addObserver by the service handler.
- *
- * <p>It will register the observer asynchronously, so it is safe to call from any thread.
- *
- * @return the normalized request wrapped within {@link RequestInfo}.
- */
- public DataUsageRequest register(Context context, DataUsageRequest inputRequest,
- IUsageCallback callback, int callingUid, @NetworkStatsAccess.Level int accessLevel) {
- DataUsageRequest request = buildRequest(context, inputRequest, callingUid);
- RequestInfo requestInfo = buildRequestInfo(request, callback, callingUid,
- accessLevel);
-
- if (LOGV) Log.v(TAG, "Registering observer for " + request);
- getHandler().sendMessage(mHandler.obtainMessage(MSG_REGISTER, requestInfo));
- return request;
- }
-
- /**
- * Unregister a data usage observer.
- *
- * <p>It will unregister the observer asynchronously, so it is safe to call from any thread.
- */
- public void unregister(DataUsageRequest request, int callingUid) {
- getHandler().sendMessage(mHandler.obtainMessage(MSG_UNREGISTER, callingUid, 0 /* ignore */,
- request));
- }
-
- /**
- * Updates data usage statistics of registered observers and notifies if limits are reached.
- *
- * <p>It will update stats asynchronously, so it is safe to call from any thread.
- */
- public void updateStats(NetworkStats xtSnapshot, NetworkStats uidSnapshot,
- ArrayMap<String, NetworkIdentitySet> activeIfaces,
- ArrayMap<String, NetworkIdentitySet> activeUidIfaces,
- long currentTime) {
- StatsContext statsContext = new StatsContext(xtSnapshot, uidSnapshot, activeIfaces,
- activeUidIfaces, currentTime);
- getHandler().sendMessage(mHandler.obtainMessage(MSG_UPDATE_STATS, statsContext));
- }
-
- private Handler getHandler() {
- if (mHandler == null) {
- synchronized (this) {
- if (mHandler == null) {
- if (LOGV) Log.v(TAG, "Creating handler");
- mHandler = new Handler(getHandlerLooperLocked(), mHandlerCallback);
- }
- }
- }
- return mHandler;
- }
-
- @VisibleForTesting
- protected Looper getHandlerLooperLocked() {
- HandlerThread handlerThread = new HandlerThread(TAG);
- handlerThread.start();
- return handlerThread.getLooper();
- }
-
- private Handler.Callback mHandlerCallback = new Handler.Callback() {
- @Override
- public boolean handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_REGISTER: {
- handleRegister((RequestInfo) msg.obj);
- return true;
- }
- case MSG_UNREGISTER: {
- handleUnregister((DataUsageRequest) msg.obj, msg.arg1 /* callingUid */);
- return true;
- }
- case MSG_UPDATE_STATS: {
- handleUpdateStats((StatsContext) msg.obj);
- return true;
- }
- default: {
- return false;
- }
- }
- }
- };
-
- /**
- * Adds a {@link RequestInfo} as an observer.
- * Should only be called from the handler thread otherwise there will be a race condition
- * on mDataUsageRequests.
- */
- private void handleRegister(RequestInfo requestInfo) {
- mDataUsageRequests.put(requestInfo.mRequest.requestId, requestInfo);
- }
-
- /**
- * Removes a {@link DataUsageRequest} if the calling uid is authorized.
- * Should only be called from the handler thread otherwise there will be a race condition
- * on mDataUsageRequests.
- */
- private void handleUnregister(DataUsageRequest request, int callingUid) {
- RequestInfo requestInfo;
- requestInfo = mDataUsageRequests.get(request.requestId);
- if (requestInfo == null) {
- if (LOGV) Log.v(TAG, "Trying to unregister unknown request " + request);
- return;
- }
- if (Process.SYSTEM_UID != callingUid && requestInfo.mCallingUid != callingUid) {
- Log.w(TAG, "Caller uid " + callingUid + " is not owner of " + request);
- return;
- }
-
- if (LOGV) Log.v(TAG, "Unregistering " + request);
- mDataUsageRequests.remove(request.requestId);
- requestInfo.unlinkDeathRecipient();
- requestInfo.callCallback(NetworkStatsManager.CALLBACK_RELEASED);
- }
-
- private void handleUpdateStats(StatsContext statsContext) {
- if (mDataUsageRequests.size() == 0) {
- return;
- }
-
- for (int i = 0; i < mDataUsageRequests.size(); i++) {
- RequestInfo requestInfo = mDataUsageRequests.valueAt(i);
- requestInfo.updateStats(statsContext);
- }
- }
-
- private DataUsageRequest buildRequest(Context context, DataUsageRequest request,
- int callingUid) {
- // For non-NETWORK_STACK permission uid, cap the minimum threshold to a safe default to
- // avoid too many callbacks.
- final long thresholdInBytes = (context.checkPermission(
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, Process.myPid(), callingUid)
- == PackageManager.PERMISSION_GRANTED ? request.thresholdInBytes
- : Math.max(MIN_THRESHOLD_BYTES, request.thresholdInBytes));
- if (thresholdInBytes > request.thresholdInBytes) {
- Log.w(TAG, "Threshold was too low for " + request
- + ". Overriding to a safer default of " + thresholdInBytes + " bytes");
- }
- return new DataUsageRequest(mNextDataUsageRequestId.incrementAndGet(),
- request.template, thresholdInBytes);
- }
-
- private RequestInfo buildRequestInfo(DataUsageRequest request, IUsageCallback callback,
- int callingUid, @NetworkStatsAccess.Level int accessLevel) {
- if (accessLevel <= NetworkStatsAccess.Level.USER) {
- return new UserUsageRequestInfo(this, request, callback, callingUid,
- accessLevel);
- } else {
- // Safety check in case a new access level is added and we forgot to update this
- if (accessLevel < NetworkStatsAccess.Level.DEVICESUMMARY) {
- throw new IllegalArgumentException(
- "accessLevel " + accessLevel + " is less than DEVICESUMMARY.");
- }
- return new NetworkUsageRequestInfo(this, request, callback, callingUid,
- accessLevel);
- }
- }
-
- /**
- * Tracks information relevant to a data usage observer.
- * It will notice when the calling process dies so we can self-expire.
- */
- private abstract static class RequestInfo implements IBinder.DeathRecipient {
- private final NetworkStatsObservers mStatsObserver;
- protected final DataUsageRequest mRequest;
- private final IUsageCallback mCallback;
- protected final int mCallingUid;
- protected final @NetworkStatsAccess.Level int mAccessLevel;
- protected NetworkStatsRecorder mRecorder;
- protected NetworkStatsCollection mCollection;
-
- RequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request,
- IUsageCallback callback, int callingUid,
- @NetworkStatsAccess.Level int accessLevel) {
- mStatsObserver = statsObserver;
- mRequest = request;
- mCallback = callback;
- mCallingUid = callingUid;
- mAccessLevel = accessLevel;
-
- try {
- mCallback.asBinder().linkToDeath(this, 0);
- } catch (RemoteException e) {
- binderDied();
- }
- }
-
- @Override
- public void binderDied() {
- if (LOGV) {
- Log.v(TAG, "RequestInfo binderDied(" + mRequest + ", " + mCallback + ")");
- }
- mStatsObserver.unregister(mRequest, Process.SYSTEM_UID);
- callCallback(NetworkStatsManager.CALLBACK_RELEASED);
- }
-
- @Override
- public String toString() {
- return "RequestInfo from uid:" + mCallingUid
- + " for " + mRequest + " accessLevel:" + mAccessLevel;
- }
-
- private void unlinkDeathRecipient() {
- mCallback.asBinder().unlinkToDeath(this, 0);
- }
-
- /**
- * Update stats given the samples and interface to identity mappings.
- */
- private void updateStats(StatsContext statsContext) {
- if (mRecorder == null) {
- // First run; establish baseline stats
- resetRecorder();
- recordSample(statsContext);
- return;
- }
- recordSample(statsContext);
-
- if (checkStats()) {
- resetRecorder();
- callCallback(NetworkStatsManager.CALLBACK_LIMIT_REACHED);
- }
- }
-
- private void callCallback(int callbackType) {
- try {
- if (LOGV) {
- Log.v(TAG, "sending notification " + callbackTypeToName(callbackType)
- + " for " + mRequest);
- }
- switch (callbackType) {
- case NetworkStatsManager.CALLBACK_LIMIT_REACHED:
- mCallback.onThresholdReached(mRequest);
- break;
- case NetworkStatsManager.CALLBACK_RELEASED:
- mCallback.onCallbackReleased(mRequest);
- break;
- }
- } catch (RemoteException e) {
- // May occur naturally in the race of binder death.
- Log.w(TAG, "RemoteException caught trying to send a callback msg for " + mRequest);
- }
- }
-
- private void resetRecorder() {
- mRecorder = new NetworkStatsRecorder();
- mCollection = mRecorder.getSinceBoot();
- }
-
- protected abstract boolean checkStats();
-
- protected abstract void recordSample(StatsContext statsContext);
-
- private String callbackTypeToName(int callbackType) {
- switch (callbackType) {
- case NetworkStatsManager.CALLBACK_LIMIT_REACHED:
- return "LIMIT_REACHED";
- case NetworkStatsManager.CALLBACK_RELEASED:
- return "RELEASED";
- default:
- return "UNKNOWN";
- }
- }
- }
-
- private static class NetworkUsageRequestInfo extends RequestInfo {
- NetworkUsageRequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request,
- IUsageCallback callback, int callingUid,
- @NetworkStatsAccess.Level int accessLevel) {
- super(statsObserver, request, callback, callingUid, accessLevel);
- }
-
- @Override
- protected boolean checkStats() {
- long bytesSoFar = getTotalBytesForNetwork(mRequest.template);
- if (LOGV) {
- Log.v(TAG, bytesSoFar + " bytes so far since notification for "
- + mRequest.template);
- }
- if (bytesSoFar > mRequest.thresholdInBytes) {
- return true;
- }
- return false;
- }
-
- @Override
- protected void recordSample(StatsContext statsContext) {
- // Recorder does not need to be locked in this context since only the handler
- // thread will update it. We pass a null VPN array because usage is aggregated by uid
- // for this snapshot, so VPN traffic can't be reattributed to responsible apps.
- mRecorder.recordSnapshotLocked(statsContext.mXtSnapshot, statsContext.mActiveIfaces,
- statsContext.mCurrentTime);
- }
-
- /**
- * Reads stats matching the given template. {@link NetworkStatsCollection} will aggregate
- * over all buckets, which in this case should be only one since we built it big enough
- * that it will outlive the caller. If it doesn't, then there will be multiple buckets.
- */
- private long getTotalBytesForNetwork(NetworkTemplate template) {
- NetworkStats stats = mCollection.getSummary(template,
- Long.MIN_VALUE /* start */, Long.MAX_VALUE /* end */,
- mAccessLevel, mCallingUid);
- return stats.getTotalBytes();
- }
- }
-
- private static class UserUsageRequestInfo extends RequestInfo {
- UserUsageRequestInfo(NetworkStatsObservers statsObserver, DataUsageRequest request,
- IUsageCallback callback, int callingUid,
- @NetworkStatsAccess.Level int accessLevel) {
- super(statsObserver, request, callback, callingUid, accessLevel);
- }
-
- @Override
- protected boolean checkStats() {
- int[] uidsToMonitor = mCollection.getRelevantUids(mAccessLevel, mCallingUid);
-
- for (int i = 0; i < uidsToMonitor.length; i++) {
- long bytesSoFar = getTotalBytesForNetworkUid(mRequest.template, uidsToMonitor[i]);
- if (bytesSoFar > mRequest.thresholdInBytes) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- protected void recordSample(StatsContext statsContext) {
- // Recorder does not need to be locked in this context since only the handler
- // thread will update it. We pass the VPN info so VPN traffic is reattributed to
- // responsible apps.
- mRecorder.recordSnapshotLocked(statsContext.mUidSnapshot, statsContext.mActiveUidIfaces,
- statsContext.mCurrentTime);
- }
-
- /**
- * Reads all stats matching the given template and uid. Ther history will likely only
- * contain one bucket per ident since we build it big enough that it will outlive the
- * caller lifetime.
- */
- private long getTotalBytesForNetworkUid(NetworkTemplate template, int uid) {
- try {
- NetworkStatsHistory history = mCollection.getHistory(template, null, uid,
- NetworkStats.SET_ALL, NetworkStats.TAG_NONE,
- NetworkStatsHistory.FIELD_ALL,
- Long.MIN_VALUE /* start */, Long.MAX_VALUE /* end */,
- mAccessLevel, mCallingUid);
- return history.getTotalBytes();
- } catch (SecurityException e) {
- if (LOGV) {
- Log.w(TAG, "CallerUid " + mCallingUid + " may have lost access to uid "
- + uid);
- }
- return 0;
- }
- }
- }
-
- private static class StatsContext {
- NetworkStats mXtSnapshot;
- NetworkStats mUidSnapshot;
- ArrayMap<String, NetworkIdentitySet> mActiveIfaces;
- ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces;
- long mCurrentTime;
-
- StatsContext(NetworkStats xtSnapshot, NetworkStats uidSnapshot,
- ArrayMap<String, NetworkIdentitySet> activeIfaces,
- ArrayMap<String, NetworkIdentitySet> activeUidIfaces,
- long currentTime) {
- mXtSnapshot = xtSnapshot;
- mUidSnapshot = uidSnapshot;
- mActiveIfaces = activeIfaces;
- mActiveUidIfaces = activeUidIfaces;
- mCurrentTime = currentTime;
- }
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java
deleted file mode 100644
index f62765d..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * Copyright (C) 2012 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.net;
-
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.TrafficStats.KB_IN_BYTES;
-import static android.net.TrafficStats.MB_IN_BYTES;
-import static android.text.format.DateUtils.YEAR_IN_MILLIS;
-
-import android.net.NetworkIdentitySet;
-import android.net.NetworkStats;
-import android.net.NetworkStats.NonMonotonicObserver;
-import android.net.NetworkStatsAccess;
-import android.net.NetworkStatsCollection;
-import android.net.NetworkStatsHistory;
-import android.net.NetworkTemplate;
-import android.net.TrafficStats;
-import android.os.Binder;
-import android.os.DropBoxManager;
-import android.service.NetworkStatsRecorderProto;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.util.FileRotator;
-import com.android.net.module.util.NetworkStatsUtils;
-
-import libcore.io.IoUtils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Logic to record deltas between periodic {@link NetworkStats} snapshots into
- * {@link NetworkStatsHistory} that belong to {@link NetworkStatsCollection}.
- * Keeps pending changes in memory until they pass a specific threshold, in
- * bytes. Uses {@link FileRotator} for persistence logic if present.
- * <p>
- * Not inherently thread safe.
- */
-public class NetworkStatsRecorder {
- private static final String TAG = "NetworkStatsRecorder";
- private static final boolean LOGD = false;
- private static final boolean LOGV = false;
-
- private static final String TAG_NETSTATS_DUMP = "netstats_dump";
-
- /** Dump before deleting in {@link #recoverFromWtf()}. */
- private static final boolean DUMP_BEFORE_DELETE = true;
-
- private final FileRotator mRotator;
- private final NonMonotonicObserver<String> mObserver;
- private final DropBoxManager mDropBox;
- private final String mCookie;
-
- private final long mBucketDuration;
- private final boolean mOnlyTags;
-
- private long mPersistThresholdBytes = 2 * MB_IN_BYTES;
- private NetworkStats mLastSnapshot;
-
- private final NetworkStatsCollection mPending;
- private final NetworkStatsCollection mSinceBoot;
-
- private final CombiningRewriter mPendingRewriter;
-
- private WeakReference<NetworkStatsCollection> mComplete;
-
- /**
- * Non-persisted recorder, with only one bucket. Used by {@link NetworkStatsObservers}.
- */
- public NetworkStatsRecorder() {
- mRotator = null;
- mObserver = null;
- mDropBox = null;
- mCookie = null;
-
- // set the bucket big enough to have all data in one bucket, but allow some
- // slack to avoid overflow
- mBucketDuration = YEAR_IN_MILLIS;
- mOnlyTags = false;
-
- mPending = null;
- mSinceBoot = new NetworkStatsCollection(mBucketDuration);
-
- mPendingRewriter = null;
- }
-
- /**
- * Persisted recorder.
- */
- public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer,
- DropBoxManager dropBox, String cookie, long bucketDuration, boolean onlyTags) {
- mRotator = Objects.requireNonNull(rotator, "missing FileRotator");
- mObserver = Objects.requireNonNull(observer, "missing NonMonotonicObserver");
- mDropBox = Objects.requireNonNull(dropBox, "missing DropBoxManager");
- mCookie = cookie;
-
- mBucketDuration = bucketDuration;
- mOnlyTags = onlyTags;
-
- mPending = new NetworkStatsCollection(bucketDuration);
- mSinceBoot = new NetworkStatsCollection(bucketDuration);
-
- mPendingRewriter = new CombiningRewriter(mPending);
- }
-
- public void setPersistThreshold(long thresholdBytes) {
- if (LOGV) Log.v(TAG, "setPersistThreshold() with " + thresholdBytes);
- mPersistThresholdBytes = NetworkStatsUtils.constrain(
- thresholdBytes, 1 * KB_IN_BYTES, 100 * MB_IN_BYTES);
- }
-
- public void resetLocked() {
- mLastSnapshot = null;
- if (mPending != null) {
- mPending.reset();
- }
- if (mSinceBoot != null) {
- mSinceBoot.reset();
- }
- if (mComplete != null) {
- mComplete.clear();
- }
- }
-
- public NetworkStats.Entry getTotalSinceBootLocked(NetworkTemplate template) {
- return mSinceBoot.getSummary(template, Long.MIN_VALUE, Long.MAX_VALUE,
- NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotal(null);
- }
-
- public NetworkStatsCollection getSinceBoot() {
- return mSinceBoot;
- }
-
- /**
- * Load complete history represented by {@link FileRotator}. Caches
- * internally as a {@link WeakReference}, and updated with future
- * {@link #recordSnapshotLocked(NetworkStats, Map, long)} snapshots as long
- * as reference is valid.
- */
- public NetworkStatsCollection getOrLoadCompleteLocked() {
- Objects.requireNonNull(mRotator, "missing FileRotator");
- NetworkStatsCollection res = mComplete != null ? mComplete.get() : null;
- if (res == null) {
- res = loadLocked(Long.MIN_VALUE, Long.MAX_VALUE);
- mComplete = new WeakReference<NetworkStatsCollection>(res);
- }
- return res;
- }
-
- public NetworkStatsCollection getOrLoadPartialLocked(long start, long end) {
- Objects.requireNonNull(mRotator, "missing FileRotator");
- NetworkStatsCollection res = mComplete != null ? mComplete.get() : null;
- if (res == null) {
- res = loadLocked(start, end);
- }
- return res;
- }
-
- private NetworkStatsCollection loadLocked(long start, long end) {
- if (LOGD) Log.d(TAG, "loadLocked() reading from disk for " + mCookie);
- final NetworkStatsCollection res = new NetworkStatsCollection(mBucketDuration);
- try {
- mRotator.readMatching(res, start, end);
- res.recordCollection(mPending);
- } catch (IOException e) {
- Log.wtf(TAG, "problem completely reading network stats", e);
- recoverFromWtf();
- } catch (OutOfMemoryError e) {
- Log.wtf(TAG, "problem completely reading network stats", e);
- recoverFromWtf();
- }
- return res;
- }
-
- /**
- * Record any delta that occurred since last {@link NetworkStats} snapshot, using the given
- * {@link Map} to identify network interfaces. First snapshot is considered bootstrap, and is
- * not counted as delta.
- */
- public void recordSnapshotLocked(NetworkStats snapshot,
- Map<String, NetworkIdentitySet> ifaceIdent, long currentTimeMillis) {
- final HashSet<String> unknownIfaces = new HashSet<>();
-
- // skip recording when snapshot missing
- if (snapshot == null) return;
-
- // assume first snapshot is bootstrap and don't record
- if (mLastSnapshot == null) {
- mLastSnapshot = snapshot;
- return;
- }
-
- final NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null;
-
- final NetworkStats delta = NetworkStats.subtract(
- snapshot, mLastSnapshot, mObserver, mCookie);
- final long end = currentTimeMillis;
- final long start = end - delta.getElapsedRealtime();
-
- NetworkStats.Entry entry = null;
- for (int i = 0; i < delta.size(); i++) {
- entry = delta.getValues(i, entry);
-
- // As a last-ditch check, report any negative values and
- // clamp them so recording below doesn't croak.
- if (entry.isNegative()) {
- if (mObserver != null) {
- mObserver.foundNonMonotonic(delta, i, mCookie);
- }
- entry.rxBytes = Math.max(entry.rxBytes, 0);
- entry.rxPackets = Math.max(entry.rxPackets, 0);
- entry.txBytes = Math.max(entry.txBytes, 0);
- entry.txPackets = Math.max(entry.txPackets, 0);
- entry.operations = Math.max(entry.operations, 0);
- }
-
- final NetworkIdentitySet ident = ifaceIdent.get(entry.iface);
- if (ident == null) {
- unknownIfaces.add(entry.iface);
- continue;
- }
-
- // skip when no delta occurred
- if (entry.isEmpty()) continue;
-
- // only record tag data when requested
- if ((entry.tag == TAG_NONE) != mOnlyTags) {
- if (mPending != null) {
- mPending.recordData(ident, entry.uid, entry.set, entry.tag, start, end, entry);
- }
-
- // also record against boot stats when present
- if (mSinceBoot != null) {
- mSinceBoot.recordData(ident, entry.uid, entry.set, entry.tag, start, end, entry);
- }
-
- // also record against complete dataset when present
- if (complete != null) {
- complete.recordData(ident, entry.uid, entry.set, entry.tag, start, end, entry);
- }
- }
- }
-
- mLastSnapshot = snapshot;
-
- if (LOGV && unknownIfaces.size() > 0) {
- Log.w(TAG, "unknown interfaces " + unknownIfaces + ", ignoring those stats");
- }
- }
-
- /**
- * Consider persisting any pending deltas, if they are beyond
- * {@link #mPersistThresholdBytes}.
- */
- public void maybePersistLocked(long currentTimeMillis) {
- Objects.requireNonNull(mRotator, "missing FileRotator");
- final long pendingBytes = mPending.getTotalBytes();
- if (pendingBytes >= mPersistThresholdBytes) {
- forcePersistLocked(currentTimeMillis);
- } else {
- mRotator.maybeRotate(currentTimeMillis);
- }
- }
-
- /**
- * Force persisting any pending deltas.
- */
- public void forcePersistLocked(long currentTimeMillis) {
- Objects.requireNonNull(mRotator, "missing FileRotator");
- if (mPending.isDirty()) {
- if (LOGD) Log.d(TAG, "forcePersistLocked() writing for " + mCookie);
- try {
- mRotator.rewriteActive(mPendingRewriter, currentTimeMillis);
- mRotator.maybeRotate(currentTimeMillis);
- mPending.reset();
- } catch (IOException e) {
- Log.wtf(TAG, "problem persisting pending stats", e);
- recoverFromWtf();
- } catch (OutOfMemoryError e) {
- Log.wtf(TAG, "problem persisting pending stats", e);
- recoverFromWtf();
- }
- }
- }
-
- /**
- * Remove the given UID from all {@link FileRotator} history, migrating it
- * to {@link TrafficStats#UID_REMOVED}.
- */
- public void removeUidsLocked(int[] uids) {
- if (mRotator != null) {
- try {
- // Rewrite all persisted data to migrate UID stats
- mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uids));
- } catch (IOException e) {
- Log.wtf(TAG, "problem removing UIDs " + Arrays.toString(uids), e);
- recoverFromWtf();
- } catch (OutOfMemoryError e) {
- Log.wtf(TAG, "problem removing UIDs " + Arrays.toString(uids), e);
- recoverFromWtf();
- }
- }
-
- // Remove any pending stats
- if (mPending != null) {
- mPending.removeUids(uids);
- }
- if (mSinceBoot != null) {
- mSinceBoot.removeUids(uids);
- }
-
- // Clear UID from current stats snapshot
- if (mLastSnapshot != null) {
- mLastSnapshot.removeUids(uids);
- }
-
- final NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null;
- if (complete != null) {
- complete.removeUids(uids);
- }
- }
-
- /**
- * Rewriter that will combine current {@link NetworkStatsCollection} values
- * with anything read from disk, and write combined set to disk. Clears the
- * original {@link NetworkStatsCollection} when finished writing.
- */
- private static class CombiningRewriter implements FileRotator.Rewriter {
- private final NetworkStatsCollection mCollection;
-
- public CombiningRewriter(NetworkStatsCollection collection) {
- mCollection = Objects.requireNonNull(collection, "missing NetworkStatsCollection");
- }
-
- @Override
- public void reset() {
- // ignored
- }
-
- @Override
- public void read(InputStream in) throws IOException {
- mCollection.read(in);
- }
-
- @Override
- public boolean shouldWrite() {
- return true;
- }
-
- @Override
- public void write(OutputStream out) throws IOException {
- mCollection.write(out);
- mCollection.reset();
- }
- }
-
- /**
- * Rewriter that will remove any {@link NetworkStatsHistory} attributed to
- * the requested UID, only writing data back when modified.
- */
- public static class RemoveUidRewriter implements FileRotator.Rewriter {
- private final NetworkStatsCollection mTemp;
- private final int[] mUids;
-
- public RemoveUidRewriter(long bucketDuration, int[] uids) {
- mTemp = new NetworkStatsCollection(bucketDuration);
- mUids = uids;
- }
-
- @Override
- public void reset() {
- mTemp.reset();
- }
-
- @Override
- public void read(InputStream in) throws IOException {
- mTemp.read(in);
- mTemp.clearDirty();
- mTemp.removeUids(mUids);
- }
-
- @Override
- public boolean shouldWrite() {
- return mTemp.isDirty();
- }
-
- @Override
- public void write(OutputStream out) throws IOException {
- mTemp.write(out);
- }
- }
-
- public void importLegacyNetworkLocked(File file) throws IOException {
- Objects.requireNonNull(mRotator, "missing FileRotator");
-
- // legacy file still exists; start empty to avoid double importing
- mRotator.deleteAll();
-
- final NetworkStatsCollection collection = new NetworkStatsCollection(mBucketDuration);
- collection.readLegacyNetwork(file);
-
- final long startMillis = collection.getStartMillis();
- final long endMillis = collection.getEndMillis();
-
- if (!collection.isEmpty()) {
- // process legacy data, creating active file at starting time, then
- // using end time to possibly trigger rotation.
- mRotator.rewriteActive(new CombiningRewriter(collection), startMillis);
- mRotator.maybeRotate(endMillis);
- }
- }
-
- public void importLegacyUidLocked(File file) throws IOException {
- Objects.requireNonNull(mRotator, "missing FileRotator");
-
- // legacy file still exists; start empty to avoid double importing
- mRotator.deleteAll();
-
- final NetworkStatsCollection collection = new NetworkStatsCollection(mBucketDuration);
- collection.readLegacyUid(file, mOnlyTags);
-
- final long startMillis = collection.getStartMillis();
- final long endMillis = collection.getEndMillis();
-
- if (!collection.isEmpty()) {
- // process legacy data, creating active file at starting time, then
- // using end time to possibly trigger rotation.
- mRotator.rewriteActive(new CombiningRewriter(collection), startMillis);
- mRotator.maybeRotate(endMillis);
- }
- }
-
- public void dumpLocked(IndentingPrintWriter pw, boolean fullHistory) {
- if (mPending != null) {
- pw.print("Pending bytes: "); pw.println(mPending.getTotalBytes());
- }
- if (fullHistory) {
- pw.println("Complete history:");
- getOrLoadCompleteLocked().dump(pw);
- } else {
- pw.println("History since boot:");
- mSinceBoot.dump(pw);
- }
- }
-
- public void dumpDebugLocked(ProtoOutputStream proto, long tag) {
- final long start = proto.start(tag);
- if (mPending != null) {
- proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES,
- mPending.getTotalBytes());
- }
- getOrLoadCompleteLocked().dumpDebug(proto,
- NetworkStatsRecorderProto.COMPLETE_HISTORY);
- proto.end(start);
- }
-
- public void dumpCheckin(PrintWriter pw, long start, long end) {
- // Only load and dump stats from the requested window
- getOrLoadPartialLocked(start, end).dumpCheckin(pw, start, end);
- }
-
- /**
- * Recover from {@link FileRotator} failure by dumping state to
- * {@link DropBoxManager} and deleting contents.
- */
- private void recoverFromWtf() {
- if (DUMP_BEFORE_DELETE) {
- final ByteArrayOutputStream os = new ByteArrayOutputStream();
- try {
- mRotator.dumpAll(os);
- } catch (IOException e) {
- // ignore partial contents
- os.reset();
- } finally {
- IoUtils.closeQuietly(os);
- }
- mDropBox.addData(TAG_NETSTATS_DUMP, os.toByteArray(), 0);
- }
-
- mRotator.deleteAll();
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
deleted file mode 100644
index e3794e4..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
+++ /dev/null
@@ -1,2528 +0,0 @@
-/*
- * Copyright (C) 2011 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.net;
-
-import static android.Manifest.permission.NETWORK_STATS_PROVIDER;
-import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
-import static android.Manifest.permission.UPDATE_DEVICE_STATS;
-import static android.app.usage.NetworkStatsManager.PREFIX_DEV;
-import static android.content.Intent.ACTION_SHUTDOWN;
-import static android.content.Intent.ACTION_UID_REMOVED;
-import static android.content.Intent.ACTION_USER_REMOVED;
-import static android.content.Intent.EXTRA_UID;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
-import static android.net.NetworkStats.IFACE_ALL;
-import static android.net.NetworkStats.IFACE_VT;
-import static android.net.NetworkStats.INTERFACES_ALL;
-import static android.net.NetworkStats.METERED_ALL;
-import static android.net.NetworkStats.ROAMING_ALL;
-import static android.net.NetworkStats.SET_ALL;
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.SET_FOREGROUND;
-import static android.net.NetworkStats.STATS_PER_IFACE;
-import static android.net.NetworkStats.STATS_PER_UID;
-import static android.net.NetworkStats.TAG_ALL;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
-import static android.net.NetworkStatsHistory.FIELD_ALL;
-import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
-import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
-import static android.net.TrafficStats.KB_IN_BYTES;
-import static android.net.TrafficStats.MB_IN_BYTES;
-import static android.net.TrafficStats.UID_TETHERING;
-import static android.net.TrafficStats.UNSUPPORTED;
-import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID;
-import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG;
-import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
-import static android.os.Trace.TRACE_TAG_NETWORK;
-import static android.system.OsConstants.ENOENT;
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-import static android.text.format.DateUtils.DAY_IN_MILLIS;
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
-import static android.text.format.DateUtils.SECOND_IN_MILLIS;
-
-import static com.android.net.module.util.NetworkCapabilitiesUtils.getDisplayTransport;
-import static com.android.net.module.util.NetworkStatsUtils.LIMIT_GLOBAL_ALERT;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.TargetApi;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.app.usage.NetworkStatsManager;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.database.ContentObserver;
-import android.net.DataUsageRequest;
-import android.net.INetd;
-import android.net.INetworkStatsService;
-import android.net.INetworkStatsSession;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkIdentity;
-import android.net.NetworkIdentitySet;
-import android.net.NetworkPolicyManager;
-import android.net.NetworkSpecifier;
-import android.net.NetworkStack;
-import android.net.NetworkStateSnapshot;
-import android.net.NetworkStats;
-import android.net.NetworkStats.NonMonotonicObserver;
-import android.net.NetworkStatsAccess;
-import android.net.NetworkStatsCollection;
-import android.net.NetworkStatsHistory;
-import android.net.NetworkTemplate;
-import android.net.TelephonyNetworkSpecifier;
-import android.net.TetherStatsParcel;
-import android.net.TetheringManager;
-import android.net.TrafficStats;
-import android.net.UnderlyingNetworkInfo;
-import android.net.Uri;
-import android.net.netstats.IUsageCallback;
-import android.net.netstats.provider.INetworkStatsProvider;
-import android.net.netstats.provider.INetworkStatsProviderCallback;
-import android.net.netstats.provider.NetworkStatsProvider;
-import android.os.Binder;
-import android.os.Build;
-import android.os.DropBoxManager;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.os.SystemClock;
-import android.os.Trace;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.provider.Settings.Global;
-import android.service.NetworkInterfaceProto;
-import android.service.NetworkStatsServiceDumpProto;
-import android.system.ErrnoException;
-import android.telephony.PhoneStateListener;
-import android.telephony.SubscriptionPlan;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.EventLog;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.SparseIntArray;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FileRotator;
-import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
-import com.android.net.module.util.BestClock;
-import com.android.net.module.util.BinderUtils;
-import com.android.net.module.util.BpfMap;
-import com.android.net.module.util.CollectionUtils;
-import com.android.net.module.util.IBpfMap;
-import com.android.net.module.util.LocationPermissionChecker;
-import com.android.net.module.util.NetworkStatsUtils;
-import com.android.net.module.util.PermissionUtils;
-import com.android.net.module.util.Struct.U32;
-import com.android.net.module.util.Struct.U8;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.time.Clock;
-import java.time.ZoneOffset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Collect and persist detailed network statistics, and provide this data to
- * other system services.
- */
-@TargetApi(Build.VERSION_CODES.TIRAMISU)
-public class NetworkStatsService extends INetworkStatsService.Stub {
- static {
- System.loadLibrary("service-connectivity");
- }
-
- static final String TAG = "NetworkStats";
- static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
- static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
-
- // Perform polling and persist all (FLAG_PERSIST_ALL).
- private static final int MSG_PERFORM_POLL = 1;
- // Perform polling, persist network, and register the global alert again.
- private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
- private static final int MSG_NOTIFY_NETWORK_STATUS = 3;
- // A message for broadcasting ACTION_NETWORK_STATS_UPDATED in handler thread to prevent
- // deadlock.
- private static final int MSG_BROADCAST_NETWORK_STATS_UPDATED = 4;
-
- /** Flags to control detail level of poll event. */
- private static final int FLAG_PERSIST_NETWORK = 0x1;
- private static final int FLAG_PERSIST_UID = 0x2;
- private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
- private static final int FLAG_PERSIST_FORCE = 0x100;
-
- /**
- * When global alert quota is high, wait for this delay before processing each polling,
- * and do not schedule further polls once there is already one queued.
- * This avoids firing the global alert too often on devices with high transfer speeds and
- * high quota.
- */
- private static final int DEFAULT_PERFORM_POLL_DELAY_MS = 1000;
-
- private static final String TAG_NETSTATS_ERROR = "netstats_error";
-
- /**
- * EventLog tags used when logging into the event log. Note the values must be sync with
- * frameworks/base/services/core/java/com/android/server/EventLogTags.logtags to get correct
- * name translation.
- */
- private static final int LOG_TAG_NETSTATS_MOBILE_SAMPLE = 51100;
- private static final int LOG_TAG_NETSTATS_WIFI_SAMPLE = 51101;
-
- // TODO: Replace the hardcoded string and move it into ConnectivitySettingsManager.
- private static final String NETSTATS_COMBINE_SUBTYPE_ENABLED =
- "netstats_combine_subtype_enabled";
-
- // This is current path but may be changed soon.
- private static final String UID_COUNTERSET_MAP_PATH =
- "/sys/fs/bpf/map_netd_uid_counterset_map";
- private static final String COOKIE_TAG_MAP_PATH =
- "/sys/fs/bpf/map_netd_cookie_tag_map";
- private static final String APP_UID_STATS_MAP_PATH =
- "/sys/fs/bpf/map_netd_app_uid_stats_map";
- private static final String STATS_MAP_A_PATH =
- "/sys/fs/bpf/map_netd_stats_map_A";
- private static final String STATS_MAP_B_PATH =
- "/sys/fs/bpf/map_netd_stats_map_B";
-
- private final Context mContext;
- private final NetworkStatsFactory mStatsFactory;
- private final AlarmManager mAlarmManager;
- private final Clock mClock;
- private final NetworkStatsSettings mSettings;
- private final NetworkStatsObservers mStatsObservers;
-
- private final File mSystemDir;
- private final File mBaseDir;
-
- private final PowerManager.WakeLock mWakeLock;
-
- private final ContentObserver mContentObserver;
- private final ContentResolver mContentResolver;
-
- protected INetd mNetd;
- private final AlertObserver mAlertObserver = new AlertObserver();
-
- @VisibleForTesting
- public static final String ACTION_NETWORK_STATS_POLL =
- "com.android.server.action.NETWORK_STATS_POLL";
- public static final String ACTION_NETWORK_STATS_UPDATED =
- "com.android.server.action.NETWORK_STATS_UPDATED";
-
- private PendingIntent mPollIntent;
-
- /**
- * Settings that can be changed externally.
- */
- public interface NetworkStatsSettings {
- long getPollInterval();
- long getPollDelay();
- boolean getSampleEnabled();
- boolean getAugmentEnabled();
- /**
- * When enabled, all mobile data is reported under {@link NetworkTemplate#NETWORK_TYPE_ALL}.
- * When disabled, mobile data is broken down by a granular ratType representative of the
- * actual ratType. {@see android.app.usage.NetworkStatsManager#getCollapsedRatType}.
- * Enabling this decreases the level of detail but saves performance, disk space and
- * amount of data logged.
- */
- boolean getCombineSubtypeEnabled();
-
- class Config {
- public final long bucketDuration;
- public final long rotateAgeMillis;
- public final long deleteAgeMillis;
-
- public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
- this.bucketDuration = bucketDuration;
- this.rotateAgeMillis = rotateAgeMillis;
- this.deleteAgeMillis = deleteAgeMillis;
- }
- }
-
- Config getDevConfig();
- Config getXtConfig();
- Config getUidConfig();
- Config getUidTagConfig();
-
- long getGlobalAlertBytes(long def);
- long getDevPersistBytes(long def);
- long getXtPersistBytes(long def);
- long getUidPersistBytes(long def);
- long getUidTagPersistBytes(long def);
- }
-
- private final Object mStatsLock = new Object();
-
- /** Set of currently active ifaces. */
- @GuardedBy("mStatsLock")
- private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
-
- /** Set of currently active ifaces for UID stats. */
- @GuardedBy("mStatsLock")
- private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
-
- /** Current default active iface. */
- @GuardedBy("mStatsLock")
- private String mActiveIface;
-
- /** Set of any ifaces associated with mobile networks since boot. */
- private volatile String[] mMobileIfaces = new String[0];
-
- /** Set of any ifaces associated with wifi networks since boot. */
- private volatile String[] mWifiIfaces = new String[0];
-
- /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
- @GuardedBy("mStatsLock")
- private Network[] mDefaultNetworks = new Network[0];
-
- /** Last states of all networks sent from ConnectivityService. */
- @GuardedBy("mStatsLock")
- @Nullable
- private NetworkStateSnapshot[] mLastNetworkStateSnapshots = null;
-
- private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
- new DropBoxNonMonotonicObserver();
-
- private static final int MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS = 100;
- private final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList =
- new CopyOnWriteArrayList<>();
- /** Semaphore used to wait for stats provider to respond to request stats update. */
- private final Semaphore mStatsProviderSem = new Semaphore(0, true);
-
- @GuardedBy("mStatsLock")
- private NetworkStatsRecorder mDevRecorder;
- @GuardedBy("mStatsLock")
- private NetworkStatsRecorder mXtRecorder;
- @GuardedBy("mStatsLock")
- private NetworkStatsRecorder mUidRecorder;
- @GuardedBy("mStatsLock")
- private NetworkStatsRecorder mUidTagRecorder;
-
- /** Cached {@link #mXtRecorder} stats. */
- @GuardedBy("mStatsLock")
- private NetworkStatsCollection mXtStatsCached;
-
- /**
- * Current counter sets for each UID.
- * TODO: maybe remove mActiveUidCounterSet and read UidCouneterSet value from mUidCounterSetMap
- * directly ? But if mActiveUidCounterSet would be accessed very frequently, maybe keep
- * mActiveUidCounterSet to avoid accessing kernel too frequently.
- */
- private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
- private final IBpfMap<U32, U8> mUidCounterSetMap;
- private final IBpfMap<CookieTagMapKey, CookieTagMapValue> mCookieTagMap;
- private final IBpfMap<StatsMapKey, StatsMapValue> mStatsMapA;
- private final IBpfMap<StatsMapKey, StatsMapValue> mStatsMapB;
- private final IBpfMap<UidStatsMapKey, StatsMapValue> mAppUidStatsMap;
-
- /** Data layer operation counters for splicing into other structures. */
- private NetworkStats mUidOperations = new NetworkStats(0L, 10);
-
- @NonNull
- private final Handler mHandler;
-
- private volatile boolean mSystemReady;
- private long mPersistThreshold = 2 * MB_IN_BYTES;
- private long mGlobalAlertBytes;
-
- private static final long POLL_RATE_LIMIT_MS = 15_000;
-
- private long mLastStatsSessionPoll;
-
- /** Map from UID to number of opened sessions */
- @GuardedBy("mOpenSessionCallsPerUid")
- private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
-
- private final static int DUMP_STATS_SESSION_COUNT = 20;
-
- @NonNull
- private final Dependencies mDeps;
-
- @NonNull
- private final NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
-
- @NonNull
- private final LocationPermissionChecker mLocationPermissionChecker;
-
- @NonNull
- private final BpfInterfaceMapUpdater mInterfaceMapUpdater;
-
- private static @NonNull File getDefaultSystemDir() {
- return new File(Environment.getDataDirectory(), "system");
- }
-
- private static @NonNull File getDefaultBaseDir() {
- File baseDir = new File(getDefaultSystemDir(), "netstats");
- baseDir.mkdirs();
- return baseDir;
- }
-
- private static @NonNull Clock getDefaultClock() {
- return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
- Clock.systemUTC());
- }
-
- private final class NetworkStatsHandler extends Handler {
- NetworkStatsHandler(@NonNull Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_PERFORM_POLL: {
- performPoll(FLAG_PERSIST_ALL);
- break;
- }
- case MSG_NOTIFY_NETWORK_STATUS: {
- // If no cached states, ignore.
- if (mLastNetworkStateSnapshots == null) break;
- // TODO (b/181642673): Protect mDefaultNetworks from concurrent accessing.
- handleNotifyNetworkStatus(
- mDefaultNetworks, mLastNetworkStateSnapshots, mActiveIface);
- break;
- }
- case MSG_PERFORM_POLL_REGISTER_ALERT: {
- performPoll(FLAG_PERSIST_NETWORK);
- registerGlobalAlert();
- break;
- }
- case MSG_BROADCAST_NETWORK_STATS_UPDATED: {
- final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
- updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
- READ_NETWORK_USAGE_HISTORY);
- break;
- }
- }
- }
- }
-
- /** Creates a new NetworkStatsService */
- public static NetworkStatsService create(Context context) {
- AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- PowerManager.WakeLock wakeLock =
- powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
- final INetd netd = INetd.Stub.asInterface(
- (IBinder) context.getSystemService(Context.NETD_SERVICE));
- final NetworkStatsService service = new NetworkStatsService(context,
- INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)),
- alarmManager, wakeLock, getDefaultClock(),
- new DefaultNetworkStatsSettings(), new NetworkStatsFactory(context),
- new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(),
- new Dependencies());
-
- return service;
- }
-
- // This must not be called outside of tests, even within the same package, as this constructor
- // does not register the local service. Use the create() helper above.
- @VisibleForTesting
- NetworkStatsService(Context context, INetd netd, AlarmManager alarmManager,
- PowerManager.WakeLock wakeLock, Clock clock, NetworkStatsSettings settings,
- NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir,
- File baseDir, @NonNull Dependencies deps) {
- mContext = Objects.requireNonNull(context, "missing Context");
- mNetd = Objects.requireNonNull(netd, "missing Netd");
- mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager");
- mClock = Objects.requireNonNull(clock, "missing Clock");
- mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings");
- mWakeLock = Objects.requireNonNull(wakeLock, "missing WakeLock");
- mStatsFactory = Objects.requireNonNull(factory, "missing factory");
- mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers");
- mSystemDir = Objects.requireNonNull(systemDir, "missing systemDir");
- mBaseDir = Objects.requireNonNull(baseDir, "missing baseDir");
- mDeps = Objects.requireNonNull(deps, "missing Dependencies");
-
- final HandlerThread handlerThread = mDeps.makeHandlerThread();
- handlerThread.start();
- mHandler = new NetworkStatsHandler(handlerThread.getLooper());
- mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext,
- (command) -> mHandler.post(command) , this);
- mContentResolver = mContext.getContentResolver();
- mContentObserver = mDeps.makeContentObserver(mHandler, mSettings,
- mNetworkStatsSubscriptionsMonitor);
- mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);
- mInterfaceMapUpdater = mDeps.makeBpfInterfaceMapUpdater(mContext, mHandler);
- mInterfaceMapUpdater.start();
- mUidCounterSetMap = mDeps.getUidCounterSetMap();
- mCookieTagMap = mDeps.getCookieTagMap();
- mStatsMapA = mDeps.getStatsMapA();
- mStatsMapB = mDeps.getStatsMapB();
- mAppUidStatsMap = mDeps.getAppUidStatsMap();
- }
-
- /**
- * Dependencies of NetworkStatsService, for injection in tests.
- */
- // TODO: Move more stuff into dependencies object.
- @VisibleForTesting
- public static class Dependencies {
- /**
- * Create a HandlerThread to use in NetworkStatsService.
- */
- @NonNull
- public HandlerThread makeHandlerThread() {
- return new HandlerThread(TAG);
- }
-
- /**
- * Create a {@link NetworkStatsSubscriptionsMonitor}, can be used to monitor RAT change
- * event in NetworkStatsService.
- */
- @NonNull
- public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(@NonNull Context context,
- @NonNull Executor executor, @NonNull NetworkStatsService service) {
- // TODO: Update RatType passively in NSS, instead of querying into the monitor
- // when notifyNetworkStatus.
- return new NetworkStatsSubscriptionsMonitor(context, executor,
- (subscriberId, type) -> service.handleOnCollapsedRatTypeChanged());
- }
-
- /**
- * Create a ContentObserver instance which is used to observe settings changes,
- * and dispatch onChange events on handler thread.
- */
- public @NonNull ContentObserver makeContentObserver(@NonNull Handler handler,
- @NonNull NetworkStatsSettings settings,
- @NonNull NetworkStatsSubscriptionsMonitor monitor) {
- return new ContentObserver(handler) {
- @Override
- public void onChange(boolean selfChange, @NonNull Uri uri) {
- if (!settings.getCombineSubtypeEnabled()) {
- monitor.start();
- } else {
- monitor.stop();
- }
- }
- };
- }
-
- /**
- * @see LocationPermissionChecker
- */
- public LocationPermissionChecker makeLocationPermissionChecker(final Context context) {
- return new LocationPermissionChecker(context);
- }
-
- /** Create BpfInterfaceMapUpdater to update bpf interface map. */
- @NonNull
- public BpfInterfaceMapUpdater makeBpfInterfaceMapUpdater(
- @NonNull Context ctx, @NonNull Handler handler) {
- return new BpfInterfaceMapUpdater(ctx, handler);
- }
-
- /** Get counter sets map for each UID. */
- public IBpfMap<U32, U8> getUidCounterSetMap() {
- try {
- return new BpfMap<U32, U8>(UID_COUNTERSET_MAP_PATH, BpfMap.BPF_F_RDWR,
- U32.class, U8.class);
- } catch (ErrnoException e) {
- Log.wtf(TAG, "Cannot open uid counter set map: " + e);
- return null;
- }
- }
-
- /** Gets the cookie tag map */
- public IBpfMap<CookieTagMapKey, CookieTagMapValue> getCookieTagMap() {
- try {
- return new BpfMap<CookieTagMapKey, CookieTagMapValue>(COOKIE_TAG_MAP_PATH,
- BpfMap.BPF_F_RDWR, CookieTagMapKey.class, CookieTagMapValue.class);
- } catch (ErrnoException e) {
- Log.wtf(TAG, "Cannot open cookie tag map: " + e);
- return null;
- }
- }
-
- /** Gets stats map A */
- public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapA() {
- try {
- return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_A_PATH,
- BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class);
- } catch (ErrnoException e) {
- Log.wtf(TAG, "Cannot open stats map A: " + e);
- return null;
- }
- }
-
- /** Gets stats map B */
- public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapB() {
- try {
- return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_B_PATH,
- BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class);
- } catch (ErrnoException e) {
- Log.wtf(TAG, "Cannot open stats map B: " + e);
- return null;
- }
- }
-
- /** Gets the uid stats map */
- public IBpfMap<UidStatsMapKey, StatsMapValue> getAppUidStatsMap() {
- try {
- return new BpfMap<UidStatsMapKey, StatsMapValue>(APP_UID_STATS_MAP_PATH,
- BpfMap.BPF_F_RDWR, UidStatsMapKey.class, StatsMapValue.class);
- } catch (ErrnoException e) {
- Log.wtf(TAG, "Cannot open app uid stats map: " + e);
- return null;
- }
- }
- }
-
- /**
- * Observer that watches for {@link INetdUnsolicitedEventListener} alerts.
- */
- @VisibleForTesting
- public class AlertObserver extends BaseNetdUnsolicitedEventListener {
- @Override
- public void onQuotaLimitReached(@NonNull String alertName, @NonNull String ifName) {
- PermissionUtils.enforceNetworkStackPermission(mContext);
-
- if (LIMIT_GLOBAL_ALERT.equals(alertName)) {
- // kick off background poll to collect network stats unless there is already
- // such a call pending; UID stats are handled during normal polling interval.
- if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
- mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
- mSettings.getPollDelay());
- }
- }
- }
- }
-
- public void systemReady() {
- synchronized (mStatsLock) {
- mSystemReady = true;
-
- // create data recorders along with historical rotators
- mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
- mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
- mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
- mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
-
- updatePersistThresholdsLocked();
-
- // upgrade any legacy stats, migrating them to rotated files
- maybeUpgradeLegacyStatsLocked();
-
- // read historical network stats from disk, since policy service
- // might need them right away.
- mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
-
- // bootstrap initial stats to prevent double-counting later
- bootstrapStatsLocked();
- }
-
- // watch for tethering changes
- final TetheringManager tetheringManager = mContext.getSystemService(TetheringManager.class);
- tetheringManager.registerTetheringEventCallback(
- (command) -> mHandler.post(command), mTetherListener);
-
- // listen for periodic polling events
- final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
- mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
-
- // listen for uid removal to clean stats
- final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
- mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
-
- // listen for user changes to clean stats
- final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
- mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
-
- // persist stats during clean shutdown
- final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
- mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
-
- try {
- mNetd.registerUnsolicitedEventListener(mAlertObserver);
- } catch (RemoteException | ServiceSpecificException e) {
- Log.wtf(TAG, "Error registering event listener :", e);
- }
-
- // schedule periodic pall alarm based on {@link NetworkStatsSettings#getPollInterval()}.
- final PendingIntent pollIntent =
- PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL),
- PendingIntent.FLAG_IMMUTABLE);
-
- final long currentRealtime = SystemClock.elapsedRealtime();
- mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
- mSettings.getPollInterval(), pollIntent);
-
- mContentResolver.registerContentObserver(Settings.Global
- .getUriFor(NETSTATS_COMBINE_SUBTYPE_ENABLED),
- false /* notifyForDescendants */, mContentObserver);
-
- // Post a runnable on handler thread to call onChange(). It's for getting current value of
- // NETSTATS_COMBINE_SUBTYPE_ENABLED to decide start or stop monitoring RAT type changes.
- mHandler.post(() -> mContentObserver.onChange(false, Settings.Global
- .getUriFor(NETSTATS_COMBINE_SUBTYPE_ENABLED)));
-
- registerGlobalAlert();
- }
-
- private NetworkStatsRecorder buildRecorder(
- String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
- final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
- Context.DROPBOX_SERVICE);
- return new NetworkStatsRecorder(new FileRotator(
- mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
- mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
- }
-
- @GuardedBy("mStatsLock")
- private void shutdownLocked() {
- final TetheringManager tetheringManager = mContext.getSystemService(TetheringManager.class);
- tetheringManager.unregisterTetheringEventCallback(mTetherListener);
- mContext.unregisterReceiver(mPollReceiver);
- mContext.unregisterReceiver(mRemovedReceiver);
- mContext.unregisterReceiver(mUserReceiver);
- mContext.unregisterReceiver(mShutdownReceiver);
-
- if (!mSettings.getCombineSubtypeEnabled()) {
- mNetworkStatsSubscriptionsMonitor.stop();
- }
-
- mContentResolver.unregisterContentObserver(mContentObserver);
-
- final long currentTime = mClock.millis();
-
- // persist any pending stats
- mDevRecorder.forcePersistLocked(currentTime);
- mXtRecorder.forcePersistLocked(currentTime);
- mUidRecorder.forcePersistLocked(currentTime);
- mUidTagRecorder.forcePersistLocked(currentTime);
-
- mSystemReady = false;
- }
-
- @GuardedBy("mStatsLock")
- private void maybeUpgradeLegacyStatsLocked() {
- File file;
- try {
- file = new File(mSystemDir, "netstats.bin");
- if (file.exists()) {
- mDevRecorder.importLegacyNetworkLocked(file);
- file.delete();
- }
-
- file = new File(mSystemDir, "netstats_xt.bin");
- if (file.exists()) {
- file.delete();
- }
-
- file = new File(mSystemDir, "netstats_uid.bin");
- if (file.exists()) {
- mUidRecorder.importLegacyUidLocked(file);
- mUidTagRecorder.importLegacyUidLocked(file);
- file.delete();
- }
- } catch (IOException e) {
- Log.wtf(TAG, "problem during legacy upgrade", e);
- } catch (OutOfMemoryError e) {
- Log.wtf(TAG, "problem during legacy upgrade", e);
- }
- }
-
- /**
- * Register for a global alert that is delivered through {@link AlertObserver}
- * or {@link NetworkStatsProviderCallback#onAlertReached()} once a threshold amount of data has
- * been transferred.
- */
- private void registerGlobalAlert() {
- try {
- mNetd.bandwidthSetGlobalAlert(mGlobalAlertBytes);
- } catch (IllegalStateException e) {
- Log.w(TAG, "problem registering for global alert: " + e);
- } catch (RemoteException e) {
- // ignored; service lives in system_server
- }
- invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetAlert(mGlobalAlertBytes));
- }
-
- @Override
- public INetworkStatsSession openSession() {
- return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
- }
-
- @Override
- public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
- return openSessionInternal(flags, callingPackage);
- }
-
- private boolean isRateLimitedForPoll(int callingUid) {
- if (callingUid == android.os.Process.SYSTEM_UID) {
- return false;
- }
-
- final long lastCallTime;
- final long now = SystemClock.elapsedRealtime();
- synchronized (mOpenSessionCallsPerUid) {
- int calls = mOpenSessionCallsPerUid.get(callingUid, 0);
- mOpenSessionCallsPerUid.put(callingUid, calls + 1);
- lastCallTime = mLastStatsSessionPoll;
- mLastStatsSessionPoll = now;
- }
-
- return now - lastCallTime < POLL_RATE_LIMIT_MS;
- }
-
- private int restrictFlagsForCaller(int flags) {
- // All non-privileged callers are not allowed to turn off POLL_ON_OPEN.
- final boolean isPrivileged = PermissionUtils.checkAnyPermissionOf(mContext,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- android.Manifest.permission.NETWORK_STACK);
- if (!isPrivileged) {
- flags |= NetworkStatsManager.FLAG_POLL_ON_OPEN;
- }
- // Non-system uids are rate limited for POLL_ON_OPEN.
- final int callingUid = Binder.getCallingUid();
- flags = isRateLimitedForPoll(callingUid)
- ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
- : flags;
- return flags;
- }
-
- private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
- final int restrictedFlags = restrictFlagsForCaller(flags);
- if ((restrictedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
- | NetworkStatsManager.FLAG_POLL_FORCE)) != 0) {
- final long ident = Binder.clearCallingIdentity();
- try {
- performPoll(FLAG_PERSIST_ALL);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- // return an IBinder which holds strong references to any loaded stats
- // for its lifetime; when caller closes only weak references remain.
-
- return new INetworkStatsSession.Stub() {
- private final int mCallingUid = Binder.getCallingUid();
- private final String mCallingPackage = callingPackage;
- private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
- callingPackage);
-
- private NetworkStatsCollection mUidComplete;
- private NetworkStatsCollection mUidTagComplete;
-
- private NetworkStatsCollection getUidComplete() {
- synchronized (mStatsLock) {
- if (mUidComplete == null) {
- mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
- }
- return mUidComplete;
- }
- }
-
- private NetworkStatsCollection getUidTagComplete() {
- synchronized (mStatsLock) {
- if (mUidTagComplete == null) {
- mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
- }
- return mUidTagComplete;
- }
- }
-
- @Override
- public int[] getRelevantUids() {
- return getUidComplete().getRelevantUids(mAccessLevel);
- }
-
- @Override
- public NetworkStats getDeviceSummaryForNetwork(
- NetworkTemplate template, long start, long end) {
- enforceTemplatePermissions(template, callingPackage);
- return internalGetSummaryForNetwork(template, restrictedFlags, start, end,
- mAccessLevel, mCallingUid);
- }
-
- @Override
- public NetworkStats getSummaryForNetwork(
- NetworkTemplate template, long start, long end) {
- enforceTemplatePermissions(template, callingPackage);
- return internalGetSummaryForNetwork(template, restrictedFlags, start, end,
- mAccessLevel, mCallingUid);
- }
-
- // TODO: Remove this after all callers are removed.
- @Override
- public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
- enforceTemplatePermissions(template, callingPackage);
- return internalGetHistoryForNetwork(template, restrictedFlags, fields,
- mAccessLevel, mCallingUid, Long.MIN_VALUE, Long.MAX_VALUE);
- }
-
- @Override
- public NetworkStatsHistory getHistoryIntervalForNetwork(NetworkTemplate template,
- int fields, long start, long end) {
- enforceTemplatePermissions(template, callingPackage);
- // TODO(b/200768422): Redact returned history if the template is location
- // sensitive but the caller is not privileged.
- return internalGetHistoryForNetwork(template, restrictedFlags, fields,
- mAccessLevel, mCallingUid, start, end);
- }
-
- @Override
- public NetworkStats getSummaryForAllUid(
- NetworkTemplate template, long start, long end, boolean includeTags) {
- enforceTemplatePermissions(template, callingPackage);
- try {
- final NetworkStats stats = getUidComplete()
- .getSummary(template, start, end, mAccessLevel, mCallingUid);
- if (includeTags) {
- final NetworkStats tagStats = getUidTagComplete()
- .getSummary(template, start, end, mAccessLevel, mCallingUid);
- stats.combineAllValues(tagStats);
- }
- return stats;
- } catch (NullPointerException e) {
- throw e;
- }
- }
-
- @Override
- public NetworkStats getTaggedSummaryForAllUid(
- NetworkTemplate template, long start, long end) {
- enforceTemplatePermissions(template, callingPackage);
- try {
- final NetworkStats tagStats = getUidTagComplete()
- .getSummary(template, start, end, mAccessLevel, mCallingUid);
- return tagStats;
- } catch (NullPointerException e) {
- throw e;
- }
- }
-
- @Override
- public NetworkStatsHistory getHistoryForUid(
- NetworkTemplate template, int uid, int set, int tag, int fields) {
- enforceTemplatePermissions(template, callingPackage);
- // NOTE: We don't augment UID-level statistics
- if (tag == TAG_NONE) {
- return getUidComplete().getHistory(template, null, uid, set, tag, fields,
- Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
- } else {
- return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
- Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
- }
- }
-
- @Override
- public NetworkStatsHistory getHistoryIntervalForUid(
- NetworkTemplate template, int uid, int set, int tag, int fields,
- long start, long end) {
- enforceTemplatePermissions(template, callingPackage);
- // TODO(b/200768422): Redact returned history if the template is location
- // sensitive but the caller is not privileged.
- // NOTE: We don't augment UID-level statistics
- if (tag == TAG_NONE) {
- return getUidComplete().getHistory(template, null, uid, set, tag, fields,
- start, end, mAccessLevel, mCallingUid);
- } else if (uid == Binder.getCallingUid()) {
- return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
- start, end, mAccessLevel, mCallingUid);
- } else {
- throw new SecurityException("Calling package " + mCallingPackage
- + " cannot access tag information from a different uid");
- }
- }
-
- @Override
- public void close() {
- mUidComplete = null;
- mUidTagComplete = null;
- }
- };
- }
-
- private void enforceTemplatePermissions(@NonNull NetworkTemplate template,
- @NonNull String callingPackage) {
- // For a template with wifi network keys, it is possible for a malicious
- // client to track the user locations via querying data usage. Thus, enforce
- // fine location permission check.
- if (!template.getWifiNetworkKeys().isEmpty()) {
- final boolean canAccessFineLocation = mLocationPermissionChecker
- .checkCallersLocationPermission(callingPackage,
- null /* featureId */,
- Binder.getCallingUid(),
- false /* coarseForTargetSdkLessThanQ */,
- null /* message */);
- if (!canAccessFineLocation) {
- throw new SecurityException("Access fine location is required when querying"
- + " with wifi network keys, make sure the app has the necessary"
- + "permissions and the location toggle is on.");
- }
- }
- }
-
- private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
- return NetworkStatsAccess.checkAccessLevel(
- mContext, Binder.getCallingPid(), Binder.getCallingUid(), callingPackage);
- }
-
- /**
- * Find the most relevant {@link SubscriptionPlan} for the given
- * {@link NetworkTemplate} and flags. This is typically used to augment
- * local measurement results to match a known anchor from the carrier.
- */
- private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
- SubscriptionPlan plan = null;
- if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
- && mSettings.getAugmentEnabled()) {
- if (LOGD) Log.d(TAG, "Resolving plan for " + template);
- final long token = Binder.clearCallingIdentity();
- try {
- plan = mContext.getSystemService(NetworkPolicyManager.class)
- .getSubscriptionPlan(template);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- if (LOGD) Log.d(TAG, "Resolved to plan " + plan);
- }
- return plan;
- }
-
- /**
- * Return network summary, splicing between DEV and XT stats when
- * appropriate.
- */
- private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
- long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
- // We've been using pure XT stats long enough that we no longer need to
- // splice DEV and XT together.
- final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
- accessLevel, callingUid, start, end);
-
- final long now = System.currentTimeMillis();
- final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
-
- final NetworkStats stats = new NetworkStats(end - start, 1);
- stats.insertEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
- entry.txBytes, entry.txPackets, entry.operations));
- return stats;
- }
-
- /**
- * Return network history, splicing between DEV and XT stats when
- * appropriate.
- */
- private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
- int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid,
- long start, long end) {
- // We've been using pure XT stats long enough that we no longer need to
- // splice DEV and XT together.
- final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
- synchronized (mStatsLock) {
- return mXtStatsCached.getHistory(template, augmentPlan,
- UID_ALL, SET_ALL, TAG_NONE, fields, start, end, accessLevel, callingUid);
- }
- }
-
- private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
- assertSystemReady();
-
- return internalGetSummaryForNetwork(template,
- NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
- NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
- }
-
- private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
- assertSystemReady();
-
- final NetworkStatsCollection uidComplete;
- synchronized (mStatsLock) {
- uidComplete = mUidRecorder.getOrLoadCompleteLocked();
- }
- return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
- android.os.Process.SYSTEM_UID);
- }
-
- @Override
- public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
- if (Binder.getCallingUid() != uid) {
- Log.w(TAG, "Snapshots only available for calling UID");
- return new NetworkStats(SystemClock.elapsedRealtime(), 0);
- }
-
- // TODO: switch to data layer stats once kernel exports
- // for now, read network layer stats and flatten across all ifaces.
- // This function is used to query NeworkStats for calle's uid. The only caller method
- // TrafficStats#getDataLayerSnapshotForUid alrady claim no special permission to query
- // its own NetworkStats.
- final long ident = Binder.clearCallingIdentity();
- final NetworkStats networkLayer;
- try {
- networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
-
- // splice in operation counts
- networkLayer.spliceOperationsFrom(mUidOperations);
-
- final NetworkStats dataLayer = new NetworkStats(
- networkLayer.getElapsedRealtime(), networkLayer.size());
-
- NetworkStats.Entry entry = null;
- for (int i = 0; i < networkLayer.size(); i++) {
- entry = networkLayer.getValues(i, entry);
- entry.iface = IFACE_ALL;
- dataLayer.combineValues(entry);
- }
-
- return dataLayer;
- }
-
- @Override
- public NetworkStats getUidStatsForTransport(int transport) {
- PermissionUtils.enforceNetworkStackPermission(mContext);
- try {
- final String[] relevantIfaces =
- transport == TRANSPORT_WIFI ? mWifiIfaces : mMobileIfaces;
- // TODO(b/215633405) : mMobileIfaces and mWifiIfaces already contain the stacked
- // interfaces, so this is not useful, remove it.
- final String[] ifacesToQuery =
- mStatsFactory.augmentWithStackedInterfaces(relevantIfaces);
- return getNetworkStatsUidDetail(ifacesToQuery);
- } catch (RemoteException e) {
- Log.wtf(TAG, "Error compiling UID stats", e);
- return new NetworkStats(0L, 0);
- }
- }
-
- @Override
- public String[] getMobileIfaces() {
- // TODO (b/192758557): Remove debug log.
- if (CollectionUtils.contains(mMobileIfaces, null)) {
- throw new NullPointerException(
- "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces));
- }
- return mMobileIfaces.clone();
- }
-
- @Override
- public void incrementOperationCount(int uid, int tag, int operationCount) {
- if (Binder.getCallingUid() != uid) {
- mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG);
- }
-
- if (operationCount < 0) {
- throw new IllegalArgumentException("operation count can only be incremented");
- }
- if (tag == TAG_NONE) {
- throw new IllegalArgumentException("operation count must have specific tag");
- }
-
- synchronized (mStatsLock) {
- final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
- mUidOperations.combineValues(
- mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
- mUidOperations.combineValues(
- mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
- }
- }
-
- private void setKernelCounterSet(int uid, int set) {
- if (mUidCounterSetMap == null) {
- Log.wtf(TAG, "Fail to set UidCounterSet: Null bpf map");
- return;
- }
-
- if (set == SET_DEFAULT) {
- try {
- mUidCounterSetMap.deleteEntry(new U32(uid));
- } catch (ErrnoException e) {
- Log.w(TAG, "UidCounterSetMap.deleteEntry(" + uid + ") failed with errno: " + e);
- }
- return;
- }
-
- try {
- mUidCounterSetMap.updateEntry(new U32(uid), new U8((short) set));
- } catch (ErrnoException e) {
- Log.w(TAG, "UidCounterSetMap.updateEntry(" + uid + ", " + set
- + ") failed with errno: " + e);
- }
- }
-
- @VisibleForTesting
- public void noteUidForeground(int uid, boolean uidForeground) {
- PermissionUtils.enforceNetworkStackPermission(mContext);
- synchronized (mStatsLock) {
- final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
- final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
- if (oldSet != set) {
- mActiveUidCounterSet.put(uid, set);
- setKernelCounterSet(uid, set);
- }
- }
- }
-
- /**
- * Notify {@code NetworkStatsService} about network status changed.
- */
- public void notifyNetworkStatus(
- @NonNull Network[] defaultNetworks,
- @NonNull NetworkStateSnapshot[] networkStates,
- @Nullable String activeIface,
- @NonNull UnderlyingNetworkInfo[] underlyingNetworkInfos) {
- PermissionUtils.enforceNetworkStackPermission(mContext);
-
- final long token = Binder.clearCallingIdentity();
- try {
- handleNotifyNetworkStatus(defaultNetworks, networkStates, activeIface);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
-
- // Update the VPN underlying interfaces only after the poll is made and tun data has been
- // migrated. Otherwise the migration would use the new interfaces instead of the ones that
- // were current when the polled data was transferred.
- mStatsFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
- }
-
- @Override
- public void forceUpdate() {
- PermissionUtils.enforceNetworkStackPermission(mContext);
-
- final long token = Binder.clearCallingIdentity();
- try {
- performPoll(FLAG_PERSIST_ALL);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /** Advise persistence threshold; may be overridden internally. */
- public void advisePersistThreshold(long thresholdBytes) {
- PermissionUtils.enforceNetworkStackPermission(mContext);
- // clamp threshold into safe range
- mPersistThreshold = NetworkStatsUtils.constrain(thresholdBytes,
- 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
- if (LOGV) {
- Log.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
- + mPersistThreshold);
- }
-
- final long oldGlobalAlertBytes = mGlobalAlertBytes;
-
- // update and persist if beyond new thresholds
- final long currentTime = mClock.millis();
- synchronized (mStatsLock) {
- if (!mSystemReady) return;
-
- updatePersistThresholdsLocked();
-
- mDevRecorder.maybePersistLocked(currentTime);
- mXtRecorder.maybePersistLocked(currentTime);
- mUidRecorder.maybePersistLocked(currentTime);
- mUidTagRecorder.maybePersistLocked(currentTime);
- }
-
- if (oldGlobalAlertBytes != mGlobalAlertBytes) {
- registerGlobalAlert();
- }
- }
-
- @Override
- public DataUsageRequest registerUsageCallback(@NonNull String callingPackage,
- @NonNull DataUsageRequest request, @NonNull IUsageCallback callback) {
- Objects.requireNonNull(callingPackage, "calling package is null");
- Objects.requireNonNull(request, "DataUsageRequest is null");
- Objects.requireNonNull(request.template, "NetworkTemplate is null");
- Objects.requireNonNull(callback, "callback is null");
-
- int callingUid = Binder.getCallingUid();
- @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
- DataUsageRequest normalizedRequest;
- final long token = Binder.clearCallingIdentity();
- try {
- normalizedRequest = mStatsObservers.register(mContext,
- request, callback, callingUid, accessLevel);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
-
- // Create baseline stats
- mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL));
-
- return normalizedRequest;
- }
-
- @Override
- public void unregisterUsageRequest(DataUsageRequest request) {
- Objects.requireNonNull(request, "DataUsageRequest is null");
-
- int callingUid = Binder.getCallingUid();
- final long token = Binder.clearCallingIdentity();
- try {
- mStatsObservers.unregister(request, callingUid);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- @Override
- public long getUidStats(int uid, int type) {
- final int callingUid = Binder.getCallingUid();
- if (callingUid != android.os.Process.SYSTEM_UID && callingUid != uid) {
- return UNSUPPORTED;
- }
- return nativeGetUidStat(uid, type);
- }
-
- @Override
- public long getIfaceStats(@NonNull String iface, int type) {
- Objects.requireNonNull(iface);
- long nativeIfaceStats = nativeGetIfaceStat(iface, type);
- if (nativeIfaceStats == -1) {
- return nativeIfaceStats;
- } else {
- // When tethering offload is in use, nativeIfaceStats does not contain usage from
- // offload, add it back here. Note that the included statistics might be stale
- // since polling newest stats from hardware might impact system health and not
- // suitable for TrafficStats API use cases.
- return nativeIfaceStats + getProviderIfaceStats(iface, type);
- }
- }
-
- @Override
- public long getTotalStats(int type) {
- long nativeTotalStats = nativeGetTotalStat(type);
- if (nativeTotalStats == -1) {
- return nativeTotalStats;
- } else {
- // Refer to comment in getIfaceStats
- return nativeTotalStats + getProviderIfaceStats(IFACE_ALL, type);
- }
- }
-
- private long getProviderIfaceStats(@Nullable String iface, int type) {
- final NetworkStats providerSnapshot = getNetworkStatsFromProviders(STATS_PER_IFACE);
- final HashSet<String> limitIfaces;
- if (iface == IFACE_ALL) {
- limitIfaces = null;
- } else {
- limitIfaces = new HashSet<>();
- limitIfaces.add(iface);
- }
- final NetworkStats.Entry entry = providerSnapshot.getTotal(null, limitIfaces);
- switch (type) {
- case TrafficStats.TYPE_RX_BYTES:
- return entry.rxBytes;
- case TrafficStats.TYPE_RX_PACKETS:
- return entry.rxPackets;
- case TrafficStats.TYPE_TX_BYTES:
- return entry.txBytes;
- case TrafficStats.TYPE_TX_PACKETS:
- return entry.txPackets;
- default:
- return 0;
- }
- }
-
- /**
- * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
- * reflect current {@link #mPersistThreshold} value. Always defers to
- * {@link Global} values when defined.
- */
- @GuardedBy("mStatsLock")
- private void updatePersistThresholdsLocked() {
- mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
- mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
- mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
- mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
- mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
- }
-
- /**
- * Listener that watches for {@link TetheringManager} to claim interface pairs.
- */
- private final TetheringManager.TetheringEventCallback mTetherListener =
- new TetheringManager.TetheringEventCallback() {
- @Override
- public void onUpstreamChanged(@Nullable Network network) {
- performPoll(FLAG_PERSIST_NETWORK);
- }
- };
-
- private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- // on background handler thread, and verified UPDATE_DEVICE_STATS
- // permission above.
- performPoll(FLAG_PERSIST_ALL);
-
- // verify that we're watching global alert
- registerGlobalAlert();
- }
- };
-
- private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- // on background handler thread, and UID_REMOVED is protected
- // broadcast.
-
- final int uid = intent.getIntExtra(EXTRA_UID, -1);
- if (uid == -1) return;
-
- synchronized (mStatsLock) {
- mWakeLock.acquire();
- try {
- removeUidsLocked(uid);
- } finally {
- mWakeLock.release();
- }
- }
- }
- };
-
- private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- // On background handler thread, and USER_REMOVED is protected
- // broadcast.
-
- final UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
- if (userHandle == null) return;
-
- synchronized (mStatsLock) {
- mWakeLock.acquire();
- try {
- removeUserLocked(userHandle);
- } finally {
- mWakeLock.release();
- }
- }
- }
- };
-
- private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- // SHUTDOWN is protected broadcast.
- synchronized (mStatsLock) {
- shutdownLocked();
- }
- }
- };
-
- /**
- * Handle collapsed RAT type changed event.
- */
- @VisibleForTesting
- public void handleOnCollapsedRatTypeChanged() {
- // Protect service from frequently updating. Remove pending messages if any.
- mHandler.removeMessages(MSG_NOTIFY_NETWORK_STATUS);
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MSG_NOTIFY_NETWORK_STATUS), mSettings.getPollDelay());
- }
-
- private void handleNotifyNetworkStatus(
- Network[] defaultNetworks,
- NetworkStateSnapshot[] snapshots,
- String activeIface) {
- synchronized (mStatsLock) {
- mWakeLock.acquire();
- try {
- mActiveIface = activeIface;
- handleNotifyNetworkStatusLocked(defaultNetworks, snapshots);
- } finally {
- mWakeLock.release();
- }
- }
- }
-
- /**
- * Inspect all current {@link NetworkStateSnapshot}s to derive mapping from {@code iface} to
- * {@link NetworkStatsHistory}. When multiple networks are active on a single {@code iface},
- * they are combined under a single {@link NetworkIdentitySet}.
- */
- @GuardedBy("mStatsLock")
- private void handleNotifyNetworkStatusLocked(@NonNull Network[] defaultNetworks,
- @NonNull NetworkStateSnapshot[] snapshots) {
- if (!mSystemReady) return;
- if (LOGV) Log.v(TAG, "handleNotifyNetworkStatusLocked()");
-
- // take one last stats snapshot before updating iface mapping. this
- // isn't perfect, since the kernel may already be counting traffic from
- // the updated network.
-
- // poll, but only persist network stats to keep codepath fast. UID stats
- // will be persisted during next alarm poll event.
- performPollLocked(FLAG_PERSIST_NETWORK);
-
- // Rebuild active interfaces based on connected networks
- mActiveIfaces.clear();
- mActiveUidIfaces.clear();
- // Update the list of default networks.
- mDefaultNetworks = defaultNetworks;
-
- mLastNetworkStateSnapshots = snapshots;
-
- final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled();
- final ArraySet<String> mobileIfaces = new ArraySet<>();
- final ArraySet<String> wifiIfaces = new ArraySet<>();
- for (NetworkStateSnapshot snapshot : snapshots) {
- final int displayTransport =
- getDisplayTransport(snapshot.getNetworkCapabilities().getTransportTypes());
- final boolean isMobile = (NetworkCapabilities.TRANSPORT_CELLULAR == displayTransport);
- final boolean isWifi = (NetworkCapabilities.TRANSPORT_WIFI == displayTransport);
- final boolean isDefault = CollectionUtils.contains(
- mDefaultNetworks, snapshot.getNetwork());
- final int ratType = combineSubtypeEnabled ? NetworkTemplate.NETWORK_TYPE_ALL
- : getRatTypeForStateSnapshot(snapshot);
- final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot,
- isDefault, ratType);
-
- // Traffic occurring on the base interface is always counted for
- // both total usage and UID details.
- final String baseIface = snapshot.getLinkProperties().getInterfaceName();
- if (baseIface != null) {
- findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
- findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
-
- // Build a separate virtual interface for VT (Video Telephony) data usage.
- // Only do this when IMS is not metered, but VT is metered.
- // If IMS is metered, then the IMS network usage has already included VT usage.
- // VT is considered always metered in framework's layer. If VT is not metered
- // per carrier's policy, modem will report 0 usage for VT calls.
- if (snapshot.getNetworkCapabilities().hasCapability(
- NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.isMetered()) {
-
- // Copy the identify from IMS one but mark it as metered.
- NetworkIdentity vtIdent = new NetworkIdentity.Builder()
- .setType(ident.getType())
- .setRatType(ident.getRatType())
- .setSubscriberId(ident.getSubscriberId())
- .setWifiNetworkKey(ident.getWifiNetworkKey())
- .setRoaming(ident.isRoaming()).setMetered(true)
- .setDefaultNetwork(true)
- .setOemManaged(ident.getOemManaged())
- .setSubId(ident.getSubId()).build();
- final String ifaceVt = IFACE_VT + getSubIdForMobile(snapshot);
- findOrCreateNetworkIdentitySet(mActiveIfaces, ifaceVt).add(vtIdent);
- findOrCreateNetworkIdentitySet(mActiveUidIfaces, ifaceVt).add(vtIdent);
- }
-
- if (isMobile) {
- mobileIfaces.add(baseIface);
- }
- if (isWifi) {
- wifiIfaces.add(baseIface);
- }
- }
-
- // Traffic occurring on stacked interfaces is usually clatd.
- //
- // UID stats are always counted on the stacked interface and never on the base
- // interface, because the packets on the base interface do not actually match
- // application sockets (they're not IPv4) and thus the app uid is not known.
- // For receive this is obvious: packets must be translated from IPv6 to IPv4
- // before the application socket can be found.
- // For transmit: either they go through the clat daemon which by virtue of going
- // through userspace strips the original socket association during the IPv4 to
- // IPv6 translation process, or they are offloaded by eBPF, which doesn't:
- // However, on an ebpf device the accounting is done in cgroup ebpf hooks,
- // which don't trigger again post ebpf translation.
- // (as such stats accounted to the clat uid are ignored)
- //
- // Interface stats are more complicated.
- //
- // eBPF offloaded 464xlat'ed packets never hit base interface ip6tables, and thus
- // *all* statistics are collected by iptables on the stacked v4-* interface.
- //
- // Additionally for ingress all packets bound for the clat IPv6 address are dropped
- // in ip6tables raw prerouting and thus even non-offloaded packets are only
- // accounted for on the stacked interface.
- //
- // For egress, packets subject to eBPF offload never appear on the base interface
- // and only appear on the stacked interface. Thus to ensure packets increment
- // interface stats, we must collate data from stacked interfaces. For xt_qtaguid
- // (or non eBPF offloaded) TX they would appear on both, however egress interface
- // accounting is explicitly bypassed for traffic from the clat uid.
- //
- // TODO: This code might be combined to above code.
- for (String iface : snapshot.getLinkProperties().getAllInterfaceNames()) {
- // baseIface has been handled, so ignore it.
- if (TextUtils.equals(baseIface, iface)) continue;
- if (iface != null) {
- findOrCreateNetworkIdentitySet(mActiveIfaces, iface).add(ident);
- findOrCreateNetworkIdentitySet(mActiveUidIfaces, iface).add(ident);
- if (isMobile) {
- mobileIfaces.add(iface);
- }
- if (isWifi) {
- wifiIfaces.add(iface);
- }
-
- mStatsFactory.noteStackedIface(iface, baseIface);
- }
- }
- }
-
- mMobileIfaces = mobileIfaces.toArray(new String[0]);
- mWifiIfaces = wifiIfaces.toArray(new String[0]);
- // TODO (b/192758557): Remove debug log.
- if (CollectionUtils.contains(mMobileIfaces, null)) {
- throw new NullPointerException(
- "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces));
- }
- if (CollectionUtils.contains(mWifiIfaces, null)) {
- throw new NullPointerException(
- "null element in mWifiIfaces: " + Arrays.toString(mWifiIfaces));
- }
- }
-
- private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) {
- if (!state.getNetworkCapabilities().hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
- throw new IllegalArgumentException("Mobile state need capability TRANSPORT_CELLULAR");
- }
-
- final NetworkSpecifier spec = state.getNetworkCapabilities().getNetworkSpecifier();
- if (spec instanceof TelephonyNetworkSpecifier) {
- return ((TelephonyNetworkSpecifier) spec).getSubscriptionId();
- } else {
- Log.wtf(TAG, "getSubIdForState invalid NetworkSpecifier");
- return INVALID_SUBSCRIPTION_ID;
- }
- }
-
- /**
- * For networks with {@code TRANSPORT_CELLULAR}, get ratType that was obtained through
- * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different
- * transport types do not actually fill this value.
- */
- private int getRatTypeForStateSnapshot(@NonNull NetworkStateSnapshot state) {
- if (!state.getNetworkCapabilities().hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
- return 0;
- }
-
- return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.getSubscriberId());
- }
-
- private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
- ArrayMap<K, NetworkIdentitySet> map, K key) {
- NetworkIdentitySet ident = map.get(key);
- if (ident == null) {
- ident = new NetworkIdentitySet();
- map.put(key, ident);
- }
- return ident;
- }
-
- @GuardedBy("mStatsLock")
- private void recordSnapshotLocked(long currentTime) throws RemoteException {
- // snapshot and record current counters; read UID stats first to
- // avoid over counting dev stats.
- Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotUid");
- final NetworkStats uidSnapshot = getNetworkStatsUidDetail(INTERFACES_ALL);
- Trace.traceEnd(TRACE_TAG_NETWORK);
- Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotXt");
- final NetworkStats xtSnapshot = readNetworkStatsSummaryXt();
- Trace.traceEnd(TRACE_TAG_NETWORK);
- Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
- final NetworkStats devSnapshot = readNetworkStatsSummaryDev();
- Trace.traceEnd(TRACE_TAG_NETWORK);
-
- // Snapshot for dev/xt stats from all custom stats providers. Counts per-interface data
- // from stats providers that isn't already counted by dev and XT stats.
- Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotStatsProvider");
- final NetworkStats providersnapshot = getNetworkStatsFromProviders(STATS_PER_IFACE);
- Trace.traceEnd(TRACE_TAG_NETWORK);
- xtSnapshot.combineAllValues(providersnapshot);
- devSnapshot.combineAllValues(providersnapshot);
-
- // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
- // can't be reattributed to responsible apps.
- Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev");
- mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
- Trace.traceEnd(TRACE_TAG_NETWORK);
- Trace.traceBegin(TRACE_TAG_NETWORK, "recordXt");
- mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
- Trace.traceEnd(TRACE_TAG_NETWORK);
-
- // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
- Trace.traceBegin(TRACE_TAG_NETWORK, "recordUid");
- mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
- Trace.traceEnd(TRACE_TAG_NETWORK);
- Trace.traceBegin(TRACE_TAG_NETWORK, "recordUidTag");
- mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
- Trace.traceEnd(TRACE_TAG_NETWORK);
-
- // We need to make copies of member fields that are sent to the observer to avoid
- // a race condition between the service handler thread and the observer's
- mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
- new ArrayMap<>(mActiveUidIfaces), currentTime);
- }
-
- /**
- * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
- * so we have baseline values without double-counting.
- */
- @GuardedBy("mStatsLock")
- private void bootstrapStatsLocked() {
- final long currentTime = mClock.millis();
-
- try {
- recordSnapshotLocked(currentTime);
- } catch (IllegalStateException e) {
- Log.w(TAG, "problem reading network stats: " + e);
- } catch (RemoteException e) {
- // ignored; service lives in system_server
- }
- }
-
- private void performPoll(int flags) {
- synchronized (mStatsLock) {
- mWakeLock.acquire();
-
- try {
- performPollLocked(flags);
- } finally {
- mWakeLock.release();
- }
- }
- }
-
- /**
- * Periodic poll operation, reading current statistics and recording into
- * {@link NetworkStatsHistory}.
- */
- @GuardedBy("mStatsLock")
- private void performPollLocked(int flags) {
- if (!mSystemReady) return;
- if (LOGV) Log.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
- Trace.traceBegin(TRACE_TAG_NETWORK, "performPollLocked");
-
- final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
- final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
- final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
-
- performPollFromProvidersLocked();
-
- // TODO: consider marking "untrusted" times in historical stats
- final long currentTime = mClock.millis();
-
- try {
- recordSnapshotLocked(currentTime);
- } catch (IllegalStateException e) {
- Log.wtf(TAG, "problem reading network stats", e);
- return;
- } catch (RemoteException e) {
- // ignored; service lives in system_server
- return;
- }
-
- // persist any pending data depending on requested flags
- Trace.traceBegin(TRACE_TAG_NETWORK, "[persisting]");
- if (persistForce) {
- mDevRecorder.forcePersistLocked(currentTime);
- mXtRecorder.forcePersistLocked(currentTime);
- mUidRecorder.forcePersistLocked(currentTime);
- mUidTagRecorder.forcePersistLocked(currentTime);
- } else {
- if (persistNetwork) {
- mDevRecorder.maybePersistLocked(currentTime);
- mXtRecorder.maybePersistLocked(currentTime);
- }
- if (persistUid) {
- mUidRecorder.maybePersistLocked(currentTime);
- mUidTagRecorder.maybePersistLocked(currentTime);
- }
- }
- Trace.traceEnd(TRACE_TAG_NETWORK);
-
- if (mSettings.getSampleEnabled()) {
- // sample stats after each full poll
- performSampleLocked();
- }
-
- // finally, dispatch updated event to any listeners
- mHandler.sendMessage(mHandler.obtainMessage(MSG_BROADCAST_NETWORK_STATS_UPDATED));
-
- Trace.traceEnd(TRACE_TAG_NETWORK);
- }
-
- @GuardedBy("mStatsLock")
- private void performPollFromProvidersLocked() {
- // Request asynchronous stats update from all providers for next poll. And wait a bit of
- // time to allow providers report-in given that normally binder call should be fast. Note
- // that size of list might be changed because addition/removing at the same time. For
- // addition, the stats of the missed provider can only be collected in next poll;
- // for removal, wait might take up to MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS
- // once that happened.
- // TODO: request with a valid token.
- Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
- final int registeredCallbackCount = mStatsProviderCbList.size();
- mStatsProviderSem.drainPermits();
- invokeForAllStatsProviderCallbacks(
- (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */));
- try {
- mStatsProviderSem.tryAcquire(registeredCallbackCount,
- MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {
- // Strictly speaking it's possible a provider happened to deliver between the timeout
- // and the log, and that doesn't matter too much as this is just a debug log.
- Log.d(TAG, "requestStatsUpdate - providers responded "
- + mStatsProviderSem.availablePermits()
- + "/" + registeredCallbackCount + " : " + e);
- }
- Trace.traceEnd(TRACE_TAG_NETWORK);
- }
-
- /**
- * Sample recent statistics summary into {@link EventLog}.
- */
- @GuardedBy("mStatsLock")
- private void performSampleLocked() {
- // TODO: migrate trustedtime fixes to separate binary log events
- final long currentTime = mClock.millis();
-
- NetworkTemplate template;
- NetworkStats.Entry devTotal;
- NetworkStats.Entry xtTotal;
- NetworkStats.Entry uidTotal;
-
- // collect mobile sample
- template = buildTemplateMobileWildcard();
- devTotal = mDevRecorder.getTotalSinceBootLocked(template);
- xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
- uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
-
- EventLog.writeEvent(LOG_TAG_NETSTATS_MOBILE_SAMPLE,
- devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
- xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
- uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
- currentTime);
-
- // collect wifi sample
- template = buildTemplateWifiWildcard();
- devTotal = mDevRecorder.getTotalSinceBootLocked(template);
- xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
- uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
-
- EventLog.writeEvent(LOG_TAG_NETSTATS_WIFI_SAMPLE,
- devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
- xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
- uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
- currentTime);
- }
-
- // deleteKernelTagData can ignore ENOENT; otherwise we should log an error
- private void logErrorIfNotErrNoent(final ErrnoException e, final String msg) {
- if (e.errno != ENOENT) Log.e(TAG, msg, e);
- }
-
- private <K extends StatsMapKey, V extends StatsMapValue> void deleteStatsMapTagData(
- IBpfMap<K, V> statsMap, int uid) {
- try {
- statsMap.forEach((key, value) -> {
- if (key.uid == uid) {
- try {
- statsMap.deleteEntry(key);
- } catch (ErrnoException e) {
- logErrorIfNotErrNoent(e, "Failed to delete data(uid = " + key.uid + ")");
- }
- }
- });
- } catch (ErrnoException e) {
- Log.e(TAG, "FAILED to delete tag data from stats map", e);
- }
- }
-
- /**
- * Deletes uid tag data from CookieTagMap, StatsMapA, StatsMapB, and UidStatsMap
- * @param uid
- */
- private void deleteKernelTagData(int uid) {
- try {
- mCookieTagMap.forEach((key, value) -> {
- // If SkDestroyListener deletes the socket tag while this code is running,
- // forEach will either restart iteration from the beginning or return null,
- // depending on when the deletion happens.
- // If it returns null, continue iteration to delete the data and in fact it would
- // just iterate from first key because BpfMap#getNextKey would return first key
- // if the current key is not exist.
- if (value != null && value.uid == uid) {
- try {
- mCookieTagMap.deleteEntry(key);
- } catch (ErrnoException e) {
- logErrorIfNotErrNoent(e, "Failed to delete data(cookie = " + key + ")");
- }
- }
- });
- } catch (ErrnoException e) {
- Log.e(TAG, "Failed to delete tag data from cookie tag map", e);
- }
-
- deleteStatsMapTagData(mStatsMapA, uid);
- deleteStatsMapTagData(mStatsMapB, uid);
-
- try {
- mUidCounterSetMap.deleteEntry(new U32(uid));
- } catch (ErrnoException e) {
- logErrorIfNotErrNoent(e, "Failed to delete tag data from uid counter set map");
- }
-
- try {
- mAppUidStatsMap.deleteEntry(new UidStatsMapKey(uid));
- } catch (ErrnoException e) {
- logErrorIfNotErrNoent(e, "Failed to delete tag data from app uid stats map");
- }
- }
-
- /**
- * Clean up {@link #mUidRecorder} after UID is removed.
- */
- @GuardedBy("mStatsLock")
- private void removeUidsLocked(int... uids) {
- if (LOGV) Log.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
-
- // Perform one last poll before removing
- performPollLocked(FLAG_PERSIST_ALL);
-
- mUidRecorder.removeUidsLocked(uids);
- mUidTagRecorder.removeUidsLocked(uids);
-
- // Clear kernel stats associated with UID
- for (int uid : uids) {
- deleteKernelTagData(uid);
- }
- }
-
- /**
- * Clean up {@link #mUidRecorder} after user is removed.
- */
- @GuardedBy("mStatsLock")
- private void removeUserLocked(@NonNull UserHandle userHandle) {
- if (LOGV) Log.v(TAG, "removeUserLocked() for UserHandle=" + userHandle);
-
- // Build list of UIDs that we should clean up
- final ArrayList<Integer> uids = new ArrayList<>();
- final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
- PackageManager.MATCH_ANY_USER
- | PackageManager.MATCH_DISABLED_COMPONENTS);
- for (ApplicationInfo app : apps) {
- final int uid = userHandle.getUid(app.uid);
- uids.add(uid);
- }
-
- removeUidsLocked(CollectionUtils.toIntArray(uids));
- }
-
- /**
- * Set the warning and limit to all registered custom network stats providers.
- * Note that invocation of any interface will be sent to all providers.
- */
- public void setStatsProviderWarningAndLimitAsync(
- @NonNull String iface, long warning, long limit) {
- PermissionUtils.enforceNetworkStackPermission(mContext);
- if (LOGV) {
- Log.v(TAG, "setStatsProviderWarningAndLimitAsync("
- + iface + "," + warning + "," + limit + ")");
- }
- invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetWarningAndLimit(iface,
- warning, limit));
- }
-
- @Override
- protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
- if (!PermissionUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
-
- long duration = DateUtils.DAY_IN_MILLIS;
- final HashSet<String> argSet = new HashSet<String>();
- for (String arg : args) {
- argSet.add(arg);
-
- if (arg.startsWith("--duration=")) {
- try {
- duration = Long.parseLong(arg.substring(11));
- } catch (NumberFormatException ignored) {
- }
- }
- }
-
- // usage: dumpsys netstats --full --uid --tag --poll --checkin
- final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
- final boolean checkin = argSet.contains("--checkin");
- final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
- final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
- final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
-
- final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, " ");
-
- synchronized (mStatsLock) {
- if (args.length > 0 && "--proto".equals(args[0])) {
- // In this case ignore all other arguments.
- dumpProtoLocked(fd);
- return;
- }
-
- if (poll) {
- performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
- pw.println("Forced poll");
- return;
- }
-
- if (checkin) {
- final long end = System.currentTimeMillis();
- final long start = end - duration;
-
- pw.print("v1,");
- pw.print(start / SECOND_IN_MILLIS); pw.print(',');
- pw.print(end / SECOND_IN_MILLIS); pw.println();
-
- pw.println("xt");
- mXtRecorder.dumpCheckin(rawWriter, start, end);
-
- if (includeUid) {
- pw.println("uid");
- mUidRecorder.dumpCheckin(rawWriter, start, end);
- }
- if (includeTag) {
- pw.println("tag");
- mUidTagRecorder.dumpCheckin(rawWriter, start, end);
- }
- return;
- }
-
- pw.println("Configs:");
- pw.increaseIndent();
- pw.print(NETSTATS_COMBINE_SUBTYPE_ENABLED, mSettings.getCombineSubtypeEnabled());
- pw.println();
- pw.decreaseIndent();
-
- pw.println("Active interfaces:");
- pw.increaseIndent();
- for (int i = 0; i < mActiveIfaces.size(); i++) {
- pw.print("iface", mActiveIfaces.keyAt(i));
- pw.print("ident", mActiveIfaces.valueAt(i));
- pw.println();
- }
- pw.decreaseIndent();
-
- pw.println("Active UID interfaces:");
- pw.increaseIndent();
- for (int i = 0; i < mActiveUidIfaces.size(); i++) {
- pw.print("iface", mActiveUidIfaces.keyAt(i));
- pw.print("ident", mActiveUidIfaces.valueAt(i));
- pw.println();
- }
- pw.decreaseIndent();
-
- // Get the top openSession callers
- final SparseIntArray calls;
- synchronized (mOpenSessionCallsPerUid) {
- calls = mOpenSessionCallsPerUid.clone();
- }
-
- final int N = calls.size();
- final long[] values = new long[N];
- for (int j = 0; j < N; j++) {
- values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
- }
- Arrays.sort(values);
-
- pw.println("Top openSession callers (uid=count):");
- pw.increaseIndent();
- final int end = Math.max(0, N - DUMP_STATS_SESSION_COUNT);
- for (int j = N - 1; j >= end; j--) {
- final int uid = (int) (values[j] & 0xffffffff);
- final int count = (int) (values[j] >> 32);
- pw.print(uid); pw.print("="); pw.println(count);
- }
- pw.decreaseIndent();
- pw.println();
-
- pw.println("Stats Providers:");
- pw.increaseIndent();
- invokeForAllStatsProviderCallbacks((cb) -> {
- pw.println(cb.mTag + " Xt:");
- pw.increaseIndent();
- pw.print(cb.getCachedStats(STATS_PER_IFACE).toString());
- pw.decreaseIndent();
- if (includeUid) {
- pw.println(cb.mTag + " Uid:");
- pw.increaseIndent();
- pw.print(cb.getCachedStats(STATS_PER_UID).toString());
- pw.decreaseIndent();
- }
- });
- pw.decreaseIndent();
-
- pw.println("Dev stats:");
- pw.increaseIndent();
- mDevRecorder.dumpLocked(pw, fullHistory);
- pw.decreaseIndent();
-
- pw.println("Xt stats:");
- pw.increaseIndent();
- mXtRecorder.dumpLocked(pw, fullHistory);
- pw.decreaseIndent();
-
- if (includeUid) {
- pw.println("UID stats:");
- pw.increaseIndent();
- mUidRecorder.dumpLocked(pw, fullHistory);
- pw.decreaseIndent();
- }
-
- if (includeTag) {
- pw.println("UID tag stats:");
- pw.increaseIndent();
- mUidTagRecorder.dumpLocked(pw, fullHistory);
- pw.decreaseIndent();
- }
- }
- }
-
- @GuardedBy("mStatsLock")
- private void dumpProtoLocked(FileDescriptor fd) {
- final ProtoOutputStream proto = new ProtoOutputStream(new FileOutputStream(fd));
-
- // TODO Right now it writes all history. Should it limit to the "since-boot" log?
-
- dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES,
- mActiveIfaces);
- dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES,
- mActiveUidIfaces);
- mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
- mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
- mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
- mUidTagRecorder.dumpDebugLocked(proto,
- NetworkStatsServiceDumpProto.UID_TAG_STATS);
-
- proto.flush();
- }
-
- private static void dumpInterfaces(ProtoOutputStream proto, long tag,
- ArrayMap<String, NetworkIdentitySet> ifaces) {
- for (int i = 0; i < ifaces.size(); i++) {
- final long start = proto.start(tag);
-
- proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
- ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES);
-
- proto.end(start);
- }
- }
-
- private NetworkStats readNetworkStatsSummaryDev() {
- try {
- return mStatsFactory.readNetworkStatsSummaryDev();
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- private NetworkStats readNetworkStatsSummaryXt() {
- try {
- return mStatsFactory.readNetworkStatsSummaryXt();
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- private NetworkStats readNetworkStatsUidDetail(int uid, String[] ifaces, int tag) {
- try {
- return mStatsFactory.readNetworkStatsDetail(uid, ifaces, tag);
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- /**
- * Return snapshot of current UID statistics, including any
- * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
- * values.
- *
- * @param ifaces A list of interfaces the stats should be restricted to, or
- * {@link NetworkStats#INTERFACES_ALL}.
- */
- private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
- throws RemoteException {
- final NetworkStats uidSnapshot = readNetworkStatsUidDetail(UID_ALL, ifaces, TAG_ALL);
-
- // fold tethering stats and operations into uid snapshot
- final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
- tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
- mStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot);
- uidSnapshot.combineAllValues(tetherSnapshot);
-
- // get a stale copy of uid stats snapshot provided by providers.
- final NetworkStats providerStats = getNetworkStatsFromProviders(STATS_PER_UID);
- providerStats.filter(UID_ALL, ifaces, TAG_ALL);
- mStatsFactory.apply464xlatAdjustments(uidSnapshot, providerStats);
- uidSnapshot.combineAllValues(providerStats);
-
- uidSnapshot.combineAllValues(mUidOperations);
-
- return uidSnapshot;
- }
-
- /**
- * Return snapshot of current non-offloaded tethering statistics. Will return empty
- * {@link NetworkStats} if any problems are encountered, or queried by {@code STATS_PER_IFACE}
- * since it is already included by {@link #nativeGetIfaceStat}.
- * See {@code OffloadTetheringStatsProvider} for offloaded tethering stats.
- */
- // TODO: Remove this by implementing {@link NetworkStatsProvider} for non-offloaded
- // tethering stats.
- private @NonNull NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
- // We only need to return per-UID stats. Per-device stats are already counted by
- // interface counters.
- if (how != STATS_PER_UID) {
- return new NetworkStats(SystemClock.elapsedRealtime(), 0);
- }
-
- final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
- try {
- final TetherStatsParcel[] tetherStatsParcels = mNetd.tetherGetStats();
- for (TetherStatsParcel tetherStats : tetherStatsParcels) {
- try {
- stats.combineValues(new NetworkStats.Entry(tetherStats.iface, UID_TETHERING,
- SET_DEFAULT, TAG_NONE, tetherStats.rxBytes, tetherStats.rxPackets,
- tetherStats.txBytes, tetherStats.txPackets, 0L));
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new IllegalStateException("invalid tethering stats " + e);
- }
- }
- } catch (IllegalStateException e) {
- Log.wtf(TAG, "problem reading network stats", e);
- }
- return stats;
- }
-
- // TODO: It is copied from ConnectivityService, consider refactor these check permission
- // functions to a proper util.
- private boolean checkAnyPermissionOf(String... permissions) {
- for (String permission : permissions) {
- if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
- return true;
- }
- }
- return false;
- }
-
- private void enforceAnyPermissionOf(String... permissions) {
- if (!checkAnyPermissionOf(permissions)) {
- throw new SecurityException("Requires one of the following permissions: "
- + String.join(", ", permissions) + ".");
- }
- }
-
- /**
- * Registers a custom provider of {@link android.net.NetworkStats} to combine the network
- * statistics that cannot be seen by the kernel to system. To unregister, invoke the
- * {@code unregister()} of the returned callback.
- *
- * @param tag a human readable identifier of the custom network stats provider.
- * @param provider the {@link INetworkStatsProvider} binder corresponding to the
- * {@link NetworkStatsProvider} to be registered.
- *
- * @return a {@link INetworkStatsProviderCallback} binder
- * interface, which can be used to report events to the system.
- */
- public @NonNull INetworkStatsProviderCallback registerNetworkStatsProvider(
- @NonNull String tag, @NonNull INetworkStatsProvider provider) {
- enforceAnyPermissionOf(NETWORK_STATS_PROVIDER,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- Objects.requireNonNull(provider, "provider is null");
- Objects.requireNonNull(tag, "tag is null");
- final NetworkPolicyManager netPolicyManager = mContext
- .getSystemService(NetworkPolicyManager.class);
- try {
- NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl(
- tag, provider, mStatsProviderSem, mAlertObserver,
- mStatsProviderCbList, netPolicyManager);
- mStatsProviderCbList.add(callback);
- Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid="
- + getCallingUid() + "/" + getCallingPid());
- return callback;
- } catch (RemoteException e) {
- Log.e(TAG, "registerNetworkStatsProvider failed", e);
- }
- return null;
- }
-
- // Collect stats from local cache of providers.
- private @NonNull NetworkStats getNetworkStatsFromProviders(int how) {
- final NetworkStats ret = new NetworkStats(0L, 0);
- invokeForAllStatsProviderCallbacks((cb) -> ret.combineAllValues(cb.getCachedStats(how)));
- return ret;
- }
-
- @FunctionalInterface
- private interface ThrowingConsumer<S, T extends Throwable> {
- void accept(S s) throws T;
- }
-
- private void invokeForAllStatsProviderCallbacks(
- @NonNull ThrowingConsumer<NetworkStatsProviderCallbackImpl, RemoteException> task) {
- for (final NetworkStatsProviderCallbackImpl cb : mStatsProviderCbList) {
- try {
- task.accept(cb);
- } catch (RemoteException e) {
- Log.e(TAG, "Fail to broadcast to provider: " + cb.mTag, e);
- }
- }
- }
-
- private static class NetworkStatsProviderCallbackImpl extends INetworkStatsProviderCallback.Stub
- implements IBinder.DeathRecipient {
- @NonNull final String mTag;
-
- @NonNull final INetworkStatsProvider mProvider;
- @NonNull private final Semaphore mSemaphore;
- @NonNull final AlertObserver mAlertObserver;
- @NonNull final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
- @NonNull final NetworkPolicyManager mNetworkPolicyManager;
-
- @NonNull private final Object mProviderStatsLock = new Object();
-
- @GuardedBy("mProviderStatsLock")
- // Track STATS_PER_IFACE and STATS_PER_UID separately.
- private final NetworkStats mIfaceStats = new NetworkStats(0L, 0);
- @GuardedBy("mProviderStatsLock")
- private final NetworkStats mUidStats = new NetworkStats(0L, 0);
-
- NetworkStatsProviderCallbackImpl(
- @NonNull String tag, @NonNull INetworkStatsProvider provider,
- @NonNull Semaphore semaphore,
- @NonNull AlertObserver alertObserver,
- @NonNull CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> cbList,
- @NonNull NetworkPolicyManager networkPolicyManager)
- throws RemoteException {
- mTag = tag;
- mProvider = provider;
- mProvider.asBinder().linkToDeath(this, 0);
- mSemaphore = semaphore;
- mAlertObserver = alertObserver;
- mStatsProviderCbList = cbList;
- mNetworkPolicyManager = networkPolicyManager;
- }
-
- @NonNull
- public NetworkStats getCachedStats(int how) {
- synchronized (mProviderStatsLock) {
- NetworkStats stats;
- switch (how) {
- case STATS_PER_IFACE:
- stats = mIfaceStats;
- break;
- case STATS_PER_UID:
- stats = mUidStats;
- break;
- default:
- throw new IllegalArgumentException("Invalid type: " + how);
- }
- // Callers might be able to mutate the returned object. Return a defensive copy
- // instead of local reference.
- return stats.clone();
- }
- }
-
- @Override
- public void notifyStatsUpdated(int token, @Nullable NetworkStats ifaceStats,
- @Nullable NetworkStats uidStats) {
- // TODO: 1. Use token to map ifaces to correct NetworkIdentity.
- // 2. Store the difference and store it directly to the recorder.
- synchronized (mProviderStatsLock) {
- if (ifaceStats != null) mIfaceStats.combineAllValues(ifaceStats);
- if (uidStats != null) mUidStats.combineAllValues(uidStats);
- }
- mSemaphore.release();
- }
-
- @Override
- public void notifyAlertReached() throws RemoteException {
- // This binder object can only have been obtained by a process that holds
- // NETWORK_STATS_PROVIDER. Thus, no additional permission check is required.
- BinderUtils.withCleanCallingIdentity(() ->
- mAlertObserver.onQuotaLimitReached(LIMIT_GLOBAL_ALERT, null /* unused */));
- }
-
- @Override
- public void notifyWarningReached() {
- Log.d(TAG, mTag + ": notifyWarningReached");
- BinderUtils.withCleanCallingIdentity(() ->
- mNetworkPolicyManager.notifyStatsProviderWarningReached());
- }
-
- @Override
- public void notifyLimitReached() {
- Log.d(TAG, mTag + ": notifyLimitReached");
- BinderUtils.withCleanCallingIdentity(() ->
- mNetworkPolicyManager.notifyStatsProviderLimitReached());
- }
-
- @Override
- public void binderDied() {
- Log.d(TAG, mTag + ": binderDied");
- mStatsProviderCbList.remove(this);
- }
-
- @Override
- public void unregister() {
- Log.d(TAG, mTag + ": unregister");
- mStatsProviderCbList.remove(this);
- }
-
- }
-
- private void assertSystemReady() {
- if (!mSystemReady) {
- throw new IllegalStateException("System not ready");
- }
- }
-
- private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
- @Override
- public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
- int rightIndex, String cookie) {
- Log.w(TAG, "Found non-monotonic values; saving to dropbox");
-
- // record error for debugging
- final StringBuilder builder = new StringBuilder();
- builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
- + "] - right[" + rightIndex + "]\n");
- builder.append("left=").append(left).append('\n');
- builder.append("right=").append(right).append('\n');
-
- mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
- builder.toString());
- }
-
- @Override
- public void foundNonMonotonic(
- NetworkStats stats, int statsIndex, String cookie) {
- Log.w(TAG, "Found non-monotonic values; saving to dropbox");
-
- final StringBuilder builder = new StringBuilder();
- builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
- builder.append("stats=").append(stats).append('\n');
-
- mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
- builder.toString());
- }
- }
-
- /**
- * Default external settings that read from
- * {@link android.provider.Settings.Global}.
- */
- private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
- DefaultNetworkStatsSettings() {}
-
- @Override
- public long getPollInterval() {
- return 30 * MINUTE_IN_MILLIS;
- }
- @Override
- public long getPollDelay() {
- return DEFAULT_PERFORM_POLL_DELAY_MS;
- }
- @Override
- public long getGlobalAlertBytes(long def) {
- return def;
- }
- @Override
- public boolean getSampleEnabled() {
- return true;
- }
- @Override
- public boolean getAugmentEnabled() {
- return true;
- }
- @Override
- public boolean getCombineSubtypeEnabled() {
- return false;
- }
- @Override
- public Config getDevConfig() {
- return new Config(HOUR_IN_MILLIS, 15 * DAY_IN_MILLIS, 90 * DAY_IN_MILLIS);
- }
- @Override
- public Config getXtConfig() {
- return getDevConfig();
- }
- @Override
- public Config getUidConfig() {
- return new Config(2 * HOUR_IN_MILLIS, 15 * DAY_IN_MILLIS, 90 * DAY_IN_MILLIS);
- }
- @Override
- public Config getUidTagConfig() {
- return new Config(2 * HOUR_IN_MILLIS, 5 * DAY_IN_MILLIS, 15 * DAY_IN_MILLIS);
- }
- @Override
- public long getDevPersistBytes(long def) {
- return def;
- }
- @Override
- public long getXtPersistBytes(long def) {
- return def;
- }
- @Override
- public long getUidPersistBytes(long def) {
- return def;
- }
- @Override
- public long getUidTagPersistBytes(long def) {
- return def;
- }
- }
-
- private static native long nativeGetTotalStat(int type);
- private static native long nativeGetIfaceStat(String iface, int type);
- private static native long nativeGetUidStat(int uid, int type);
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
deleted file mode 100644
index 65ccd20..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2020 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.net;
-
-import static android.app.usage.NetworkStatsManager.NETWORK_TYPE_5G_NSA;
-import static android.app.usage.NetworkStatsManager.getCollapsedRatType;
-import static android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED;
-import static android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
-
-import android.annotation.NonNull;
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyCallback;
-import android.telephony.TelephonyDisplayInfo;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.net.module.util.CollectionUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.Executor;
-
-/**
- * Helper class that watches for events that are triggered per subscription.
- */
-@TargetApi(Build.VERSION_CODES.TIRAMISU)
-public class NetworkStatsSubscriptionsMonitor extends
- SubscriptionManager.OnSubscriptionsChangedListener {
-
- /**
- * Interface that this monitor uses to delegate event handling to NetworkStatsService.
- */
- public interface Delegate {
- /**
- * Notify that the collapsed RAT type has been changed for any subscription. The method
- * will also be triggered for any existing sub when start and stop monitoring.
- *
- * @param subscriberId IMSI of the subscription.
- * @param collapsedRatType collapsed RAT type.
- * @see android.app.usage.NetworkStatsManager#getCollapsedRatType(int).
- */
- void onCollapsedRatTypeChanged(@NonNull String subscriberId, int collapsedRatType);
- }
- private final Delegate mDelegate;
-
- /**
- * Receivers that watches for {@link TelephonyDisplayInfo} changes for each subscription, to
- * monitor the transitioning between Radio Access Technology(RAT) types for each sub.
- */
- @NonNull
- private final CopyOnWriteArrayList<RatTypeListener> mRatListeners =
- new CopyOnWriteArrayList<>();
-
- @NonNull
- private final SubscriptionManager mSubscriptionManager;
- @NonNull
- private final TelephonyManager mTeleManager;
-
- @NonNull
- private final Executor mExecutor;
-
- NetworkStatsSubscriptionsMonitor(@NonNull Context context,
- @NonNull Executor executor, @NonNull Delegate delegate) {
- super();
- mSubscriptionManager = (SubscriptionManager) context.getSystemService(
- Context.TELEPHONY_SUBSCRIPTION_SERVICE);
- mTeleManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- mExecutor = executor;
- mDelegate = delegate;
- }
-
- @Override
- public void onSubscriptionsChanged() {
- // Collect active subId list, hidden subId such as opportunistic subscriptions are
- // also needed to track CBRS.
- final List<Integer> newSubs = getActiveSubIdList(mSubscriptionManager);
-
- // IMSI is needed for every newly added sub. Listener stores subscriberId into it to
- // prevent binder call to telephony when querying RAT. Keep listener registration with empty
- // IMSI is meaningless since the RAT type changed is ambiguous for multi-SIM if reported
- // with empty IMSI. So filter the subs w/o a valid IMSI to prevent such registration.
- final List<Pair<Integer, String>> filteredNewSubs = new ArrayList<>();
- for (final int subId : newSubs) {
- final String subscriberId =
- mTeleManager.createForSubscriptionId(subId).getSubscriberId();
- if (!TextUtils.isEmpty(subscriberId)) {
- filteredNewSubs.add(new Pair(subId, subscriberId));
- }
- }
-
- for (final Pair<Integer, String> sub : filteredNewSubs) {
- // Fully match listener with subId and IMSI, since in some rare cases, IMSI might be
- // suddenly change regardless of subId, such as switch IMSI feature in modem side.
- // If that happens, register new listener with new IMSI and remove old one later.
- if (CollectionUtils.any(mRatListeners, it -> it.equalsKey(sub.first, sub.second))) {
- continue;
- }
-
- final RatTypeListener listener = new RatTypeListener(this, sub.first, sub.second);
- mRatListeners.add(listener);
-
- // Register listener to the telephony manager that associated with specific sub.
- mTeleManager.createForSubscriptionId(sub.first)
- .registerTelephonyCallback(mExecutor, listener);
- Log.d(NetworkStatsService.TAG, "RAT type listener registered for sub " + sub.first);
- }
-
- for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) {
- // If there is no subId and IMSI matched the listener, removes it.
- if (!CollectionUtils.any(filteredNewSubs,
- it -> listener.equalsKey(it.first, it.second))) {
- handleRemoveRatTypeListener(listener);
- }
- }
- }
-
- @NonNull
- private List<Integer> getActiveSubIdList(@NonNull SubscriptionManager subscriptionManager) {
- final ArrayList<Integer> ret = new ArrayList<>();
- final int[] ids = subscriptionManager.getCompleteActiveSubscriptionIdList();
- for (int id : ids) ret.add(id);
- return ret;
- }
-
- /**
- * Get a collapsed RatType for the given subscriberId.
- *
- * @param subscriberId the target subscriberId
- * @return collapsed RatType for the given subscriberId
- */
- public int getRatTypeForSubscriberId(@NonNull String subscriberId) {
- final int index = CollectionUtils.indexOf(mRatListeners,
- it -> TextUtils.equals(subscriberId, it.mSubscriberId));
- return index != -1 ? mRatListeners.get(index).mLastCollapsedRatType
- : TelephonyManager.NETWORK_TYPE_UNKNOWN;
- }
-
- /**
- * Start monitoring events that triggered per subscription.
- */
- public void start() {
- mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor, this);
- }
-
- /**
- * Unregister subscription changes and all listeners for each subscription.
- */
- public void stop() {
- mSubscriptionManager.removeOnSubscriptionsChangedListener(this);
-
- for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) {
- handleRemoveRatTypeListener(listener);
- }
- }
-
- private void handleRemoveRatTypeListener(@NonNull RatTypeListener listener) {
- mTeleManager.createForSubscriptionId(listener.mSubId)
- .unregisterTelephonyCallback(listener);
- Log.d(NetworkStatsService.TAG, "RAT type listener unregistered for sub " + listener.mSubId);
- mRatListeners.remove(listener);
-
- // Removal of subscriptions doesn't generate RAT changed event, fire it for every
- // RatTypeListener.
- mDelegate.onCollapsedRatTypeChanged(
- listener.mSubscriberId, TelephonyManager.NETWORK_TYPE_UNKNOWN);
- }
-
- static class RatTypeListener extends TelephonyCallback
- implements TelephonyCallback.DisplayInfoListener {
- // Unique id for the subscription. See {@link SubscriptionInfo#getSubscriptionId}.
- @NonNull
- private final int mSubId;
-
- // IMSI to identifying the corresponding network from {@link NetworkState}.
- // See {@link TelephonyManager#getSubscriberId}.
- @NonNull
- private final String mSubscriberId;
-
- private volatile int mLastCollapsedRatType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
- @NonNull
- private final NetworkStatsSubscriptionsMonitor mMonitor;
-
- RatTypeListener(@NonNull NetworkStatsSubscriptionsMonitor monitor, int subId,
- @NonNull String subscriberId) {
- mSubId = subId;
- mSubscriberId = subscriberId;
- mMonitor = monitor;
- }
-
- @Override
- public void onDisplayInfoChanged(TelephonyDisplayInfo displayInfo) {
- // In 5G SA (Stand Alone) mode, the primary cell itself will be 5G hence telephony
- // would report RAT = 5G_NR.
- // However, in 5G NSA (Non Stand Alone) mode, the primary cell is still LTE and
- // network allocates a secondary 5G cell so telephony reports RAT = LTE along with
- // NR state as connected. In such case, attributes the data usage to NR.
- // See b/160727498.
- final boolean is5GNsa = displayInfo.getNetworkType() == NETWORK_TYPE_LTE
- && (displayInfo.getOverrideNetworkType() == OVERRIDE_NETWORK_TYPE_NR_NSA
- || displayInfo.getOverrideNetworkType() == OVERRIDE_NETWORK_TYPE_NR_ADVANCED);
-
- final int networkType =
- (is5GNsa ? NETWORK_TYPE_5G_NSA : displayInfo.getNetworkType());
- final int collapsedRatType = getCollapsedRatType(networkType);
- if (collapsedRatType == mLastCollapsedRatType) return;
-
- if (NetworkStatsService.LOGD) {
- Log.d(NetworkStatsService.TAG, "subtype changed for sub(" + mSubId + "): "
- + mLastCollapsedRatType + " -> " + collapsedRatType);
- }
- mLastCollapsedRatType = collapsedRatType;
- mMonitor.mDelegate.onCollapsedRatTypeChanged(mSubscriberId, mLastCollapsedRatType);
- }
-
- @VisibleForTesting
- public int getSubId() {
- return mSubId;
- }
-
- boolean equalsKey(int subId, @NonNull String subscriberId) {
- return mSubId == subId && TextUtils.equals(mSubscriberId, subscriberId);
- }
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/StatsMapKey.java b/packages/ConnectivityT/service/src/com/android/server/net/StatsMapKey.java
deleted file mode 100644
index ea8d836..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/StatsMapKey.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.net;
-
-import com.android.net.module.util.Struct;
-import com.android.net.module.util.Struct.Field;
-import com.android.net.module.util.Struct.Type;
-
-/**
- * Key for both stats maps.
- */
-public class StatsMapKey extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long uid;
-
- @Field(order = 1, type = Type.U32)
- public final long tag;
-
- @Field(order = 2, type = Type.U32)
- public final long counterSet;
-
- @Field(order = 3, type = Type.U32)
- public final long ifaceIndex;
-
- public StatsMapKey(final long uid, final long tag, final long counterSet,
- final long ifaceIndex) {
- this.uid = uid;
- this.tag = tag;
- this.counterSet = counterSet;
- this.ifaceIndex = ifaceIndex;
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/StatsMapValue.java b/packages/ConnectivityT/service/src/com/android/server/net/StatsMapValue.java
deleted file mode 100644
index 48f26ce..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/StatsMapValue.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.net;
-
-import com.android.net.module.util.Struct;
-import com.android.net.module.util.Struct.Field;
-import com.android.net.module.util.Struct.Type;
-
-/**
- * Value used for both stats maps and uid stats map.
- */
-public class StatsMapValue extends Struct {
- @Field(order = 0, type = Type.U63)
- public final long rxPackets;
-
- @Field(order = 1, type = Type.U63)
- public final long rxBytes;
-
- @Field(order = 2, type = Type.U63)
- public final long txPackets;
-
- @Field(order = 3, type = Type.U63)
- public final long txBytes;
-
- public StatsMapValue(final long rxPackets, final long rxBytes, final long txPackets,
- final long txBytes) {
- this.rxPackets = rxPackets;
- this.rxBytes = rxBytes;
- this.txPackets = txPackets;
- this.txBytes = txBytes;
- }
-}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/UidStatsMapKey.java b/packages/ConnectivityT/service/src/com/android/server/net/UidStatsMapKey.java
deleted file mode 100644
index 2849f94..0000000
--- a/packages/ConnectivityT/service/src/com/android/server/net/UidStatsMapKey.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.net;
-
-import com.android.net.module.util.Struct;
-import com.android.net.module.util.Struct.Field;
-import com.android.net.module.util.Struct.Type;
-
-/**
- * Key for uid stats map.
- */
-public class UidStatsMapKey extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long uid;
-
- public UidStatsMapKey(final long uid) {
- this.uid = uid;
- }
-}
diff --git a/packages/ConnectivityT/tests/unit/java/com/android/server/NativeDaemonConnectorTest.java b/packages/ConnectivityT/tests/unit/java/com/android/server/NativeDaemonConnectorTest.java
deleted file mode 100644
index e2253a2..0000000
--- a/packages/ConnectivityT/tests/unit/java/com/android/server/NativeDaemonConnectorTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-import static com.android.server.NativeDaemonConnector.appendEscaped;
-import static com.android.server.NativeDaemonConnector.makeCommand;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-
-import com.android.server.NativeDaemonConnector.SensitiveArg;
-
-/**
- * Tests for {@link NativeDaemonConnector}.
- */
-@MediumTest
-public class NativeDaemonConnectorTest extends AndroidTestCase {
- private static final String TAG = "NativeDaemonConnectorTest";
-
- public void testArgumentNormal() throws Exception {
- final StringBuilder builder = new StringBuilder();
-
- builder.setLength(0);
- appendEscaped(builder, "");
- assertEquals("", builder.toString());
-
- builder.setLength(0);
- appendEscaped(builder, "foo");
- assertEquals("foo", builder.toString());
-
- builder.setLength(0);
- appendEscaped(builder, "foo\"bar");
- assertEquals("foo\\\"bar", builder.toString());
-
- builder.setLength(0);
- appendEscaped(builder, "foo\\bar\\\"baz");
- assertEquals("foo\\\\bar\\\\\\\"baz", builder.toString());
- }
-
- public void testArgumentWithSpaces() throws Exception {
- final StringBuilder builder = new StringBuilder();
-
- builder.setLength(0);
- appendEscaped(builder, "foo bar");
- assertEquals("\"foo bar\"", builder.toString());
-
- builder.setLength(0);
- appendEscaped(builder, "foo\"bar\\baz foo");
- assertEquals("\"foo\\\"bar\\\\baz foo\"", builder.toString());
- }
-
- public void testArgumentWithUtf() throws Exception {
- final StringBuilder builder = new StringBuilder();
-
- builder.setLength(0);
- appendEscaped(builder, "caf\u00E9 c\u00F6ffee");
- assertEquals("\"caf\u00E9 c\u00F6ffee\"", builder.toString());
- }
-
- public void testSensitiveArgs() throws Exception {
- final StringBuilder rawBuilder = new StringBuilder();
- final StringBuilder logBuilder = new StringBuilder();
-
- rawBuilder.setLength(0);
- logBuilder.setLength(0);
- makeCommand(rawBuilder, logBuilder, 1, "foo", "bar", "baz");
- assertEquals("1 foo bar baz\0", rawBuilder.toString());
- assertEquals("1 foo bar baz", logBuilder.toString());
-
- rawBuilder.setLength(0);
- logBuilder.setLength(0);
- makeCommand(rawBuilder, logBuilder, 1, "foo", new SensitiveArg("bar"), "baz");
- assertEquals("1 foo bar baz\0", rawBuilder.toString());
- assertEquals("1 foo [scrubbed] baz", logBuilder.toString());
-
- rawBuilder.setLength(0);
- logBuilder.setLength(0);
- makeCommand(rawBuilder, logBuilder, 1, "foo", new SensitiveArg("foo bar"), "baz baz",
- new SensitiveArg("wat"));
- assertEquals("1 foo \"foo bar\" \"baz baz\" wat\0", rawBuilder.toString());
- assertEquals("1 foo [scrubbed] \"baz baz\" [scrubbed]", logBuilder.toString());
- }
-}
diff --git a/packages/ConnectivityT/tests/unit/java/com/android/server/net/IpConfigStoreTest.java b/packages/ConnectivityT/tests/unit/java/com/android/server/net/IpConfigStoreTest.java
deleted file mode 100644
index ad0be58..0000000
--- a/packages/ConnectivityT/tests/unit/java/com/android/server/net/IpConfigStoreTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2018 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.net;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import android.net.InetAddresses;
-import android.net.IpConfiguration;
-import android.net.IpConfiguration.IpAssignment;
-import android.net.IpConfiguration.ProxySettings;
-import android.net.LinkAddress;
-import android.net.ProxyInfo;
-import android.net.StaticIpConfiguration;
-import android.util.ArrayMap;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Unit tests for {@link IpConfigStore}
- */
-@RunWith(AndroidJUnit4.class)
-public class IpConfigStoreTest {
- private static final int KEY_CONFIG = 17;
- private static final String IFACE_1 = "eth0";
- private static final String IFACE_2 = "eth1";
- private static final String IP_ADDR_1 = "192.168.1.10/24";
- private static final String IP_ADDR_2 = "192.168.1.20/24";
- private static final String DNS_IP_ADDR_1 = "1.2.3.4";
- private static final String DNS_IP_ADDR_2 = "5.6.7.8";
-
- @Test
- public void backwardCompatibility2to3() throws IOException {
- ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
- DataOutputStream outputStream = new DataOutputStream(byteStream);
-
- final IpConfiguration expectedConfig =
- newIpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null);
-
- // Emulate writing to old format.
- writeDhcpConfigV2(outputStream, KEY_CONFIG, expectedConfig);
-
- InputStream in = new ByteArrayInputStream(byteStream.toByteArray());
- ArrayMap<String, IpConfiguration> configurations = IpConfigStore.readIpConfigurations(in);
-
- assertNotNull(configurations);
- assertEquals(1, configurations.size());
- IpConfiguration actualConfig = configurations.get(String.valueOf(KEY_CONFIG));
- assertNotNull(actualConfig);
- assertEquals(expectedConfig, actualConfig);
- }
-
- @Test
- public void staticIpMultiNetworks() throws Exception {
- final ArrayList<InetAddress> dnsServers = new ArrayList<>();
- dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_1));
- dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_2));
- final StaticIpConfiguration staticIpConfiguration1 = new StaticIpConfiguration.Builder()
- .setIpAddress(new LinkAddress(IP_ADDR_1))
- .setDnsServers(dnsServers).build();
- final StaticIpConfiguration staticIpConfiguration2 = new StaticIpConfiguration.Builder()
- .setIpAddress(new LinkAddress(IP_ADDR_2))
- .setDnsServers(dnsServers).build();
-
- ProxyInfo proxyInfo =
- ProxyInfo.buildDirectProxy("10.10.10.10", 88, Arrays.asList("host1", "host2"));
-
- IpConfiguration expectedConfig1 = newIpConfiguration(IpAssignment.STATIC,
- ProxySettings.STATIC, staticIpConfiguration1, proxyInfo);
- IpConfiguration expectedConfig2 = newIpConfiguration(IpAssignment.STATIC,
- ProxySettings.STATIC, staticIpConfiguration2, proxyInfo);
-
- ArrayMap<String, IpConfiguration> expectedNetworks = new ArrayMap<>();
- expectedNetworks.put(IFACE_1, expectedConfig1);
- expectedNetworks.put(IFACE_2, expectedConfig2);
-
- MockedDelayedDiskWrite writer = new MockedDelayedDiskWrite();
- IpConfigStore store = new IpConfigStore(writer);
- store.writeIpConfigurations("file/path/not/used/", expectedNetworks);
-
- InputStream in = new ByteArrayInputStream(writer.byteStream.toByteArray());
- ArrayMap<String, IpConfiguration> actualNetworks = IpConfigStore.readIpConfigurations(in);
- assertNotNull(actualNetworks);
- assertEquals(2, actualNetworks.size());
- assertEquals(expectedNetworks.get(IFACE_1), actualNetworks.get(IFACE_1));
- assertEquals(expectedNetworks.get(IFACE_2), actualNetworks.get(IFACE_2));
- }
-
- private IpConfiguration newIpConfiguration(IpAssignment ipAssignment,
- ProxySettings proxySettings, StaticIpConfiguration staticIpConfig, ProxyInfo info) {
- final IpConfiguration config = new IpConfiguration();
- config.setIpAssignment(ipAssignment);
- config.setProxySettings(proxySettings);
- config.setStaticIpConfiguration(staticIpConfig);
- config.setHttpProxy(info);
- return config;
- }
-
- // This is simplified snapshot of code that was used to store values in V2 format (key as int).
- private static void writeDhcpConfigV2(DataOutputStream out, int configKey,
- IpConfiguration config) throws IOException {
- out.writeInt(2); // VERSION 2
- switch (config.getIpAssignment()) {
- case DHCP:
- out.writeUTF("ipAssignment");
- out.writeUTF(config.getIpAssignment().toString());
- break;
- default:
- fail("Not supported in test environment");
- }
-
- out.writeUTF("id");
- out.writeInt(configKey);
- out.writeUTF("eos");
- }
-
- /** Synchronously writes into given byte steam */
- private static class MockedDelayedDiskWrite extends DelayedDiskWrite {
- final ByteArrayOutputStream mByteStream = new ByteArrayOutputStream();
-
- @Override
- public void write(String filePath, Writer w) {
- DataOutputStream outputStream = new DataOutputStream(mByteStream);
-
- try {
- w.onWriteCalled(outputStream);
- } catch (IOException e) {
- fail();
- }
- }
- }
-}
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 1b7298a..9a80b02 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -51,6 +51,7 @@
"SettingsLibSettingsTransition",
"SettingsLibButtonPreference",
"setupdesign",
+ "zxing-core-1.7",
],
// ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_SHARED_JAVA_LIBRARIES
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
index b78eae4..7c9a045 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
@@ -144,6 +144,5 @@
for (OnMainSwitchChangeListener listener : mSwitchChangeListeners) {
mMainSwitchBar.addOnSwitchChangeListener(listener);
}
- mSwitchChangeListeners.clear();
}
}
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v31/settingslib_preference_dialog_edittext.xml b/packages/SettingsLib/SettingsTheme/res/layout-v31/settingslib_preference_dialog_edittext.xml
new file mode 100644
index 0000000..79a1c49
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/layout-v31/settingslib_preference_dialog_edittext.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<!--Synced from androidx preference/preference/res/layout/preference_dialog_edittext.xml-->
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginTop="48dp"
+ android:layout_marginBottom="48dp"
+ android:overScrollMode="ifContentScrolls">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@android:id/message"
+ style="?android:attr/textAppearanceSmall"
+ android:layout_marginLeft="24dp"
+ android:layout_marginRight="24dp"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="24dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textColor="?android:attr/textColorSecondary"/>
+
+ <EditText
+ android:id="@android:id/edit"
+ android:layout_marginLeft="20dp"
+ android:layout_marginRight="20dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="20dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight = "48dp" />
+
+ </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/style_preference.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/style_preference.xml
index e61d553..bda478e 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v31/style_preference.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v31/style_preference.xml
@@ -47,6 +47,7 @@
<style name="SettingsEditTextPreference.SettingsLib"
parent="@style/Preference.DialogPreference.EditTextPreference.Material">
<item name="layout">@layout/settingslib_preference</item>
+ <item name="dialogLayout">@layout/settingslib_preference_dialog_edittext</item>
<item name="iconSpaceReserved">@bool/settingslib_config_icon_space_reserved</item>
</style>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 1c1e1ba3..a9f5f85 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -410,12 +410,14 @@
<string name="launch_defaults_none">No defaults set</string>
<!-- DO NOT TRANSLATE Empty summary for dynamic preferences -->
<string name="summary_empty" translatable="false"></string>
+ <!-- DO NOT TRANSLATE Summary placeholder -->
+ <string name="summary_placeholder" translatable="false"> </string>
<!-- Text-To-Speech (TTS) settings --><skip />
<!-- Name of the TTS package as listed by the package manager. -->
<string name="tts_settings">Text-to-speech settings</string>
<!-- TTS option item name in the main settings screen -->
<string name="tts_settings_title">Text-to-speech output</string>
- <!-- On main TTS Settings screen, in default settings section, setting default speech rate for synthesized voice -->
+ <!-- On main TTS Settings screen, in default settings section, setting default speech rate for synthesized voice -->
<string name="tts_default_rate_title">Speech rate</string>
<!-- On main TTS Settings screen, summary for default speech rate for synthesized voice -->
<string name="tts_default_rate_summary">Speed at which the text is spoken</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/SettingsInjector.java b/packages/SettingsLib/src/com/android/settingslib/location/SettingsInjector.java
index ea5105b..6fb0179 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/SettingsInjector.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/SettingsInjector.java
@@ -35,6 +35,7 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AttributeSet;
@@ -449,17 +450,22 @@
if (setting == null) {
return;
}
- final Preference preference = setting.preference;
Bundle bundle = msg.getData();
- boolean enabled = bundle.getBoolean(SettingInjectorService.ENABLED_KEY, true);
- String summary = bundle.getString(SettingInjectorService.SUMMARY_KEY, null);
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, setting + ": received " + msg + ", bundle: " + bundle);
}
- preference.setSummary(summary);
+ boolean enabled = bundle.getBoolean(SettingInjectorService.ENABLED_KEY, true);
+ String summary = bundle.getString(SettingInjectorService.SUMMARY_KEY);
+ final Preference preference = setting.preference;
+ if (TextUtils.isEmpty(summary)) {
+ // Set a placeholder summary when received empty summary from injected service.
+ // This is necessary to avoid preference height change.
+ preference.setSummary(R.string.summary_placeholder);
+ } else {
+ preference.setSummary(summary);
+ }
preference.setEnabled(enabled);
- mHandler.sendMessage(
- mHandler.obtainMessage(WHAT_RECEIVED_STATUS, setting));
+ mHandler.sendMessage(mHandler.obtainMessage(WHAT_RECEIVED_STATUS, setting));
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeGenerator.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeGenerator.java
new file mode 100644
index 0000000..bc5824a
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeGenerator.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.qrcode;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+public final class QrCodeGenerator {
+ /**
+ * Generates a barcode image with {@code contents}.
+ *
+ * @param contents The contents to encode in the barcode
+ * @param size The preferred image size in pixels
+ * @return Barcode bitmap
+ */
+ public static Bitmap encodeQrCode(String contents, int size)
+ throws WriterException, IllegalArgumentException {
+ final Map<EncodeHintType, Object> hints = new HashMap<>();
+ if (!isIso88591(contents)) {
+ hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());
+ }
+
+ final BitMatrix qrBits = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE,
+ size, size, hints);
+ final Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.RGB_565);
+ for (int x = 0; x < size; x++) {
+ for (int y = 0; y < size; y++) {
+ bitmap.setPixel(x, y, qrBits.get(x, y) ? Color.BLACK : Color.WHITE);
+ }
+ }
+ return bitmap;
+ }
+
+ private static boolean isIso88591(String contents) {
+ CharsetEncoder encoder = StandardCharsets.ISO_8859_1.newEncoder();
+ return encoder.canEncode(contents);
+ }
+}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 057a9b0..e358b16 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -236,6 +236,7 @@
Settings.Global.DEVICE_NAME,
Settings.Global.DEVICE_POLICY_CONSTANTS,
Settings.Global.DEVICE_PROVISIONED,
+ Settings.Global.BYPASS_DEVICE_POLICY_MANAGEMENT_ROLE_QUALIFICATIONS,
Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED,
Settings.Global.DISK_FREE_CHANGE_REPORTING_THRESHOLD,
Settings.Global.DISPLAY_PANEL_LPM,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 955aee9..03384a2 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -110,7 +110,7 @@
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<uses-permission android:name="android.permission.READ_INSTALL_SESSIONS" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
- <uses-permission android:name="android.permission.SEND_LOST_MODE_LOCATION_UPDATES" />
+ <uses-permission android:name="android.permission.TRIGGER_LOST_MODE" />
<!-- ACCESS_BACKGROUND_LOCATION is needed for testing purposes only. -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- ACCESS_MTP is needed for testing purposes only. -->
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 8cc9e00..f05c1e2 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -128,6 +128,10 @@
kotlincflags: ["-Xjvm-default=enable"],
plugins: ["dagger2-compiler"],
+
+ lint: {
+ extra_check_modules: ["SystemUILintChecker"],
+ },
}
filegroup {
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 8323e32..6c8a92d 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -72,6 +72,7 @@
xuqiu@google.com
zakcohen@google.com
jernej@google.com
+jglazier@google.com
#Android Auto
hseog@google.com
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
index 5b3e45c..35b4166 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
@@ -1,15 +1,15 @@
package com.android.systemui.animation
import android.app.ActivityManager
-import android.view.SurfaceControl
import android.view.View
-import android.view.ViewRootImpl
+import android.window.SurfaceSyncer
/** A util class to synchronize 2 view roots. */
// TODO(b/200284684): Remove this class.
object ViewRootSync {
// TODO(b/217621394): Remove special handling for low-RAM devices after animation sync is fixed
private val forceDisableSynchronization = ActivityManager.isLowRamDeviceStatic()
+ private var surfaceSyncer: SurfaceSyncer? = null
/**
* Synchronize the next draw between the view roots of [view] and [otherView], then run [then].
@@ -33,35 +33,11 @@
return
}
- // Consume the next frames of both view roots to make sure the ghost view is drawn at
- // exactly the same time as when the touch surface is made invisible.
- var remainingTransactions = 0
- val mergedTransactions = SurfaceControl.Transaction()
-
- fun onTransaction(transaction: SurfaceControl.Transaction?) {
- remainingTransactions--
- transaction?.let { mergedTransactions.merge(it) }
-
- if (remainingTransactions == 0) {
- mergedTransactions.apply()
- then()
- }
- }
-
- fun consumeNextDraw(viewRootImpl: ViewRootImpl) {
- if (viewRootImpl.consumeNextDraw(::onTransaction)) {
- remainingTransactions++
-
- // Make sure we trigger a traversal.
- viewRootImpl.view.invalidate()
- }
- }
-
- consumeNextDraw(view.viewRootImpl)
- consumeNextDraw(otherView.viewRootImpl)
-
- if (remainingTransactions == 0) {
- then()
+ surfaceSyncer = SurfaceSyncer().apply {
+ val syncId = setupSync(Runnable { then() })
+ addToSync(syncId, view)
+ addToSync(syncId, otherView)
+ markSyncReady(syncId)
}
}
diff --git a/packages/SystemUI/checks/Android.bp b/packages/SystemUI/checks/Android.bp
new file mode 100644
index 0000000..8457312
--- /dev/null
+++ b/packages/SystemUI/checks/Android.bp
@@ -0,0 +1,52 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_library_host {
+ name: "SystemUILintChecker",
+ srcs: [
+ "src/**/*.kt",
+ "src/**/*.java",
+ ],
+ plugins: ["auto_service_plugin"],
+ libs: [
+ "auto_service_annotations",
+ "lint_api",
+ ],
+}
+
+java_test_host {
+ name: "SystemUILintCheckerTest",
+ srcs: [
+ "tests/**/*.kt",
+ "tests/**/*.java",
+ ],
+ static_libs: [
+ "SystemUILintChecker",
+ "junit",
+ "lint",
+ "lint_tests",
+ ],
+ test_options: {
+ unit_test: true,
+ },
+}
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/BroadcastSentViaContextDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/BroadcastSentViaContextDetector.kt
new file mode 100644
index 0000000..8d48f09
--- /dev/null
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/BroadcastSentViaContextDetector.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.systemui.lint
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiMethod
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UClass
+import org.jetbrains.uast.getParentOfType
+
+/**
+ * Checks if anyone is calling sendBroadcast / sendBroadcastAsUser on a Context (or subclasses) and
+ * directs them to using com.android.systemui.broadcast.BroadcastSender instead.
+ */
+@Suppress("UnstableApiUsage")
+class BroadcastSentViaContextDetector : Detector(), SourceCodeScanner {
+
+ override fun getApplicableMethodNames(): List<String> {
+ return listOf("sendBroadcast", "sendBroadcastAsUser")
+ }
+
+ override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+ if (node.getParentOfType(UClass::class.java)?.qualifiedName ==
+ "com.android.systemui.broadcast.BroadcastSender"
+ ) {
+ // Don't warn for class we want the developers to use.
+ return
+ }
+
+ val evaulator = context.evaluator
+ if (evaulator.isMemberInSubClassOf(method, "android.content.Context")) {
+ context.report(
+ ISSUE,
+ method,
+ context.getNameLocation(node),
+ "Please don't call sendBroadcast/sendBroadcastAsUser directly on " +
+ "Context, use com.android.systemui.broadcast.BroadcastSender instead."
+ )
+ }
+ }
+
+ companion object {
+ @JvmField
+ val ISSUE: Issue =
+ Issue.create(
+ id = "BroadcastSentViaContext",
+ briefDescription = "Broadcast sent via Context instead of BroadcastSender.",
+ explanation =
+ "Broadcast was sent via " +
+ "Context.sendBroadcast/Context.sendBroadcastAsUser. Please use " +
+ "BroadcastSender.sendBroadcast/BroadcastSender.sendBroadcastAsUser " +
+ "which will schedule dispatch of broadcasts on background thread. " +
+ "Sending broadcasts on main thread causes jank due to synchronous " +
+ "Binder calls.",
+ category = Category.PERFORMANCE,
+ priority = 8,
+ severity = Severity.WARNING,
+ implementation =
+ Implementation(BroadcastSentViaContextDetector::class.java, Scope.JAVA_FILE_SCOPE)
+ )
+ }
+}
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
new file mode 100644
index 0000000..397a110
--- /dev/null
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.systemui.lint
+
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+import com.android.tools.lint.detector.api.CURRENT_API
+import com.android.tools.lint.detector.api.Issue
+import com.google.auto.service.AutoService
+
+@AutoService(IssueRegistry::class)
+@Suppress("UnstableApiUsage")
+class SystemUIIssueRegistry : IssueRegistry() {
+
+ override val issues: List<Issue>
+ get() = listOf(BroadcastSentViaContextDetector.ISSUE)
+
+ override val api: Int
+ get() = CURRENT_API
+ override val minApi: Int
+ get() = 8
+
+ override val vendor: Vendor =
+ Vendor(
+ vendorName = "Android",
+ feedbackUrl = "http://b/issues/new?component=78010",
+ contact = "jernej@google.com"
+ )
+}
diff --git a/packages/SystemUI/checks/tests/com/android/systemui/lint/BroadcastSentViaContextDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/systemui/lint/BroadcastSentViaContextDetectorTest.kt
new file mode 100644
index 0000000..da010212f2
--- /dev/null
+++ b/packages/SystemUI/checks/tests/com/android/systemui/lint/BroadcastSentViaContextDetectorTest.kt
@@ -0,0 +1,150 @@
+package com.android.internal.systemui.lint
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestFiles
+import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.checks.infrastructure.TestLintTask
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Test
+
+class BroadcastSentViaContextDetectorTest : LintDetectorTest() {
+
+ override fun getDetector(): Detector = BroadcastSentViaContextDetector()
+ override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)
+
+ override fun getIssues(): List<Issue> = listOf(
+ BroadcastSentViaContextDetector.ISSUE)
+
+ @Test
+ fun testSendBroadcast() {
+ lint().files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import android.content.Context;
+
+ public class TestClass1 {
+ public void send(Context context) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ context.sendBroadcast(intent);
+ }
+ }
+ """
+ ).indented(),
+ *stubs)
+ .issues(BroadcastSentViaContextDetector.ISSUE)
+ .run()
+ .expectWarningCount(1)
+ .expectContains(
+ "Please don't call sendBroadcast/sendBroadcastAsUser directly on " +
+ "Context, use com.android.systemui.broadcast.BroadcastSender instead.")
+ }
+
+ @Test
+ fun testSendBroadcastAsUser() {
+ lint().files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import android.content.Context;
+ import android.os.UserHandle;
+
+ public class TestClass1 {
+ public void send(Context context) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ context.sendBroadcastAsUser(intent, UserHandle.ALL, "permission");
+ }
+ }
+ """).indented(),
+ *stubs)
+ .issues(BroadcastSentViaContextDetector.ISSUE)
+ .run()
+ .expectWarningCount(1)
+ .expectContains(
+ "Please don't call sendBroadcast/sendBroadcastAsUser directly on " +
+ "Context, use com.android.systemui.broadcast.BroadcastSender instead.")
+ }
+
+ @Test
+ fun testSendBroadcastInActivity() {
+ lint().files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import android.app.Activity;
+ import android.os.UserHandle;
+
+ public class TestClass1 {
+ public void send(Activity activity) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ activity.sendBroadcastAsUser(intent, UserHandle.ALL, "permission");
+ }
+
+ }
+ """).indented(),
+ *stubs)
+ .issues(BroadcastSentViaContextDetector.ISSUE)
+ .run()
+ .expectWarningCount(1)
+ .expectContains(
+ "Please don't call sendBroadcast/sendBroadcastAsUser directly on " +
+ "Context, use com.android.systemui.broadcast.BroadcastSender instead.")
+ }
+
+ @Test
+ fun testNoopIfNoCall() {
+ lint().files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import android.content.Context;
+
+ public class TestClass1 {
+ public void sendBroadcast() {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ context.startActivity(intent);
+ }
+ }
+ """).indented(),
+ *stubs)
+ .issues(BroadcastSentViaContextDetector.ISSUE)
+ .run()
+ .expectClean()
+ }
+
+ private val contextStub: TestFile = java(
+ """
+ package android.content;
+ import android.os.UserHandle;
+
+ public class Context {
+ public void sendBroadcast(Intent intent) {};
+ public void sendBroadcast(Intent intent, String receiverPermission) {};
+ public void sendBroadcastAsUser(Intent intent, UserHandle userHandle,
+ String permission) {};
+ }
+ """
+ )
+
+ private val activityStub: TestFile = java(
+ """
+ package android.app;
+ import android.content.Context;
+
+ public class Activity extends Context {}
+ """
+ )
+
+ private val userHandleStub: TestFile = java(
+ """
+ package android.os;
+
+ public enum UserHandle {
+ ALL
+ }
+ """
+ )
+
+ private val stubs = arrayOf(contextStub, activityStub, userHandleStub)
+}
diff --git a/packages/SystemUI/docs/broadcasts.md b/packages/SystemUI/docs/broadcasts.md
index e75ae29..0a35725 100644
--- a/packages/SystemUI/docs/broadcasts.md
+++ b/packages/SystemUI/docs/broadcasts.md
@@ -21,6 +21,7 @@
* The `IntentFilter` may or may not contain categories.
* The `IntentFilter` **does not** contain data types, data schemes, data authorities or data paths.
* The broadcast **is not** gated behind a permission.
+* The broadcast **is not** ordered and doesn't need to set result data.
Additionally, the dispatcher supports the following:
@@ -107,3 +108,8 @@
```
Unregistering can be done even if the `BroadcastReceiver` has never been registered with `BroadcastDispatcher`. In that case, it is a No-Op.
+
+### A note on goAsync()
+
+If you're processing a broadcast in a background thread, you shouldn't call `goAsync()` and
+`finish()`. The system will keep sysui alive regardless, so it isn't needed.
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
index 8ad2009..75d95e6 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
@@ -123,6 +123,11 @@
default void setScrollListener(ScrollListener scrollListener) {}
/**
+ * Sets the amount of vertical over scroll that should be performed on QS.
+ */
+ default void setOverScrollAmount(int overScrollAmount) {}
+
+ /**
* Callback for when QSPanel container is scrolled
*/
@ProvidesInterface(version = ScrollListener.VERSION)
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index 669d6a3..2b16999 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -39,7 +39,7 @@
@DependsOn(target = Icon.class)
@DependsOn(target = State.class)
public interface QSTile {
- int VERSION = 3;
+ int VERSION = 4;
String getTileSpec();
@@ -114,6 +114,12 @@
return false;
}
+ /**
+ * Return whether the tile is set to its listening state and therefore receiving updates and
+ * refreshes from controllers
+ */
+ boolean isListening();
+
@ProvidesInterface(version = Callback.VERSION)
interface Callback {
static final int VERSION = 2;
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index 166be1b..8e58b90 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -21,7 +21,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Ange pinkoden"</string>
- <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Ange det grafiska lösenordet"</string>
+ <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Ange mönstret"</string>
<string name="keyguard_enter_your_password" msgid="7225626204122735501">"Ange ditt lösenord"</string>
<string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Ogiltigt kort."</string>
<string name="keyguard_charged" msgid="5478247181205188995">"Laddat"</string>
diff --git a/packages/SystemUI/res/drawable/ic_media_pause.xml b/packages/SystemUI/res/drawable/ic_media_pause.xml
index 1f4b2cf..0009b6c 100644
--- a/packages/SystemUI/res/drawable/ic_media_pause.xml
+++ b/packages/SystemUI/res/drawable/ic_media_pause.xml
@@ -1,26 +1,91 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="14dp"
- android:height="16dp"
- android:viewportWidth="14"
- android:viewportHeight="16">
- <path
- android:pathData="M9.1818,15.6363H13.5455V0.3635H9.1818V15.6363ZM0.4546,15.6363H4.8182V0.3635H0.4546V15.6363Z"
- android:fillColor="#FFFFFF"
- android:fillType="evenOdd"/>
-</vector>
\ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="24dp"
+ android:width="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G"
+ android:translateX="12"
+ android:translateY="12.125">
+ <path android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillColor="#ffffff"
+ android:fillAlpha="1"
+ android:fillType="nonZero"
+ android:pathData=" M-6 7 C-6,7 -2,7 -2,7 C-2,7 -2,-7 -2,-7 C-2,-7 -6,-7 -6,-7 C-6,-7 -6,7 -6,7c "/>
+ </group>
+ <group android:name="_R_G_L_0_G"
+ android:translateX="12"
+ android:translateY="12.125">
+ <path android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillColor="#ffffff"
+ android:fillAlpha="1"
+ android:fillType="nonZero"
+ android:pathData=" M2 7 C2,7 6,7 6,7 C6,7 6,-0.12 6,-0.12 C6,-0.12 6,-7 6,-7 C6,-7 2,-7 2,-7 C2,-7 2,7 2,7c "/>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData"
+ android:duration="333"
+ android:startOffset="0"
+ android:valueFrom="M-6 7 C-6,7 -2,7 -2,7 C-2,7 -2,-7 -2,-7 C-2,-7 -6,-7 -6,-7 C-6,-7 -6,7 -6,7c "
+ android:valueTo="M-6 7 C-6,7 -2,3.94 -2,3.94 C-2,3.94 -2,-4.37 -2,-4.37 C-2,-4.37 -6,-7 -6,-7 C-6,-7 -6,7 -6,7c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData"
+ android:duration="333"
+ android:startOffset="0"
+ android:valueFrom="M2 7 C2,7 6,7 6,7 C6,7 6,-0.12 6,-0.12 C6,-0.12 6,-7 6,-7 C6,-7 2,-7 2,-7 C2,-7 2,7 2,7c "
+ android:valueTo="M-5.62 7 C-5.62,7 -4.75,7 -4.75,7 C-4.75,7 6,-0.12 6,-0.12 C6,-0.12 -4.44,-7 -4.44,-7 C-4.44,-7 -5.62,-7 -5.62,-7 C-5.62,-7 -5.62,7 -5.62,7c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX"
+ android:duration="517"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_media_pause_container.xml b/packages/SystemUI/res/drawable/ic_media_pause_container.xml
new file mode 100644
index 0000000..b92e635
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_media_pause_container.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G"
+ android:translateX="24"
+ android:translateY="24"
+ android:scaleX="0.5"
+ android:scaleY="0.5"/>
+ <group android:name="_R_G_L_0_G"
+ android:translateX="24"
+ android:translateY="24"
+ android:scaleX="0.5"
+ android:scaleY="0.5">
+ <path android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillColor="#ffddb3"
+ android:fillAlpha="1"
+ android:fillType="nonZero"
+ android:pathData=" M48 -16 C48,-16 48,16 48,16 C48,33.67 33.67,48 16,48 C16,48 -16,48 -16,48 C-33.67,48 -48,33.67 -48,16 C-48,16 -48,-16 -48,-16 C-48,-33.67 -33.67,-48 -16,-48 C-16,-48 16,-48 16,-48 C33.67,-48 48,-33.67 48,-16c "/>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData"
+ android:duration="500"
+ android:startOffset="0"
+ android:valueFrom="M48 -16 C48,-16 48,16 48,16 C48,33.67 33.67,48 16,48 C16,48 -16,48 -16,48 C-33.67,48 -48,33.67 -48,16 C-48,16 -48,-16 -48,-16 C-48,-33.67 -33.67,-48 -16,-48 C-16,-48 16,-48 16,-48 C33.67,-48 48,-33.67 48,-16c "
+ android:valueTo="M48 0.25 C48,0.25 48,0 48,0 C47.75,26 31.25,48 0,48 C0,48 0,48 0,48 C-30,48 -48,25.75 -48,-0.25 C-48,-0.25 -48,-0.25 -48,-0.25 C-47.75,-23.5 -32.25,-47.75 0.5,-48 C0.5,-48 0.5,-48 0.5,-48 C28,-47.75 47.75,-29.75 48,0.25c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.526,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX"
+ android:duration="517"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_media_play.xml b/packages/SystemUI/res/drawable/ic_media_play.xml
index 0eac1ad..eb32470 100644
--- a/packages/SystemUI/res/drawable/ic_media_play.xml
+++ b/packages/SystemUI/res/drawable/ic_media_play.xml
@@ -1,26 +1,91 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M20,12L6,21V3L20,12ZM15.26,12L8.55,7.68V16.32L15.26,12Z"
- android:fillColor="#FFFFFF"
- android:fillType="evenOdd"/>
-</vector>
\ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="24dp"
+ android:width="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G"
+ android:translateX="12"
+ android:translateY="12.125">
+ <path android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillColor="#ffffff"
+ android:fillAlpha="1"
+ android:fillType="nonZero"
+ android:pathData=" M-6 7 C-6,7 -2,3.94 -2,3.94 C-2,3.94 -2,-4.37 -2,-4.37 C-2,-4.37 -6,-7 -6,-7 C-6,-7 -6,7 -6,7c "/>
+ </group>
+ <group android:name="_R_G_L_0_G"
+ android:translateX="12"
+ android:translateY="12.125">
+ <path android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillColor="#ffffff"
+ android:fillAlpha="1"
+ android:fillType="nonZero"
+ android:pathData=" M-5.62 7 C-5.62,7 -4.75,7 -4.75,7 C-4.75,7 6,-0.12 6,-0.12 C6,-0.12 -4.44,-7 -4.44,-7 C-4.44,-7 -5.62,-7 -5.62,-7 C-5.62,-7 -5.62,7 -5.62,7c "/>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData"
+ android:duration="333"
+ android:startOffset="0"
+ android:valueFrom="M-6 7 C-6,7 -2,3.94 -2,3.94 C-2,3.94 -2,-4.37 -2,-4.37 C-2,-4.37 -6,-7 -6,-7 C-6,-7 -6,7 -6,7c "
+ android:valueTo="M-6 7 C-6,7 -2,7 -2,7 C-2,7 -2,-7 -2,-7 C-2,-7 -6,-7 -6,-7 C-6,-7 -6,7 -6,7c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData"
+ android:duration="333"
+ android:startOffset="0"
+ android:valueFrom="M-5.62 7 C-5.62,7 -4.75,7 -4.75,7 C-4.75,7 6,-0.12 6,-0.12 C6,-0.12 -4.44,-7 -4.44,-7 C-4.44,-7 -5.62,-7 -5.62,-7 C-5.62,-7 -5.62,7 -5.62,7c "
+ android:valueTo="M2 7 C2,7 6,7 6,7 C6,7 6,-0.12 6,-0.12 C6,-0.12 6,-7 6,-7 C6,-7 2,-7 2,-7 C2,-7 2,7 2,7c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX"
+ android:duration="517"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_media_play_container.xml b/packages/SystemUI/res/drawable/ic_media_play_container.xml
new file mode 100644
index 0000000..2fc9fc8
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_media_play_container.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_0_G"
+ android:translateX="24"
+ android:translateY="24"
+ android:scaleX="0.5"
+ android:scaleY="0.5">
+ <path android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillColor="#ffddb3"
+ android:fillAlpha="1"
+ android:fillType="nonZero"
+ android:pathData=" M48 0.25 C48,0.25 48,0 48,0 C47.75,26 31.25,48 0,48 C0,48 0,48 0,48 C-30,48 -48,25.75 -48,-0.25 C-48,-0.25 -48,-0.25 -48,-0.25 C-47.75,-23.5 -32.25,-47.75 0.5,-48 C0.5,-48 0.5,-48 0.5,-48 C28,-47.75 47.75,-29.75 48,0.25c "/>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData"
+ android:duration="500"
+ android:startOffset="0"
+ android:valueFrom="M48 0.25 C48,0.25 48,0 48,0 C47.75,26 31.25,48 0,48 C0,48 0,48 0,48 C-30,48 -48,25.75 -48,-0.25 C-48,-0.25 -48,-0.25 -48,-0.25 C-47.75,-23.5 -32.25,-47.75 0.5,-48 C0.5,-48 0.5,-48 0.5,-48 C28,-47.75 47.75,-29.75 48,0.25c "
+ android:valueTo="M48 -16 C48,-16 48,16 48,16 C48,33.67 33.67,48 16,48 C16,48 -16,48 -16,48 C-33.67,48 -48,33.67 -48,16 C-48,16 -48,-16 -48,-16 C-48,-33.67 -33.67,-48 -16,-48 C-16,-48 16,-48 16,-48 C33.67,-48 48,-33.67 48,-16c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.518,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX"
+ android:duration="517"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_warning.xml b/packages/SystemUI/res/drawable/ic_warning.xml
index fbed779..9f90db2 100644
--- a/packages/SystemUI/res/drawable/ic_warning.xml
+++ b/packages/SystemUI/res/drawable/ic_warning.xml
@@ -16,4 +16,4 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:fillColor="@android:color/white" android:pathData="M12,12.5zM1,21L12,2l11,19zM11,15h2v-5h-2zM12,18q0.425,0 0.713,-0.288Q13,17.425 13,17t-0.287,-0.712Q12.425,16 12,16t-0.713,0.288Q11,16.575 11,17t0.287,0.712Q11.575,18 12,18zM4.45,19h15.1L12,6z"/>
-</vector>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/overlay_button_background.xml b/packages/SystemUI/res/drawable/overlay_button_background.xml
index 3c39fe2..0e8438c 100644
--- a/packages/SystemUI/res/drawable/overlay_button_background.xml
+++ b/packages/SystemUI/res/drawable/overlay_button_background.xml
@@ -14,20 +14,27 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<!-- Long screenshot save/cancel button background -->
+<!-- Button background for activities downstream of overlays
+ (clipboard text editor, long screenshots) -->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:color="?android:textColorPrimary">
<item android:id="@android:id/background">
- <shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/colorAccentPrimary"/>
- <corners android:radius="20dp"/>
- </shape>
+ <inset android:insetTop="4dp" android:insetBottom="4dp">
+ <shape android:shape="rectangle">
+ <solid android:color="?androidprv:attr/colorAccentPrimary"/>
+ <corners android:radius="20dp"/>
+ <size android:height="40dp"/>
+ </shape>
+ </inset>
</item>
<item android:id="@android:id/mask">
- <shape android:shape="rectangle">
- <solid android:color="?android:textColorPrimary"/>
- <corners android:radius="20dp"/>
- </shape>
+ <inset android:insetTop="4dp" android:insetBottom="4dp">
+ <shape android:shape="rectangle">
+ <solid android:color="?android:textColorPrimary"/>
+ <corners android:radius="20dp"/>
+ <size android:height="40dp"/>
+ </shape>
+ </inset>
</item>
</ripple>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
index da4088f..1122ca6 100644
--- a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
+++ b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
@@ -6,13 +6,14 @@
android:layout_height="match_parent">
<Button
- android:id="@+id/copy_button"
- style="@android:style/Widget.DeviceDefault.Button.Colored"
+ android:id="@+id/done_button"
+ style="@style/EditTextActivityButton"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="8dp"
+ android:layout_height="48dp"
android:layout_marginTop="8dp"
- android:text="@string/clipboard_edit_text_copy"
+ android:layout_marginStart="12dp"
+ android:background="@drawable/overlay_button_background"
+ android:text="@string/clipboard_edit_text_done"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -20,22 +21,23 @@
android:id="@+id/attribution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- app:layout_constraintStart_toStartOf="@+id/copy_button"
- app:layout_constraintTop_toBottomOf="@+id/copy_button" />
+ android:layout_marginTop="40dp"
+ android:layout_marginStart="4dp"
+ app:layout_constraintStart_toStartOf="@id/done_button"
+ app:layout_constraintTop_toBottomOf="@id/done_button" />
<ImageButton
android:id="@+id/share"
style="@android:style/Widget.Material.Button.Borderless"
android:layout_width="48dp"
android:layout_height="48dp"
- android:layout_marginEnd="8dp"
android:padding="12dp"
android:scaleType="fitCenter"
android:contentDescription="@*android:string/share"
android:tooltipText="@*android:string/share"
+ android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="@+id/copy_button"
+ app:layout_constraintTop_toTopOf="@id/done_button"
android:tint="?android:attr/textColorPrimary"
android:src="@drawable/ic_screenshot_share" />
@@ -43,17 +45,19 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
+ android:layout_marginStart="4dp"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintStart_toStartOf="@+id/copy_button"
- app:layout_constraintTop_toBottomOf="@+id/attribution">
+ app:layout_constraintStart_toStartOf="@id/done_button"
+ app:layout_constraintEnd_toEndOf="@id/share"
+ app:layout_constraintTop_toBottomOf="@id/attribution">
<EditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:background="@null"
android:gravity="start|top"
android:textSize="24sp" />
</ScrollView>
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index 2782300..c0436b2 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -16,7 +16,9 @@
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:theme="@style/FloatingOverlay"
android:alpha="0"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -28,7 +30,6 @@
android:src="@drawable/overlay_actions_background_protection"/>
<com.android.systemui.screenshot.DraggableConstraintLayout
android:id="@+id/clipboard_ui"
- android:theme="@style/FloatingOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
@@ -118,7 +119,8 @@
android:autoSizeTextType="uniform"
android:autoSizeMinTextSize="10sp"
android:autoSizeMaxTextSize="200sp"
- android:textColor="?android:attr/textColorPrimary"
+ android:textColor="?attr/overlayButtonTextColor"
+ android:background="?androidprv:attr/colorAccentSecondary"
android:layout_width="@dimen/clipboard_preview_size"
android:layout_height="@dimen/clipboard_preview_size"/>
<ImageView
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index cdf6103..2927d6b 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -27,7 +27,7 @@
android:id="@+id/save"
style="@android:style/Widget.DeviceDefault.Button.Colored"
android:layout_width="wrap_content"
- android:layout_height="40dp"
+ android:layout_height="48dp"
android:text="@string/save"
android:layout_marginStart="8dp"
android:layout_marginTop="@dimen/long_screenshot_action_bar_top_margin"
@@ -41,7 +41,7 @@
android:id="@+id/cancel"
style="@android:style/Widget.DeviceDefault.Button.Colored"
android:layout_width="wrap_content"
- android:layout_height="40dp"
+ android:layout_height="48dp"
android:text="@android:string/cancel"
android:layout_marginStart="6dp"
android:layout_marginTop="@dimen/long_screenshot_action_bar_top_margin"
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 6cf3215..e1f3eca 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -145,8 +145,7 @@
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="@dimen/qs_media_padding"
- android:layout_marginEnd="@dimen/qs_media_padding"
- />
+ android:layout_marginEnd="@dimen/qs_media_padding" />
<!-- See comment in media_session_collapsed.xml for how these barriers are used -->
<androidx.constraintlayout.widget.Barrier
@@ -172,10 +171,19 @@
app:layout_constraintStart_toStartOf="parent"
/>
+ <androidx.constraintlayout.widget.Barrier
+ android:id="@+id/media_action_barrier_top"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:barrierDirection="top"
+ app:constraint_referenced_ids="actionPrev,media_progress_bar,actionNext,action0,action1,action2,action3,action4"
+ />
+
<!-- Button visibility will be controlled in code -->
<ImageButton
android:id="@+id/actionPrev"
- style="@style/MediaPlayer.SessionAction"
+ style="@style/MediaPlayer.SessionAction.Secondary"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="4dp"
@@ -202,7 +210,7 @@
<ImageButton
android:id="@+id/actionNext"
- style="@style/MediaPlayer.SessionAction"
+ style="@style/MediaPlayer.SessionAction.Secondary"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="0dp"
@@ -212,7 +220,7 @@
<ImageButton
android:id="@+id/action0"
- style="@style/MediaPlayer.SessionAction"
+ style="@style/MediaPlayer.SessionAction.Secondary"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="@dimen/qs_media_action_spacing"
@@ -222,7 +230,7 @@
<ImageButton
android:id="@+id/action1"
- style="@style/MediaPlayer.SessionAction"
+ style="@style/MediaPlayer.SessionAction.Secondary"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="@dimen/qs_media_action_spacing"
@@ -232,7 +240,7 @@
<ImageButton
android:id="@+id/action2"
- style="@style/MediaPlayer.SessionAction"
+ style="@style/MediaPlayer.SessionAction.Secondary"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="@dimen/qs_media_action_spacing"
@@ -242,7 +250,7 @@
<ImageButton
android:id="@+id/action3"
- style="@style/MediaPlayer.SessionAction"
+ style="@style/MediaPlayer.SessionAction.Secondary"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="@dimen/qs_media_action_spacing"
@@ -252,7 +260,7 @@
<ImageButton
android:id="@+id/action4"
- style="@style/MediaPlayer.SessionAction"
+ style="@style/MediaPlayer.SessionAction.Secondary"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="@dimen/qs_media_action_spacing"
diff --git a/packages/SystemUI/res/layout/rounded_corners_bottom.xml b/packages/SystemUI/res/layout/rounded_corners_bottom.xml
new file mode 100644
index 0000000..bb6d4bd
--- /dev/null
+++ b/packages/SystemUI/res/layout/rounded_corners_bottom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 2020, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+-->
+<com.android.systemui.RegionInterceptingFrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/rounded_corners_bottom"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <ImageView
+ android:id="@+id/left"
+ android:layout_width="12dp"
+ android:layout_height="12dp"
+ android:layout_gravity="left|bottom"
+ android:tint="#ff000000"
+ android:visibility="gone"
+ android:src="@drawable/rounded_corner_bottom"/>
+
+ <ImageView
+ android:id="@+id/right"
+ android:layout_width="12dp"
+ android:layout_height="12dp"
+ android:tint="#ff000000"
+ android:visibility="gone"
+ android:layout_gravity="right|bottom"
+ android:src="@drawable/rounded_corner_bottom"/>
+
+</com.android.systemui.RegionInterceptingFrameLayout>
diff --git a/packages/SystemUI/res/layout/rounded_corners_top.xml b/packages/SystemUI/res/layout/rounded_corners_top.xml
new file mode 100644
index 0000000..46648c8
--- /dev/null
+++ b/packages/SystemUI/res/layout/rounded_corners_top.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 2020, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+-->
+<com.android.systemui.RegionInterceptingFrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/rounded_corners_top"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <ImageView
+ android:id="@+id/left"
+ android:layout_width="12dp"
+ android:layout_height="12dp"
+ android:layout_gravity="left|top"
+ android:tint="#ff000000"
+ android:visibility="gone"
+ android:src="@drawable/rounded_corner_top"/>
+
+ <ImageView
+ android:id="@+id/right"
+ android:layout_width="12dp"
+ android:layout_height="12dp"
+ android:tint="#ff000000"
+ android:visibility="gone"
+ android:layout_gravity="right|top"
+ android:src="@drawable/rounded_corner_top"/>
+
+</com.android.systemui.RegionInterceptingFrameLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 8d09d76..5123f70 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"As jy met jou volgende poging \'n verkeerde patroon invoer, sal jou werkprofiel en die data daarvan uitgevee word."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"As jy met jou volgende poging \'n verkeerde PIN invoer, sal jou werkprofiel en die data daarvan uitgevee word."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"As jy met jou volgende poging \'n verkeerde wagwoord invoer, sal jou werkprofiel en die data daarvan uitgevee word."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Te veel verkeerde pogings. Hierdie toestel se data sal uitgevee word."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Te veel verkeerde pogings. Hierdie gebruiker sal uitgevee word."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Te veel verkeerde pogings. Hierdie werkprofiel en sy data sal uitgevee word."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Maak toe"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Raak die vingerafdruksensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Vingerafdrukikoon"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Kan nie gesig herken nie. Gebruik eerder vingerafdruk."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Laai tans stadig • Vol oor <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Laaidok • Vol oor <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Wissel gebruiker"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Voeg gebruiker by"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Nuwe gebruiker"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Verwyder gas?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle programme en data in hierdie sessie sal uitgevee word."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Verwyder"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welkom terug, gas!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Wiil jy jou sessie voortsit?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Begin van voor af"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, gaan voort"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Voeg nuwe gebruiker by?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Wanneer jy \'n nuwe gebruiker byvoeg, moet daardie persoon hul spasie opstel.\n\nEnige gebruiker kan programme vir al die ander gebruikers opdateer."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Gebruikerlimiet is bereik"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Jy kan tot <xliff:g id="COUNT">%d</xliff:g> gebruikers byvoeg.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ontsluit om te gebruik"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Kon nie jou kaarte kry nie; probeer later weer"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Sluitskerminstellings"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skandeer QR-kode"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Werkprofiel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Vliegtuigmodus"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Jy sal nie jou volgende wekker <xliff:g id="WHEN">%1$s</xliff:g> hoor nie"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swiep om meer te sien"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Laai tans aanbevelings"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Versteek hierdie mediasessie?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Versteek hierdie mediakontrole vir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Die huidige mediasessie kan nie versteek word nie."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Maak toe"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Versteek"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Hervat"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Instellings"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> deur <xliff:g id="ARTIST_NAME">%2$s</xliff:g> speel tans vanaf <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Beweeg nader aan <xliff:g id="DEVICENAME">%1$s</xliff:g> om hier te speel"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Speel tans op <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Speel tans op hierdie foon"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Iets is fout"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Iets is fout. Probeer weer."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Onaktief, gaan program na"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nie gekry nie"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrole is nie beskikbaar nie"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 83c0184..6793e10 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"በሚቀጥለው ሙከራ ላይ ትክክል ያልሆነ ሥርዓተ ጥለት ካስገቡ የእርስዎ የሥራ መገለጫ እና ውሂቡ ይሰረዛሉ።"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"በሚቀጥለው ሙከራ ላይ ትክክል ያልሆነ ፒን ካስገቡ የእርስዎ የሥራ መገለጫ እና ውሂቡ ይሰረዛሉ።"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"በሚቀጥለው ሙከራ ላይ ትክክል ያልሆነ የይለፍ ቃል ካስገቡ የእርስዎ የሥራ መገለጫ እና ውሂቡ ይሰረዛሉ።"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"በጣም ብዙ ትክክል ያልሆኑ ሙከራዎች። ይህ የመሣሪያ ውሂብ ይሰረዛል።"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"በጣም ብዙ ትክክል ያልሆኑ ሙከራዎች። ይህ ተጠቃሚ ይሰረዛል።"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"በጣም ብዙ ትክክል ያልሆኑ ሙከራዎች። የዚህ የሥራ መገለጫ እና ውሂቡ ይሰረዛሉ።"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"አሰናብት"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"የጣት አሻራ ዳሳሹን ይንኩ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"የጣት አሻራ አዶ"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"መልክን መለየት አልተቻለም። በምትኩ የጣት አሻራ ይጠቀሙ።"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • በዝግታ ኃይልን በመሙላት ላይ • በ<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ውስጥ ይሞላል"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • የባትሪ ኃይል መሙያ መትከያ • በ<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ውስጥ ይሞላል"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ተጠቃሚ ቀይር"</string>
- <string name="user_add_user" msgid="4336657383006913022">"ተጠቃሚ አክል"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"አዲስ ተጠቃሚ"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"እንግዳ ይወገድ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"አስወግድ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"እንኳን በደህና ተመለሱ እንግዳ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ክፍለ-ጊዜዎን መቀጠል ይፈልጋሉ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"እንደገና ጀምር"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"አዎ፣ ቀጥል"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"አዲስ ተጠቃሚ ይታከል?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"እርስዎ አንድ አዲስ ተጠቃሚ ሲያክሉ ያ ሰው የራሱ ቦታ ማዘጋጀት አለበት።\n\nማንኛውም ተጠቃሚ መተግበሪያዎችን ለሌሎች ተጠቃሚዎች ሁሉ ሊያዘምን ይችላል።"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"የተጠቃሚ ገደብ ላይ ተደርሷል"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one"><xliff:g id="COUNT">%d</xliff:g> ተጠቃሚዎች ብቻ ናቸው ሊፈጠሩ የሚችሉት።</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ለማየት ይክፈቱ"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"የእርስዎን ካርዶች ማግኘት ላይ ችግር ነበር፣ እባክዎ ቆይተው እንደገና ይሞክሩ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"የገጽ መቆለፊያ ቅንብሮች"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR ኮድ ቃኝ"</string>
<string name="status_bar_work" msgid="5238641949837091056">"የስራ መገለጫ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"የአውሮፕላን ሁነታ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"የእርስዎን ቀጣይ ማንቂያ <xliff:g id="WHEN">%1$s</xliff:g> አይሰሙም"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ተጨማሪ ለማየት ያንሸራትቱ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ምክሮችን በመጫን ላይ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ሚዲያ"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"ይህ የሚዲያ ክፍለ ጊዜ ይደበቅ?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"ለ<xliff:g id="APP_NAME">%1$s</xliff:g> የዚህ ሚዲያ መቆጣጠሪያ ይደበቅ?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"የአሁኑ የሚዲያ ክፍለ ጊዜ ሊደበቅ አይቻልም።"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"አሰናብት"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ደብቅ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ከቆመበት ቀጥል"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ቅንብሮች"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> በ<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ከ<xliff:g id="APP_LABEL">%3$s</xliff:g> እየተጫወተ ነው"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"እዚህ ለመጫወት ወደ <xliff:g id="DEVICENAME">%1$s</xliff:g> ቀረብ ይበሉ"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"በ<xliff:g id="DEVICENAME">%1$s</xliff:g> ላይ በማጫወት ላይ"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"በዚህ ስልክ በመጫወት ላይ"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"የሆነ ችግር ተፈጥሯል"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"የሆነ ችግር ተፈጥሯል። እንደገና ይሞክሩ።"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ንቁ ያልኾነ፣ መተግበሪያን ይፈትሹ"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"አልተገኘም"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"መቆጣጠሪያ አይገኝም"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 24e36fb..abc686a 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"عند إدخال نقش غير صحيح في المحاولة التالية، سيتم حذف ملفك الشخصي للعمل وبياناته."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"عند إدخال رقم تعريف شخصي غير صحيح في المحاولة التالية، سيتم حذف ملفك الشخصي للعمل وبياناته."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"عند إدخال كلمة مرور غير صحيحة في المحاولة التالية، سيتم حذف ملفك الشخصي للعمل وبياناته."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"لقد استنفدت عدد المحاولات غير الصحيحة وسيتم حذف بيانات هذا الجهاز."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"لقد استنفدت عدد المحاولات غير الصحيحة وسيتم حذف هذا المستخدم."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"لقد استنفدت عدد المحاولات غير الصحيحة وسيتم حذف الملف الشخصي للعمل وبياناته."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"إغلاق"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"المس مستشعر بصمة الإصبع"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"رمز بصمة الإصبع"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"يتعذّر التعرّف على الوجه. استخدِم بصمة الإصبع بدلاً من ذلك."</string>
@@ -331,17 +327,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • جارٍ الشحن ببطء • ستمتلئ البطارية خلال <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • جارٍ الشحن على وحدة الإرساء • ستمتلئ البطارية خلال <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تبديل المستخدم"</string>
- <string name="user_add_user" msgid="4336657383006913022">"إضافة مستخدم"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"مستخدم جديد"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"هل تريد إزالة جلسة الضيف؟"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"سيتم حذف كل التطبيقات والبيانات في هذه الجلسة."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"إزالة"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"مرحبًا بك مجددًا في جلسة الضيف"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"هل تريد متابعة جلستك؟"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"البدء من جديد"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"نعم، متابعة"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"هل تريد إضافة مستخدم جديد؟"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"عند إضافة مستخدم جديد، عليه إعداد مساحته.\n\nويُمكن لأي مستخدم تحديث التطبيقات لجميع المستخدمين الآخرين."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"تم الوصول إلى أقصى عدد للمستخدمين"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="zero">يمكنك إضافة ما يصل إلى <xliff:g id="COUNT">%d</xliff:g> مستخدم.</item>
@@ -471,8 +462,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"فتح القفل للاستخدام"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"حدثت مشكلة أثناء الحصول على البطاقات، يُرجى إعادة المحاولة لاحقًا."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"إعدادات شاشة القفل"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"مسح رمز الاستجابة السريعة ضوئيًا"</string>
<string name="status_bar_work" msgid="5238641949837091056">"الملف الشخصي للعمل"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"وضع الطيران"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"لن تسمع المنبّه القادم في <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -809,9 +799,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"مرّر سريعًا لرؤية المزيد."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"جارٍ تحميل الاقتراحات"</string>
<string name="controls_media_title" msgid="1746947284862928133">"الوسائط"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"هل تريد إخفاء جلسة الوسائط هذه؟"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"لا يمكن إخفاء جلسة الوسائط الحالية."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"إغلاق"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"إخفاء"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"استئناف التشغيل"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"الإعدادات"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"يتم تشغيل <xliff:g id="SONG_NAME">%1$s</xliff:g> للفنان <xliff:g id="ARTIST_NAME">%2$s</xliff:g> من تطبيق <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
@@ -829,7 +820,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"يُرجى الاقتراب من <xliff:g id="DEVICENAME">%1$s</xliff:g> لتشغيل الوسائط هنا."</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"جارٍ تشغيل الوسائط على <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"جارٍ تشغيل الوسائط على هذا الهاتف"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"حدث خطأ."</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"حدث خطأ. يُرجى إعادة المحاولة."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غير نشط، تحقّق من التطبيق."</string>
<string name="controls_error_removed" msgid="6675638069846014366">"لم يتم العثور عليه."</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"عنصر التحكّم غير متوفّر"</string>
@@ -926,7 +917,7 @@
<item quantity="one">تطبيق واحد (<xliff:g id="COUNT_0">%s</xliff:g>) نشط</item>
</plurals>
<string name="fgs_dot_content_description" msgid="2865071539464777240">"معلومات جديدة"</string>
- <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"# تطبيق نشط"</string>
+ <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"التطبيقات النشطة"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"إيقاف"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"متوقّف"</string>
<string name="clipboard_edit_text_copy" msgid="770856373439969178">"نسخ"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 7bb97a7..e3cb119 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"আপুনি পৰৱৰ্তী প্ৰয়াসত এটা ভুল আৰ্হি দিলে, আপোনাৰ কৰ্মস্থানৰ প্ৰ’ফাইল আৰু ইয়াৰ ডেটা মচি পেলোৱা হ’ব।"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"আপুনি পৰৱৰ্তী প্ৰয়াসত এটা ভুল পিন দিলে, আপোনাৰ কৰ্মস্থানৰ প্ৰ’ফাইল আৰু ইয়াৰ ডেটা মচি পেলোৱা হ’ব।"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"আপুনি পৰৱৰ্তী প্ৰয়াসত এটা ভুল পাছৱৰ্ড দিলে, আপোনাৰ কৰ্মস্থানৰ প্ৰ’ফাইল আৰু ইয়াৰ ডেটা মচি পেলোৱা হ’ব।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"বহুসংখ্যক ভুল প্ৰয়াস। এই ডিভাইচটোৰ ডেটা মচা হ\'ব।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"বহুসংখ্যক ভুল প্ৰয়াস। এই ব্যৱহাৰকাৰীক মচা হ\'ব।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"বহুসংখ্যক ভুল প্ৰয়াস। এই কৰ্মস্থানৰ প্ৰ\'ফাইলটো আৰু তাৰ লগত জড়িত ডেটা মচা হ\'ব।"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"অগ্ৰাহ্য কৰক"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো স্পৰ্শ কৰক"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"ফিংগাৰপ্ৰিণ্ট আইকন"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"মুখাৱয়ব চিনিব নোৱাৰি। ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক।"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • লাহে লাহে চাৰ্জ হৈ আছে • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>ত সম্পূৰ্ণ হ’ব"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • চাৰ্জিং ডক • সম্পূৰ্ণ হ’বলৈ <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> লাগিব"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
- <string name="user_add_user" msgid="4336657383006913022">"ব্যৱহাৰকাৰী যোগ কৰক"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"নতুন ব্যৱহাৰকাৰী"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"অতিথি আঁতৰাবনে?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই ছেশ্বনৰ আটাইবোৰ এপ্ আৰু ডেটা মচা হ\'ব।"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"আঁতৰাওক"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"অতিথি, আপোনাক পুনৰ স্বাগতম!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"আপুনি আপোনাৰ ছেশ্বন অব্যাহত ৰাখিব বিচাৰেনে?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আকৌ আৰম্ভ কৰক"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"হয়, অব্যাহত ৰাখক"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"নতুন ব্যৱহাৰকাৰী যোগ কৰিবনে?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"আপুনি যেতিয়া এজন নতুন ব্যৱহাৰকাৰী যোগ কৰে, তেওঁ নিজৰ স্থান ছেট আপ কৰা প্ৰয়োজন।\n\nযিকোনো ব্যৱহাৰকাৰীয়ে নিজৰ লগতে আন ব্যৱহাৰকাৰীৰো এপ্ আপডে’ট কৰিব পাৰে।"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"অধিকতম ব্যৱহাৰকাৰী সৃষ্টি কৰা হ’ল"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">আপুনি <xliff:g id="COUNT">%d</xliff:g> জনলৈকে ব্যৱহাৰকাৰী যোগ কৰিব পাৰে।</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ব্যৱহাৰ কৰিবলৈ আনলক কৰক"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"আপোনাৰ কাৰ্ড লাভ কৰোঁতে এটা সমস্যা হৈছে, অনুগ্ৰহ কৰি পাছত পুনৰ চেষ্টা কৰক"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"লক স্ক্ৰীনৰ ছেটিং"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"কিউআৰ ক’ড স্কেন কৰক"</string>
<string name="status_bar_work" msgid="5238641949837091056">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"এয়াৰপ্লেইন ম\'ড"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"আপুনি আপোনাৰ পিছৰটো এলাৰ্ম <xliff:g id="WHEN">%1$s</xliff:g> বজাত শুনা নাপাব"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"অধিক চাবলৈ ছোৱাইপ কৰক"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"চুপাৰিছসমূহ ল’ড কৰি থকা হৈছে"</string>
<string name="controls_media_title" msgid="1746947284862928133">"মিডিয়া"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"এই মিডিয়াৰ ছেশ্বনটো লুকুৱাবনে?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে এই মিডিয়া নিয়ন্ত্ৰণটো লুকুৱাবনে?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"বৰ্তমানৰ মিডিয়াৰ ছেশ্বনটো লুকুৱাব নোৱাৰি।"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"অগ্ৰাহ্য কৰক"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"লুকুৱাওক"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"পুনৰ আৰম্ভ কৰক"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ছেটিং"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ত <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ৰ <xliff:g id="SONG_NAME">%1$s</xliff:g> গীতটো প্লে’ হৈ আছে"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ইয়াত খেলিবলৈ <xliff:g id="DEVICENAME">%1$s</xliff:g>ৰ আৰু ওচৰলৈ যাওক"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ত প্লে কৰি থকা হৈছে"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"এই ফ’নটোত প্লে কৰি থকা হৈছে"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"কিবা ভুল হ’ল"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"কিবা ভুল হ’ল। পুনৰ চেষ্টা কৰক।"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"সক্ৰিয় নহয়, এপ্টো পৰীক্ষা কৰক"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"বিচাৰি পোৱা নগ’ল"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"নিয়ন্ত্ৰণটো উপলব্ধ নহয়"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index a796a20..81fb71a 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Növbəti cəhddə yanlış model daxil etsəniz, iş profili və datası silinəcək."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Növbəti cəhddə yanlış PIN daxil etsəniz, iş profili və datası silinəcək."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Növbəti cəhddə yanlış parol daxil etsəniz, iş profili və datası silinəcək."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Həddindən artıq yanlış cəhd. Bu cihazın datası silinəcək."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Həddindən artıq yanlış cəhd. Bu istifadəçi silinəcək."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Həddindən artıq yanlış cəhd. Bu iş profili və oradakı data silinəcək."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Ötürün"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Barmaq izi sensoruna klikləyin"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Barmaq izi ikonası"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Tanımaq olmur. Barmaq izini işlədin."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Asta şarj edilir • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> sonra dolacaq"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Şarj Doku • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> sonra dolacaq"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
- <string name="user_add_user" msgid="4336657383006913022">"İstifadəçi əlavə edin"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Yeni istifadəçi"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Qonaq silinsin?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu sessiyada bütün tətbiqlər və data silinəcək."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Yığışdır"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Xoş gəlmisiniz!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Sessiya davam etsin?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Yenidən başlayın"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Bəli, davam edin"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Yeni istifadəçi əlavə edilsin?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Yeni istifadəçi əlavə etdiyiniz zaman həmin şəxs öz yerini quraşdırmalıdır. \n\n İstənilən istifadəçi bütün digər istifadəçilərdən olan tətbiqləri güncəlləşdirə bilər."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"İstifadəçi limitinə çatmısınız"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Maksimum <xliff:g id="COUNT">%d</xliff:g> istifadəçi əlavə edə bilərsiniz.</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Digərlərini görmək üçün sürüşdürün"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Tövsiyələr yüklənir"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Bu media sessiyası gizlədilsin?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün bu media nizamlayıcısı gizlədilsin?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Cari media sessiyası gizlədilə bilməz."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"İmtina edin"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Gizlədin"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Davam edin"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> tərəfindən <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> tətbiqindən oxudulur"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Burada oxutmaq üçün <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaxınlaşın"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oxudulur"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Bu telefonda oxudulur"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Xəta oldu"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Xəta oldu. Yenə cəhd edin."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Aktiv deyil, tətbiqi yoxlayın"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Tapılmadı"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Nəzarət əlçatan deyil"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index cd6b9cc..befc982 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ako unesete netačan šablon pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ako unesete netačan PIN pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ako unesete netačnu lozinku pri sledećem pokušaju, izbrisaćemo poslovni profil i njegove podatke."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Previše netačnih pokušaja. Izbrisaćemo podatke sa ovog uređaja."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Previše netačnih pokušaja. Izbrisaćemo ovog korisnika."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Previše netačnih pokušaja. Izbrisaćemo ovaj poslovni profil i njegove podatke."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Odbaci"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dodirnite senzor za otisak prsta"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona otiska prsta"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Lice nije prepoznato. Koristite otisak prsta."</string>
@@ -325,17 +321,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Sporo se puni • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Bazna stanica za punjenje • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Dodaj korisnika"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite li da uklonite gosta?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli nazad, goste!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li da nastavite sesiju?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni iz početka"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Dodajete novog korisnika?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Kada dodate novog korisnika, ta osoba treba da podesi svoj prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Dostignut maksimalni broj korisnika"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Možete da dodate najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
@@ -790,9 +781,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da biste videli još"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavaju se preporuke"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Želite li da sakrijete ovu sesiju medija?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Aktuelna sesija medija ne može da bude sakrivena."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Odbaci"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Podešavanja"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se pušta iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -810,7 +802,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da biste na njemu puštali"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Pušta se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Pušta se na ovom telefonu"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Došlo je do greške"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo je do greške. Probajte ponovo."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 0380a76..bbbbdee 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Калі вы ўведзяце няправільны ўзор разблакіроўкі яшчэ раз, ваш працоўны профіль і звязаныя з ім даныя будуць выдалены."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Калі вы ўведзяце няправільны PIN-код яшчэ раз, ваш працоўны профіль і звязаныя з ім даныя будуць выдалены."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Калі вы ўведзяце няправільны пароль яшчэ раз, ваш працоўны профіль і звязаныя з ім даныя будуць выдалены."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Занадта шмат няўдалых спроб. Даныя будуць выдалены з гэтай прылады."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Занадта шмат няўдалых спроб. Гэты карыстальнік будзе выдалены."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Занадта шмат няўдалых спроб. Гэты працоўны профіль і звязаныя з ім даныя будуць выдалены."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Адхіліць"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Дакраніцеся да сканера адбіткаў пальцаў"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Значок адбіткаў пальцаў"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Твар не распазнаны. Скарыстайце адбітак пальца."</string>
@@ -327,17 +323,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ідзе павольная зарадка • Поўны зарад праз <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ідзе зарадка праз док-станцыю • Поўнасцю зарадзіцца праз <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Перайсці да іншага карыстальніка"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Дадаць карыстальніка"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Новы карыстальнік"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Выдаліць госця?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Выдаліць"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"З вяртаннем, госць!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Хочаце працягнуць сеанс?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Пачаць зноў"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Так, працягнуць"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Дадаць новага карыстальніка?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Пасля стварэння профілю яго трэба наладзіць.\n\nЛюбы карыстальнік прылады можа абнаўляць праграмы ўсіх іншых карыстальнікаў."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Дасягнуты ліміт карыстальнікаў"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Можна дадаць <xliff:g id="COUNT">%d</xliff:g> карыстальніка.</item>
@@ -465,8 +456,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Разблакіраваць для выкарыстання"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Узнікла праблема з загрузкай вашых карт. Паўтарыце спробу пазней"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Налады экрана блакіроўкі"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Сканіраванне QR-кода"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Працоўны профіль"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Рэжым палёту"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Вы не пачуеце наступны будзільнік <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -797,9 +787,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Правядзіце пальцам, каб убачыць больш інфармацыі"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Загружаюцца рэкамендацыі"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Мультымедыя"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Схаваць гэты сеанс мультымедыя?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Не ўдалося схаваць бягучы сеанс мультымедыя."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Адхіліць"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Схаваць"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Узнавіць"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Налады"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"У праграме \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\" прайграецца кампазіцыя \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", выканаўца – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string>
@@ -817,7 +808,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Падыдзіце бліжэй да прылады \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", каб прайграць на гэтай"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Прайграецца на прыладзе \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\""</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Прайграецца на гэтым тэлефоне"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Нешта пайшло не так"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Нешта пайшло не так. Паўтарыце спробу."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактыўна, праверце праграму"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Не знойдзена"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Кіраванне недаступнае"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index f56e57d..73a2391 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ако въведете неправилна фигура при следващия опит, служебният ви потребителски профил и данните в него ще бъдат изтрити."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ако въведете неправилен ПИН код при следващия опит, служебният ви потребителски профил и данните в него ще бъдат изтрити."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ако въведете неправилна парола при следващия опит, служебният ви потребителски профил и данните в него ще бъдат изтрити."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Твърде много неправилни опити. Данните от това устройство ще бъдат изтрити."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Твърде много неправилни опити. Този потребител ще бъде изтрит."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Твърде много неправилни опити. Този служебен потребителски профил и данните в него ще бъдат изтрити."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Отхвърляне"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Докоснете сензора за отпечатъци"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Икона за отпечатък"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Лицето не е разпознато. Използвайте отпечатък."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Зарежда се бавно • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до пълно зареждане"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Докинг станция за зареждане • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до пълно зареждане"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Превключване между потребителите"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Добавяне на потребител"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Нов потребител"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Да се премахне ли гостът?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Всички приложения и данни в тази сесия ще бъдат изтрити."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Премахване"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Добре дошли отново в сесията като гост!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Искате ли да продължите сесията си?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Започване отначало"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продължавам"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Да се добави ли нов потребител?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Когато добавите нов потребител, той трябва да настрои работното си пространство.\n\nВсеки потребител може да актуализира приложенията за всички останали потребители."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнахте огранич. за потребители"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Можете да добавите до <xliff:g id="COUNT">%d</xliff:g> потребители.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Отключване с цел използване"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"При извличането на картите ви възникна проблем. Моля, опитайте отново по-късно"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Настройки за заключения екран"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Сканиране на QR код"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Потребителски профил в Work"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Самолетен режим"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Няма да чуете следващия си будилник в <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Прекарайте пръст, за да видите повече"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Препоръките се зареждат"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Мултимедия"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Да се скрие ли тази сесия за мултимедия?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Текущата сесия за мултимедия не бе скрита."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Отхвърляне"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скриване"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Възобновяване"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> на <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се възпроизвежда от <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближете се до <xliff:g id="DEVICENAME">%1$s</xliff:g> за възпроизвеждане на това устройство"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Възпроизвежда се на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Възпроизвежда се на този телефон"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Нещо се обърка"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Нещо се обърка. Опитайте отново."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, проверете прилож."</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Не е намерено"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е налице"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 2730b4c..a967a5c 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"আপনি পরের বারও ভুল প্যাটার্ন দিলে আপনার অফিস প্রোফাইল এবং তার ডেটা মুছে দেওয়া হবে।"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"আপনি পরের বারও ভুল পিন দিলে আপনার অফিস প্রোফাইল এবং তার ডেটা মুছে দেওয়া হবে।"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"আপনি পরের বারও ভুল পাসওয়ার্ড দিলে আপনার অফিস প্রোফাইল এবং তার ডেটা মুছে দেওয়া হবে।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"বহুবার ভুল লেখা হয়েছে। এই ডিভাইসের ডেটা মুছে যাবে।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"বহুবার ভুল লেখা হয়েছে। এই ব্যবহারকারীর ডেটা মুছে যাবে।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"বহুবার ভুল লেখা হয়েছে। এই অফিসের প্রোফাইল ও সংশ্লিষ্ট ডেটা মুছে যাবে।"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"বাতিল করুন"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"আঙ্গুলের ছাপের সেন্সর স্পর্শ করুন"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"আঙ্গুলের ছাপের আইকন"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"মুখ শনাক্ত করতে পারছি না। পরিবর্তে আঙ্গুলের ছাপ ব্যবহার করুন।"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ধীরে চার্জ হচ্ছে • পুরো চার্জ হতে <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> লাগবে"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • চার্জিং ডক • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-এর মধ্যে সম্পূর্ণ হয়ে যাবে"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যবহারকারী পাল্টে দিন"</string>
- <string name="user_add_user" msgid="4336657383006913022">"ব্যবহারকারী জুড়ুন"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"নতুন ব্যবহারকারী"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"অতিথি সরাবেন?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ ও ডেটা মুছে ফেলা হবে।"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"সরান"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"অতিথি, আপনি ফিরে আসায় আপনাকে স্বাগত!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"আপনি কি আপনার সেশনটি চালিয়ে যেতে চান?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আবার শুরু করুন"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"হ্যাঁ, চালিয়ে যান"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"নতুন ব্যবহারকারীকে যোগ করবেন?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"আপনি একজন নতুন ব্যবহারকারী যোগ করলে তাকে তার জায়গা সেট-আপ করে নিতে হবে৷\n\nযেকোনও ব্যবহারকারী অন্য সব ব্যবহারকারীর জন্য অ্যাপ আপডেট করতে পারবেন৷"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"আর কোনও প্রোফাইল যোগ করা যাবে না"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">আপনি <xliff:g id="COUNT">%d</xliff:g> জন পর্যন্ত ব্যবহারকারীর প্রোফাইল যোগ করতে পারেন।</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ব্যবহার করতে আনলক করুন"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"আপনার কার্ড সংক্রান্ত তথ্য পেতে সমস্যা হয়েছে, পরে আবার চেষ্টা করুন"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"লক স্ক্রিন সেটিংস"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR কোড স্ক্যান করুন"</string>
<string name="status_bar_work" msgid="5238641949837091056">"কাজের প্রোফাইল"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"বিমান মোড"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"আপনি আপনার পরবর্তী <xliff:g id="WHEN">%1$s</xliff:g> অ্যালার্ম শুনতে পাবেন না"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"আরও দেখতে সোয়াইপ করুন"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"সাজেশন লোড করা হচ্ছে"</string>
<string name="controls_media_title" msgid="1746947284862928133">"মিডিয়া"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"এই মিডিয়া সেশন লুকিয়ে রাখতে চান?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"বর্তমান মিডিয়া সেশন লুকিয়ে রাখা যাবে না।"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"খারিজ করুন"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"লুকান"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"আবার চালু করুন"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"সেটিংস"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>-এর <xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%3$s</xliff:g> অ্যাপে চলছে"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"এখান থেকে চালাতে <xliff:g id="DEVICENAME">%1$s</xliff:g>-এর কাছে নিয়ে যান"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>-এ ভিডিও চালানো হচ্ছে"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"এই ফোনে চালানো হচ্ছে"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"কোনও সমস্যা হয়েছে"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"কোনও সমস্যা হয়েছে। আবার চেষ্টা করুন।"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"বন্ধ আছে, অ্যাপ চেক করুন"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"খুঁজে পাওয়া যায়নি"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"কন্ট্রোল উপলভ্য নেই"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 00973ee..c84ffc3 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ako u sljedećem pokušaju unesete neispravan uzorak, vaš radni profil i njegovi podaci će se izbrisati."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ako u sljedećem pokušaju unesete neispravan PIN, vaš radni profil i njegovi podaci će se izbrisati."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ako u sljedećem pokušaju unesete neispravnu lozinku, vaš radni profil i njegovi podaci će se izbrisati."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Previše je neispravnih pokušaja. Podaci ovog uređaja će se izbrisati."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Previše je neispravnih pokušaja. Ovaj korisnik će se izbrisati."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Previše je neispravnih pokušaja. Ovaj radni profil i njegovi podaci će se izbrisati."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Odbaci"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dodirnite senzor za otisak prsta"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona za otisak prsta"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Nije moguće prepoznati lice. Koristite otisak prsta."</string>
@@ -325,17 +321,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Sporo punjenje • Potpuna napunjenost za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Priključna stanica za punjenje • Potpuna napunjenost za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zamijeni korisnika"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Dodaj korisnika"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ukloniti gosta?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Zdravo! Lijepo je opet vidjeti goste."</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Dodati novog korisnika?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Kada dodate novog korisnika, ta osoba treba postaviti svoj prostor.\n\nSvaki korisnik može ažurirati aplikacije za sve ostale korisnike."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Dostignut limit za broj korisnika"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
@@ -462,7 +453,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Otključajte da koristite"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Došlo je do problema prilikom preuzimanja vaših kartica. Pokušajte ponovo kasnije"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Postavke zaključavanja ekrana"</string>
- <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skeniraj QR kôd"</string>
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skenirajte QR kôd"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil za posao"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Način rada u avionu"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nećete čuti sljedeći alarm u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -790,9 +781,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da vidite više"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavanje preporuka"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Sakriti ovu sesiju medija?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Želite li sakriti kontroler medija za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Trenutna sesija medija se ne može sakriti."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Odbaci"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Pjesma <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se reproducira pomoću aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -810,7 +801,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da na njemu reproducirate"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducira se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Reproducira se na ovom telefonu"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Nešto nije uredu"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije uredu. Pokušajte ponovo."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, vidite aplikaciju"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 975f4e0..c8c8816 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si tornes a introduir un patró incorrecte, se suprimirà el perfil de treball i les dades que contingui."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si tornes a introduir un PIN incorrecte, se suprimirà el perfil de treball i les dades que contingui."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si tornes a introduir una contrasenya incorrecta, se suprimirà el perfil de treball i les dades que contingui."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Has superat el nombre d\'intents incorrectes permesos. Se suprimiran les dades del dispositiu."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Has superat el nombre d\'intents incorrectes permesos. Se suprimirà l\'usuari."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Has superat el nombre d\'intents incorrectes permesos. Se suprimirà el perfil de treball i les dades que contingui."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Ignora"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toca el sensor d\'empremtes digitals"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Icona d\'empremta digital"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"No podem detectar la cara. Usa l\'empremta digital."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregant lentament • Es completarà d\'aquí a <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Base de càrrega • Es completarà d\'aquí a <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Canvia d\'usuari"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Afegeix un usuari"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Usuari nou"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vols suprimir el convidat?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Suprimeix"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvingut de nou, convidat."</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vols continuar amb la sessió?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Torna a començar"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continua"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Vols afegir un usuari nou?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar-se l\'espai.\n\nQualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"S\'ha assolit el límit d\'usuaris"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Pots afegir fins a <xliff:g id="COUNT">%d</xliff:g> usuaris.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloqueja per utilitzar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Hi ha hagut un problema en obtenir les teves targetes; torna-ho a provar més tard"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Configuració de la pantalla de bloqueig"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Escaneja un codi QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de treball"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode d\'avió"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g> no sentiràs la pròxima alarma"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Llisca per veure\'n més"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregant les recomanacions"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimèdia"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Vols amagar aquesta sessió multimèdia?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"La sessió multimèdia actual no es pot amagar."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignora"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Amaga"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprèn"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuració"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) s\'està reproduint des de l\'aplicació <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acosta\'t a <xliff:g id="DEVICENAME">%1$s</xliff:g> per reproduir el contingut aquí"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"S\'està reproduint a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"S\'està reproduint en aquest telèfon"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"S\'ha produït un error"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"S\'ha produït un error. Torna-ho a provar."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactiu; comprova l\'aplicació"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"No s\'ha trobat"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"El control no està disponible"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index ee9a04f..db89392 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Pokud při příštím pokusu zadáte nesprávné gesto, váš pracovní profil a přidružená data budou smazána."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Pokud při příštím pokusu zadáte nesprávný PIN, váš pracovní profil a přidružená data budou smazána."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Pokud při příštím pokusu zadáte nesprávné heslo, váš pracovní profil a přidružená data budou smazána."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Příliš mnoho neplatných pokusů. Data v tomto zařízení budou smazána."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Příliš mnoho neplatných pokusů. Tento uživatel bude smazán."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Příliš mnoho neplatných pokusů. Tento pracovní profil a přidružená data budou smazána."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Zavřít"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dotkněte se snímače otisků prstů"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona otisku prstu"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Obličej se nepodařilo rozpoznat. Použijte místo něj otisk prstu."</string>
@@ -327,17 +323,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Pomalé nabíjení • Plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Nabíjecí dok • Plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Přepnout uživatele"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Přidat uživatele"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Nový uživatel"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Odstranit hosta?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstranit"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Vítejte zpět v relaci hosta!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relaci pokračovat?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začít znovu"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ano, pokračovat"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Přidat nového uživatele?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Když přidáte nového uživatele, musí si nastavit vlastní prostor.\n\nJakýkoli uživatel může aktualizovat aplikace všech ostatních uživatelů."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Bylo dosaženo limitu uživatelů"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="few">Lze přidat až <xliff:g id="COUNT">%d</xliff:g> uživatele.</item>
@@ -465,8 +456,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Odemknout a použít"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Při načítání karet došlo k problému, zkuste to později"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Nastavení obrazovky uzamčení"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Naskenovat QR kód"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Pracovní profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Režim Letadlo"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Svůj další budík <xliff:g id="WHEN">%1$s</xliff:g> neuslyšíte"</string>
@@ -797,9 +787,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Přejetím prstem zobrazíte další položky"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Načítání doporučení"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Média"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Skrýt tuto mediální relaci?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Aktuální mediální relaci nelze skrýt."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Zavřít"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrýt"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Pokračovat"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavení"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Skladba <xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> hrajte z aplikace <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -817,7 +808,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Pokud zde chcete přehrávat média, přibližte se k zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Přehrávání v zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Přehrávání v tomto telefonu"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Něco se pokazilo"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo k chybě. Zkuste to znovu."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivní, zkontrolujte aplikaci"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nenalezeno"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Ovládání není k dispozici"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 43027b8..c82e3bd 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Hvis du angiver et forkert mønster i næste forsøg, slettes din arbejdsprofil og de tilhørende data."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Hvis du angiver en forkert pinkode i næste forsøg, slettes din arbejdsprofil og de tilhørende data."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Hvis du angiver en forkert adgangskode i næste forsøg, slettes din arbejdsprofil og de tilhørende data."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"For mange forkerte forsøg. Dataene på denne enhed slettes."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"For mange forkerte forsøg. Denne bruger slettes."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"For mange forkerte forsøg. Denne arbejdsprofil og de tilhørende data slettes."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Afvis"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Sæt fingeren på fingeraftrykslæseren"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikon for fingeraftryk"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ansigtet kan ikke genkendes. Brug fingeraftryk i stedet."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Oplader langsomt • Fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Oplader i dockingstation • Fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skift bruger"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Tilføj bruger"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Ny bruger"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vil du fjerne gæsten?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps og data i denne session slettes."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkommen tilbage, gæst!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsætte din session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start forfra"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsæt"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Vil du tilføje en ny bruger?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Når du tilføjer en ny bruger, skal personen konfigurere sit område.\n\nAlle brugere kan opdatere apps for alle de andre brugere."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Grænsen for antal brugere er nået"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Du kan tilføje op til <xliff:g id="COUNT">%d</xliff:g> bruger.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lås op for at bruge"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Dine kort kunne ikke hentes. Prøv igen senere."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Lås skærmindstillinger"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Scan QR-kode"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Arbejdsprofil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flytilstand"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Du vil ikke kunne høre din næste alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Stryg for at se mere"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Indlæser anbefalinger"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medie"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Vil du skjule denne mediesession?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Vil du skjule denne mediefunktion for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Den aktuelle mediesession kan ikke skjules."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Luk"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skjul"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Genoptag"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Indstillinger"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> af <xliff:g id="ARTIST_NAME">%2$s</xliff:g> afspilles via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ryk tættere på <xliff:g id="DEVICENAME">%1$s</xliff:g> for at afspille her"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Afspilles på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Afspilles på denne telefon"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Noget gik galt"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Noget gik galt. Prøv igen."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Tjek appen"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ikke fundet"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Styringselement ikke tilgængeligt"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 60bcecb..7614904 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Wenn du beim nächsten Versuch ein falsches Muster eingibst, werden dein Arbeitsprofil und die zugehörigen Daten gelöscht."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Wenn du beim nächsten Versuch eine falsche PIN eingibst, werden dein Arbeitsprofil und die zugehörigen Daten gelöscht."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Wenn du beim nächsten Versuch ein falsches Passwort eingibst, werden dein Arbeitsprofil und die zugehörigen Daten gelöscht."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Zu viele Fehlversuche. Die Daten auf diesem Gerät werden gelöscht."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Zu viele Fehlversuche. Dieser Nutzer wird vom Gerät entfernt."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Zu viele Fehlversuche. Dieses Arbeitsprofil und die zugehörigen Daten werden gelöscht."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Schließen"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Berühre den Fingerabdrucksensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Fingerabdruck-Symbol"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Gesicht wurde nicht erkannt. Verwende stattdessen den Fingerabdruck."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Wird langsam geladen • Voll in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ladestation • Voll in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Nutzer wechseln"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Nutzer hinzufügen"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Neuer Nutzer"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gast entfernen?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Entfernen"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Willkommen zurück im Gastmodus"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Möchtest du deine Sitzung fortsetzen?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Neu starten"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, weiter"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Neuen Nutzer hinzufügen?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Wenn du einen neuen Nutzer hinzufügst, muss dieser seinen Bereich einrichten.\n\nJeder Nutzer kann Apps für alle anderen Nutzer aktualisieren."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Nutzerlimit erreicht"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Du kannst bis zu <xliff:g id="COUNT">%d</xliff:g> Nutzer hinzufügen.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Zum Verwenden entsperren"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Beim Abrufen deiner Karten ist ein Fehler aufgetreten – bitte versuch es später noch einmal"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Einstellungen für den Sperrbildschirm"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR-Code scannen"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Arbeitsprofil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flugmodus"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Lautloser Weckruf <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Wischen, um weitere zu sehen"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Empfehlungen werden geladen"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medien"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Diese Mediensitzung ausblenden?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Die Mediensitzung kann nicht ausgeblendet werden."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ausblenden"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ausblenden"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Fortsetzen"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Einstellungen"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> von <xliff:g id="ARTIST_NAME">%2$s</xliff:g> wird gerade über <xliff:g id="APP_LABEL">%3$s</xliff:g> wiedergegeben"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Platziere für die Wiedergabe dein Gerät näher an „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Wird auf „<xliff:g id="DEVICENAME">%1$s</xliff:g>“ abgespielt"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Wird auf diesem Smartphone abgespielt"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Ein Fehler ist aufgetreten"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Es gab ein Problem. Versuch es noch einmal."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv – sieh in der App nach"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nicht gefunden"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Steuerelement nicht verfügbar"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 17a54c2..bbc2ee3 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Εάν εισαγάγετε εσφαλμένο μοτίβο στην επόμενη προσπάθεια, το προφίλ εργασίας σας και τα δεδομένα του θα διαγραφούν."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Εάν εισαγάγετε εσφαλμένο PIN στην επόμενη προσπάθεια, το προφίλ εργασίας σας και τα δεδομένα του θα διαγραφούν."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Εάν εισαγάγετε εσφαλμένο κωδικό πρόσβασης στην επόμενη προσπάθεια, το προφίλ εργασίας σας και τα δεδομένα του θα διαγραφούν."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Πάρα πολλές ανεπιτυχείς προσπάθειες. Τα δεδομένα αυτής της συσκευής θα διαγραφούν."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Πάρα πολλές ανεπιτυχείς προσπάθειες. Αυτός ο χρήστης θα διαγραφεί."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Πάρα πολλές ανεπιτυχείς προσπάθειες. Αυτό το προφίλ εργασίας και τα δεδομένα του θα διαγραφούν."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Παράβλεψη"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Αγγίξτε τον αισθητήρα δακτυλικού αποτυπώματος"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Εικονίδιο δακτυλικών αποτυπωμάτων"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Το πρόσωπο δεν αναγνωρίζεται. Χρησιμ. δακτ. αποτ."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Αργή φόρτιση • Πλήρης φόρτιση σε <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Βάση φόρτισης • Πλήρης φόρτιση σε <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Εναλλαγή χρήστη"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Προσθήκη χρήστη"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Νέος χρήστης"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Κατάργηση επισκέπτη;"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Όλες οι εφαρμογές και τα δεδομένα αυτής της περιόδου σύνδεσης θα διαγραφούν."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Κατάργηση"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Kαλώς ορίσατε ξανά!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Θέλετε να συνεχίσετε την περίοδο σύνδεσής σας;"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Έναρξη από την αρχή"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ναι, συνέχεια"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Προσθήκη νέου χρήστη;"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει τον χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Συμπληρώθηκε το όριο χρηστών"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Μπορείτε να προσθέσετε έως <xliff:g id="COUNT">%d</xliff:g> χρήστες.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ξεκλείδωμα για χρήση"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Παρουσιάστηκε πρόβλημα με τη λήψη των καρτών σας. Δοκιμάστε ξανά αργότερα"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Ρυθμίσεις κλειδώματος οθόνης"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Σάρωση κωδικού QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Προφίλ εργασίας"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Λειτουργία πτήσης"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Δεν θα ακούσετε το επόμενο ξυπνητήρι σας <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Σύρετε για να δείτε περισσότερα."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Φόρτωση προτάσεων"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Μέσα"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Απόκρυψη αυτής της περιόδου λειτουργίας μέσου;"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Αδυναμία απόκρ. τρέχουσας περιόδ. λειτουργ. μέσου."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Παράβλεψη"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Απόκρυψη"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Συνέχιση"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ρυθμίσεις"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Γίνεται αναπαραγωγή του <xliff:g id="SONG_NAME">%1$s</xliff:g> από <xliff:g id="ARTIST_NAME">%2$s</xliff:g> στην εφαρμογή <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Μετακινηθείτε πιο κοντά στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g> για αναπαραγωγή εδώ"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Αναπαραγωγή στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Αναπαραγωγή σε αυτό το τηλέφωνο"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Παρουσιάστηκε κάποιο πρόβλημα"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Παρουσιάστηκε κάποιο πρόβλημα. Δοκιμάστε ξανά."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Ανενεργό, έλεγχος εφαρμογής"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Δεν βρέθηκε."</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Μη διαθέσιμο στοιχείο ελέγχου"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 5544a95..64e5501 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"If you enter an incorrect password on the next attempt, your work profile and its data will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Too many incorrect attempts. This device’s data will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Too many incorrect attempts. This user will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Too many incorrect attempts. This work profile and its data will be deleted."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Dismiss"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touch the fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Fingerprint icon"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Can’t recognise face. Use fingerprint instead."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging slowly • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging dock • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Add user"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Hide this media session?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dismiss"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Playing on this phone"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Something went wrong"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 9a204eb..259a16f 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"If you enter an incorrect password on the next attempt, your work profile and its data will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Too many incorrect attempts. This device’s data will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Too many incorrect attempts. This user will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Too many incorrect attempts. This work profile and its data will be deleted."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Dismiss"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touch the fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Fingerprint icon"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Can’t recognise face. Use fingerprint instead."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging slowly • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging dock • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Add user"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Hide this media session?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dismiss"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Playing on this phone"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Something went wrong"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
@@ -887,7 +878,7 @@
<string name="see_all_networks" msgid="3773666844913168122">"See all"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"To switch networks, disconnect Ethernet"</string>
<string name="wifi_scan_notify_message" msgid="3753839537448621794">"To improve device experience, apps and services can still scan for Wi‑Fi networks at any time, even when Wi‑Fi is off. You can change this in Wi‑Fi scanning settings. "<annotation id="link">"Change"</annotation></string>
- <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Turn off aeroplane mode"</string>
+ <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Turn off Airplane mode"</string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> wants to add the following tile to Quick Settings"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 5544a95..64e5501 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"If you enter an incorrect password on the next attempt, your work profile and its data will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Too many incorrect attempts. This device’s data will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Too many incorrect attempts. This user will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Too many incorrect attempts. This work profile and its data will be deleted."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Dismiss"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touch the fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Fingerprint icon"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Can’t recognise face. Use fingerprint instead."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging slowly • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging dock • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Add user"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Hide this media session?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dismiss"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Playing on this phone"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Something went wrong"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 5544a95..64e5501 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"If you enter an incorrect password on the next attempt, your work profile and its data will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Too many incorrect attempts. This device’s data will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Too many incorrect attempts. This user will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Too many incorrect attempts. This work profile and its data will be deleted."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Dismiss"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touch the fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Fingerprint icon"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Can’t recognise face. Use fingerprint instead."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging slowly • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging dock • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Add user"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Hide this media session?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dismiss"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Playing on this phone"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Something went wrong"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 052f175..aef122a 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"If you enter an incorrect pattern on the next attempt, your work profile and its data will be deleted."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"If you enter an incorrect PIN on the next attempt, your work profile and its data will be deleted."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"If you enter an incorrect password on the next attempt, your work profile and its data will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Too many incorrect attempts. This device’s data will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Too many incorrect attempts. This user will be deleted."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Too many incorrect attempts. This work profile and its data will be deleted."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Dismiss"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touch the fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Fingerprint icon"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Can’t recognize face. Use fingerprint instead."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging slowly • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging Dock • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Add user"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start over"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe to see more"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Loading recommendations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Hide this media session?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dismiss"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Playing on this phone"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Something went wrong"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 57996ee..1976ab4 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si ingresas un patrón incorrecto en el próximo intento, se borrarán tu perfil de trabajo y sus datos."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si ingresas un PIN incorrecto en el próximo intento, se borrarán tu perfil de trabajo y sus datos."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si ingresas una contraseña incorrecta en el próximo intento, se borrarán tu perfil de trabajo y sus datos."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Hubo demasiados intentos incorrectos. Se borrarán los datos del dispositivo."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Hubo demasiados intentos incorrectos. Se borrará este usuario."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Hubo demasiados intentos incorrectos. Se borrarán este perfil de trabajo y sus datos."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Descartar"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toca el sensor de huellas dactilares"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ícono de huella dactilar"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"No se reconoce el rostro. Usa la huella dactilar."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando lento • Se completará en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Conectado y cargando • Carga completa en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Agregar usuario"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Usuario nuevo"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"¿Quitar invitado?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"¡Hola de nuevo, invitado!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres retomar la sesión?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continuar"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"¿Agregar usuario nuevo?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Cuando agregas un nuevo usuario, esa persona debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Alcanzaste el límite de usuarios"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Puedes agregar hasta <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Ocurrió un problema al obtener las tarjetas; vuelve a intentarlo más tarde"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Configuración de pantalla de bloqueo"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Escanear código QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo de avión"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"No oirás la próxima alarma a la(s) <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Desliza el dedo para ver más elementos"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendaciones"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Contenido multimedia"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"¿Quieres ocultar esta sesión multimedia?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"¿Quieres ocultar este control multimedia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"No se puede ocultar la sesión multimedia actual."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Descartar"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Se está reproduciendo <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para reproducir aquí"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproduciendo en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Reproduciendo en este teléfono"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Ocurrió un error"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Se produjo un error. Vuelve a intentarlo."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Verifica la app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"No se encontró"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"El control no está disponible"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index f4a8cf7..a45d85e 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si vuelves a introducir un patrón incorrecto, tu perfil de trabajo y sus datos se eliminarán."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si vuelves a introducir un PIN incorrecto, tu perfil de trabajo y sus datos se eliminarán."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si vuelves a introducir una contraseña incorrecta, tu perfil de trabajo y sus datos se eliminarán."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Se han producido demasiados intentos fallidos. Los datos de este dispositivo se eliminarán."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Se han producido demasiados intentos fallidos. Este usuario se eliminará."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Se han producido demasiados intentos fallidos. Este perfil de trabajo y sus datos se eliminarán."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Cerrar"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toca el sensor de huellas digitales"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Icono de huella digital"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"No se reconoce la cara. Usa la huella digital."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carga lenta • En <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> terminará de cargarse"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Base de carga • En <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> terminará de cargar"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar de usuario"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Añadir usuario"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Nuevo usuario"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"¿Quitar invitado?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Hola de nuevo, invitado"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres continuar con la sesión?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continuar"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"¿Añadir nuevo usuario?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Al añadir un nuevo usuario, este debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de usuarios."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Has alcanzado el límite de usuarios"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Puedes añadir hasta <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Se ha producido un problema al obtener tus tarjetas. Inténtalo de nuevo más tarde."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Ajustes de pantalla de bloqueo"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Escanear código QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo avión"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"No oirás la próxima alarma (<xliff:g id="WHEN">%1$s</xliff:g>)"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Desliza el dedo para ver más"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendaciones"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimedia"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"¿Ocultar esta sesión multimedia?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"¿Ocultar este control multimedia a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"La sesión multimedia no se puede ocultar."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Cerrar"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ajustes"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Se está reproduciendo <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para jugar aquí"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproduciendo en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Reproduciendo en este dispositivo"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Se ha producido un error"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Se ha producido un error. Inténtalo de nuevo."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo, comprobar aplicación"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"No se ha encontrado"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Control no disponible"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index b6d266c..0b39a2c 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Kui sisestate järgmisel katsel vale mustri, kustutatakse teie tööprofiil ja selle andmed."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Kui sisestate järgmisel katsel vale PIN-koodi, kustutatakse teie tööprofiil ja selle andmed."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Kui sisestate järgmisel katsel vale parooli, kustutatakse teie tööprofiil ja selle andmed."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Liiga palju valesid katseid. Selle seadme andmed kustutatakse."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Liiga palju valesid katseid. See kasutaja kustutatakse."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Liiga palju valesid katseid. See tööprofiil ja selle andmed kustutatakse."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Sulge"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Puudutage sõrmejäljeandurit"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Sõrmejälje ikoon"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Nägu ei õnnestu tuvastada. Kasutage sõrmejälge."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Aeglane laadimine • Täis <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> pärast"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Laadimisdokk • Täis <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> pärast"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kasutaja vahetamine"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Lisa kasutaja"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Uus kasutaja"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Kas eemaldada külaline?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Seansi kõik rakendused ja andmed kustutatakse."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eemalda"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Tere tulemast tagasi, külaline!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Kas soovite seansiga jätkata?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Alusta uuesti"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Jah, jätka"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Kas lisada uus kasutaja?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Kui lisate uue kasutaja, siis peab ta seadistama oma ruumi.\n\nIga kasutaja saab värskendada rakendusi kõigi kasutajate jaoks."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Kasutajate limiit on täis"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Võite lisada kuni <xliff:g id="COUNT">%d</xliff:g> kasutajat.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Avage kasutamiseks"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Teie kaartide hankimisel ilmnes probleem, proovige hiljem uuesti"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Lukustuskuva seaded"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skannige QR-kood"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Tööprofiil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lennukirežiim"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Te ei kuule järgmist äratust kell <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pühkige sõrmega, et näha rohkem"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Soovituste laadimine"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Meedia"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Kas peita see meediaseanss?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Praegust meediaseanssi ei saa peita."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Loobu"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Peida"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Jätka"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Seaded"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> esitajalt <xliff:g id="ARTIST_NAME">%2$s</xliff:g> esitatakse rakenduses <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Siin esitamiseks liigutage seadmele <xliff:g id="DEVICENAME">%1$s</xliff:g> lähemale"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Esitatakse seadmes <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Esitatakse selles telefonis"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Midagi läks valesti"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Midagi läks valesti. Proovige uuesti."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Passiivne, vaadake rakendust"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ei leitud"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Juhtelement pole saadaval"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 768c202..95bd08f 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Hurrengo saiakeran eredua oker marrazten baduzu, laneko profila eta bertako datuak ezabatuko dira."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Hurrengo saiakeran PINa oker idazten baduzu, laneko profila eta bertako datuak ezabatuko dira."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Hurrengo saiakeran pasahitza oker idazten baduzu, laneko profila eta bertako datuak ezabatuko dira."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Saiakera oker gehiegi egin dituzu. Gailuko datuak ezabatu egingo dira."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Saiakera oker gehiegi egin dituzu. Erabiltzailea ezabatu egingo da."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Saiakera oker gehiegi egin dituzu. Laneko profila eta bertako datuak ezabatu egingo dira."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Baztertu"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Sakatu hatz-marken sentsorea"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Hatz-markaren ikonoa"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ez da hauteman aurpegia. Erabili hatz-marka."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mantso kargatzen • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> guztiz kargatu arte"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Oinarrian kargatzen • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> guztiz kargatu arte"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Aldatu erabiltzailea"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Gehitu erabiltzaile bat"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Erabiltzaile berria"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gonbidatua kendu nahi duzu?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Saioko aplikazio eta datu guztiak ezabatuko dira."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kendu"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Ongi etorri berriro, gonbidatu hori!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Saioarekin jarraitu nahi duzu?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Hasi berriro"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Bai, jarraitu"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Beste erabiltzaile bat gehitu?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Erabiltzaile bat gehitzen duzunean, erabiltzaile horrek bere eremua konfiguratu beharko du.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Erabiltzaile-mugara iritsi zara"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Gehienez, <xliff:g id="COUNT">%d</xliff:g> erabiltzaile gehi ditzakezu.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desblokeatu erabiltzeko"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Arazo bat izan da txartelak eskuratzean. Saiatu berriro geroago."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Pantaila blokeatuaren ezarpenak"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Eskaneatu QR kodea"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Work profila"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Hegaldi modua"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Ez duzu entzungo hurrengo alarma (<xliff:g id="WHEN">%1$s</xliff:g>)"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pasatu hatza aukera gehiago ikusteko"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Gomendioak kargatzen"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimedia-edukia"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Multimedia-saioa ezkutatu nahi duzu?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Ezin da ezkutatu multimedia-saioa."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Baztertu"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ezkutatu"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Berrekin"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ezarpenak"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) ari da erreproduzitzen <xliff:g id="APP_LABEL">%3$s</xliff:g> bidez"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Gerturatu <xliff:g id="DEVICENAME">%1$s</xliff:g> gailura bertan erreproduzitzen ari dena hemen erreproduzitzeko"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> gailuan erreproduzitzen"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Telefono honetan erreproduzitzen"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Arazoren bat izan da"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Arazoren bat izan da. Saiatu berriro."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktibo; egiaztatu aplikazioa"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ez da aurkitu"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Ez dago erabilgarri kontrolatzeko aukera"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 3e76c46..dd6a6cb 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -98,7 +98,7 @@
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"درحال ضبط صفحهنمایش"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"درحال ضبط صفحهنمایش و صدا"</string>
<string name="screenrecord_taps_label" msgid="1595690528298857649">"نمایش قسمتهای لمسشده روی صفحهنمایش"</string>
- <string name="screenrecord_stop_label" msgid="72699670052087989">"توقف"</string>
+ <string name="screenrecord_stop_label" msgid="72699670052087989">"متوقف کردن"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"همرسانی"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"قطعه ضبطشده از صفحهنمایش ذخیره شد"</string>
<string name="screenrecord_save_text" msgid="3008973099800840163">"برای مشاهده ضربه بزنید"</string>
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"اگر در تلاش بعدی الگوی نادرستی وارد کنید، دادههای نمایه کاری شما و دادههای آن حذف خواهد شد."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"اگر در تلاش بعدی پین نادرستی وارد کنید، نمایه کاری شما و دادههای آن حذف خواهند شد."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"اگر در تلاش بعدی گذرواژه نادرستی وارد کنید، نمایه کاری شما و دادههای آن حذف خواهند شد."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"تلاشهای نادرست بسیار زیادی انجام شده است. دادههای این دستگاه حذف خواهد شد."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"تلاشهای اشتباه بسیار زیادی انجام شده است. این کاربر حذف خواهد شد."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"تلاشهای اشتباه بسیار زیادی انجام شده است. این نمایه کاری و دادههای آن حذف خواهند شد."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"رد کردن"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"حسگر اثر انگشت را لمس کنید"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"نماد اثر انگشت"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"چهره شناسایی نشد. درعوض از اثر انگشت استفاده کنید."</string>
@@ -283,7 +279,7 @@
<string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC فعال است"</string>
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"ضبط صفحهنمایش"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"شروع"</string>
- <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"توقف"</string>
+ <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"متوقف کردن"</string>
<string name="quick_settings_onehanded_label" msgid="2416537930246274991">"حالت تک حرکت"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"میکروفون دستگاه لغو انسداد شود؟"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"دوربین دستگاه لغو انسداد شود؟"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • درحال شارژ کردن آهسته • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> تا شارژ کامل"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • پایه شارژ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> تا شارژ کامل"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تغییر کاربر"</string>
- <string name="user_add_user" msgid="4336657383006913022">"افزودن کاربر"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"کاربر جدید"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"مهمان حذف شود؟"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"همه برنامهها و دادههای این جلسه حذف خواهد شد."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"حذف"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"مهمان گرامی، بازگشتتان را خوش آمد میگوییم!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"آیا میخواهید جلسهتان را ادامه دهید؟"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"شروع مجدد"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"بله، ادامه داده شود"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"کاربر جدیدی اضافه میکنید؟"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"وقتی کاربر جدیدی اضافه میکنید آن فرد باید فضای خودش را تنظیم کند.\n\nهر کاربری میتواند برنامهها را برای همه کاربران دیگر بهروزرسانی کند."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"به تعداد مجاز تعداد کاربر رسیدهاید"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">میتوانید حداکثر <xliff:g id="COUNT">%d</xliff:g> کاربر اضافه کنید.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"برای استفاده، قفل را باز کنید"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"هنگام دریافت کارتها مشکلی پیش آمد، لطفاً بعداً دوباره امتحان کنید"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"تنظیمات صفحه قفل"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"اسکن رمزینه پاسخسریع"</string>
<string name="status_bar_work" msgid="5238641949837091056">"نمایه کاری"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"حالت هواپیما"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"در ساعت <xliff:g id="WHEN">%1$s</xliff:g>، دیگر صدای زنگ ساعت را نمیشنوید"</string>
@@ -546,7 +536,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"ورود"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"پسبر"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"پخش/مکث"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"توقف"</string>
+ <string name="keyboard_key_media_stop" msgid="1509943745250377699">"متوقف کردن"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"بعدی"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"قبلی"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"عقب بردن"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"برای دیدن موارد بیشتر، تند بکشید"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"درحال بار کردن توصیهها"</string>
<string name="controls_media_title" msgid="1746947284862928133">"رسانه"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"این جلسه رسانه پنهان شود؟"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"جلسه رسانه کنونی نمیتواند پنهان شود."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"رد کردن"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"پنهان کردن"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ازسرگیری"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"تنظیمات"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> از <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ازطریق <xliff:g id="APP_LABEL">%3$s</xliff:g> پخش میشود"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"برای پخش در اینجا، به <xliff:g id="DEVICENAME">%1$s</xliff:g> نزدیکتر شوید"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"درحال پخش در <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"درحال پخش در این تلفن"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"مشکلی رخ داد"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"مشکلی پیش آمد. دوباره امتحان کنید."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غیرفعال، برنامه را بررسی کنید"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"پیدا نشد"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"کنترل دردسترس نیست"</string>
@@ -899,8 +890,8 @@
</plurals>
<string name="fgs_dot_content_description" msgid="2865071539464777240">"اطلاعات جدید"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"برنامههای فعال"</string>
- <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"توقف"</string>
- <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"متوقف شد"</string>
+ <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"متوقف کردن"</string>
+ <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"متوقف شده"</string>
<string name="clipboard_edit_text_copy" msgid="770856373439969178">"کپی کردن"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"کپی شد"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"از <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 3257d8b..85623e0 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jos annat väärän kuvion seuraavalla yrityskerralla, työprofiilisi ja sen data poistetaan."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jos annat väärän PIN-koodin seuraavalla yrityskerralla, työprofiilisi ja sen data poistetaan."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Jos annat väärän salasanan seuraavalla yrityskerralla, työprofiilisi ja sen data poistetaan."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Liian monta virheellistä yritystä. Laitteen data poistetaan."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Liian monta virheellistä yritystä. Tämä käyttäjä poistetaan."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Liian monta virheellistä yritystä. Tämä työprofiili ja sen data poistetaan."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Ohita"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Kosketa sormenjälkitunnistinta"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Sormenjälkikuvake"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Kasvoja ei voi tunnistaa. Käytä sormenjälkeä."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Latautuu hitaasti • Täynnä <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> päästä"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ladataan telineellä • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> kunnes täynnä"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Vaihda käyttäjää"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Lisää käyttäjä"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Uusi käyttäjä"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Poistetaaanko vieras?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Poista"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Tervetuloa takaisin!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Haluatko jatkaa istuntoa?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Aloita alusta"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Kyllä, haluan jatkaa"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Lisätäänkö uusi käyttäjä?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Kun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Käyttäjäraja saavutettu"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Voit lisätä korkeintaan <xliff:g id="COUNT">%d</xliff:g> käyttäjää.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Avaa lukitus ja käytä"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Korttien noutamisessa oli ongelma, yritä myöhemmin uudelleen"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Lukitusnäytön asetukset"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skannaa QR-koodi"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Työprofiili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lentokonetila"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Et kuule seuraavaa hälytystäsi (<xliff:g id="WHEN">%1$s</xliff:g>)."</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pyyhkäise nähdäksesi lisää"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Ladataan suosituksia"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Piilotetaanko median käyttökerta?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Tätä median käyttökertaa ei voi piilottaa."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ohita"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Piilota"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Jatka"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Asetukset"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> soittaa nyt tätä: <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>)"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Siirrä <xliff:g id="DEVICENAME">%1$s</xliff:g> lähemmäs toistaaksesi täällä"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Toistetaan: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Toistetaan tällä puhelimella"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Tapahtui virhe"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Jotain meni pieleen. Yritä uudelleen."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Epäaktiivinen, tarkista sovellus"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ei löydy"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Ohjain ei ole käytettävissä"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index e91e55d..f39a639 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si vous entrez un schéma incorrect à la prochaine tentative suivante, votre profil professionnel et ses données seront supprimés."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si vous entrez un NIP incorrect à la prochaine tentative, votre profil professionnel et ses données seront supprimés."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si vous entrez un mot de passe incorrect à la prochaine tentative suivante, votre profil professionnel et ses données seront supprimés."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Trop de tentatives incorrectes. Les données de cet appareil seront supprimées."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Trop de tentatives incorrectes. Cet utilisateur sera supprimé."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Trop de tentatives incorrectes. Ce profil professionnel et ses données seront supprimés."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Fermer"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touchez le capteur d\'empreintes digitales"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Icône d\'empreinte digitale"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Visage non reconnu. Utilisez plutôt l\'empreinte digitale."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"En recharge lente : <xliff:g id="PERCENTAGE">%2$s</xliff:g> • Terminée <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Station de recharge • Recharge terminée dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Ajouter un utilisateur"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Nouvel utilisateur"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Supprimer l\'invité?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recommencer"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oui, continuer"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Ajouter un utilisateur?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nTout utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Limite d\'utilisateurs atteinte"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Vous pouvez ajouter jusqu\'à <xliff:g id="COUNT">%d</xliff:g> utilisateur.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Déverrouiller pour utiliser"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Un problème est survenu lors de la récupération de vos cartes, veuillez réessayer plus tard"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Paramètres de l\'écran de verrouillage"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Numériser le code QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil professionnel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode Avion"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Vous n\'entendrez pas votre prochaine alarme à <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Balayez l\'écran pour en afficher davantage"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Chargement des recommandations…"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Commandes multimédias"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Masquer cette session multimédia?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Impossible de masquer la session multimédia actuelle"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Fermer"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Masquer"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> est en cours de lecteur à partir de <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Rapprochez-vous de <xliff:g id="DEVICENAME">%1$s</xliff:g> pour lire le contenu"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lecture sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Lecture sur ce téléphone"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Un problème est survenu"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Un problème est survenu. Réessayez."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"La commande n\'est pas accessible"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 33194aa..9b0b68f 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si vous dessinez un schéma incorrect lors de la prochaine tentative, votre profil professionnel et les données associées seront supprimés."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si vous saisissez un code incorrect lors de la prochaine tentative, votre profil professionnel et les données associées seront supprimés."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si vous saisissez un mot de passe incorrect lors de la prochaine tentative, votre profil professionnel et les données associées seront supprimés."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Trop de tentatives incorrectes. Les données de cet appareil vont être supprimées."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Trop de tentatives incorrectes. Ce compte utilisateur va être supprimé."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Trop de tentatives incorrectes. Ce profil professionnel et les données associées vont être supprimés."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Fermer"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Appuyez sur le lecteur d\'empreinte digitale"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Icône d\'empreinte digitale"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Visage non reconnu. Utilisez votre empreinte."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge lente • Chargé dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Station de charge • Chargé dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Ajouter un utilisateur"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Nouvel utilisateur"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Supprimer l\'invité ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la dernière session ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Non, nouvelle session"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oui, continuer"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Ajouter un utilisateur ?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nN\'importe quel utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Limite nombre utilisateurs atteinte"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Vous pouvez ajouter <xliff:g id="COUNT">%d</xliff:g> profil utilisateur.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Déverrouiller pour utiliser"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Problème de récupération de vos cartes. Réessayez plus tard"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Paramètres de l\'écran de verrouillage"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Scanner un code QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil professionnel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode Avion"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Vous n\'entendrez pas votre prochaine alarme <xliff:g id="WHEN">%1$s</xliff:g>."</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Balayer l\'écran pour voir plus d\'annonces"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Chargement des recommandations"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimédia"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Masquer cette session multimédia ?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Session multimédia en cours impossible à masquer."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Fermer"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Masquer"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> est en cours de lecture depuis <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Rapprochez l\'appareil pour transférer la diffusion à votre <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lecture sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Lire sur ce téléphone"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Un problème est survenu"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Un problème est survenu. Réessayez."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifier l\'appli"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Commande indisponible"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 52a55e7..915aef1 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Se indicas un padrón incorrecto no seguinte intento, eliminaranse o teu perfil de traballo e os datos asociados."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Se indicas un PIN incorrecto no seguinte intento, eliminaranse o teu perfil de traballo e os datos asociados."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Se indicas un contrasinal incorrecto no seguinte intento, eliminaranse o teu perfil de traballo e os datos asociados."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Realizaches demasiados intentos incorrectos. Eliminaranse os datos deste dispositivo."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Realizaches demasiados intentos incorrectos. Eliminarase este usuario."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Realizaches demasiados intentos incorrectos. Eliminaranse este perfil de traballo e os datos asociados."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Ignorar"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toca o sensor de impresión dixital"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Icona de impresión dixital"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Non se recoñeceu a cara. Usa a impresión dixital."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando lentamente • A carga completarase en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Base de carga • Carga completa dentro de <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Engadir usuario"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuario"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Queres quitar o convidado?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Eliminaranse todas as aplicacións e datos desta sesión."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvido de novo, convidado"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Queres continuar coa túa sesión?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Comezar de novo"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Si, continuar"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Engadir un usuario novo?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Cando engadas un usuario novo, este deberá configurar o seu espazo.\n\nCalquera usuario pode actualizar as aplicacións para todos os demais usuarios."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Alcanzouse o límite de usuarios"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Podes engadir ata <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Produciuse un problema ao obter as tarxetas. Téntao de novo máis tarde"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Configuración da pantalla de bloqueo"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Escanear código QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de traballo"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo avión"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Non escoitarás a alarma seguinte <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Pasar o dedo para ver máis"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendacións"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Contido multimedia"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Queres ocultar esta sesión multimedia?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Non se pode ocultar esta sesión multimedia."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignorar"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Estase reproducindo <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Achégate ao dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>) para reproducir o contido neste"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducindo contido noutro dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>)"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Reproducindo contido neste teléfono"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Produciuse un erro"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Produciuse un erro. Téntao de novo."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Comproba a app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Non se atopou"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"O control non está dispoñible"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 497029e..ce43d8a 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"જો તમે આગલા પ્રયત્નમાં ખોટી પૅટર્ન દાખલ કરશો, તો તમારી કાર્યાલયની પ્રોફાઇલ અને તેનો ડેટા ડિલીટ કરવામાં આવશે."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"જો તમે આગલા પ્રયત્નમાં ખોટો પિન દાખલ કરશો, તો તમારી કાર્યાલયની પ્રોફાઇલ અને તેનો ડેટા ડિલીટ કરવામાં આવશે."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"જો તમે આગલા પ્રયત્નમાં ખોટો પાસવર્ડ દાખલ કરશો, તો તમારી કાર્યાલયની પ્રોફાઇલ અને તેનો ડેટા ડિલીટ કરવામાં આવશે."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"ઘણા બધા ખોટા પ્રયત્નો. આ ડિવાઇસનો ડેટા ડિલીટ કરવામાં આવશે."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"ઘણા બધા ખોટા પ્રયત્નો. આ વપરાશકર્તાને ડિલીટ કરવામાં આવશે."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"ઘણા બધા ખોટા પ્રયત્નો. આ કાર્યાલયની પ્રોફાઇલ અને તેનો ડેટા ડિલીટ કરવામાં આવશે."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"છોડી દો"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ફિંગરપ્રિન્ટના સેન્સરને સ્પર્શ કરો"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"ફિંગરપ્રિન્ટનું આઇકન"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ચહેરો ઓળખી શકતા નથી. તેને બદલે ફિંગરપ્રિન્ટ વાપરો."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ધીમેથી ચાર્જ થઈ રહ્યું છે • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>માં ચાર્જ થઈ જશે"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ડૉકથી ચાર્જ થઈ રહ્યું છે • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>માં સંપૂર્ણ ચાર્જ થઈ જશે"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"વપરાશકર્તા સ્વિચ કરો"</string>
- <string name="user_add_user" msgid="4336657383006913022">"વપરાશકર્તા ઉમેરો"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"નવો વપરાશકર્તા"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"અતિથિ દૂર કરીએ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ અને ડેટા કાઢી નાખવામાં આવશે."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"કાઢી નાખો"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ફરી સ્વાગત છે, અતિથિ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"શું તમે તમારું સત્ર ચાલુ રાખવા માંગો છો?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"શરૂ કરો"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"હા, ચાલુ રાખો"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"નવા વપરાશકર્તાને ઉમેરીએ?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમનું સ્થાન સેટ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા બધા અન્ય વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"વપરાશકર્તા સંખ્યાની મર્યાદા"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">તમે <xliff:g id="COUNT">%d</xliff:g> વપરાશકર્તા સુધી ઉમેરી શકો છો.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ઉપયોગ કરવા માટે અનલૉક કરો"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"તમારા કાર્ડની માહિતી મેળવવામાં સમસ્યા આવી હતી, કૃપા કરીને થોડા સમય પછી ફરી પ્રયાસ કરો"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"લૉક સ્ક્રીનના સેટિંગ"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR કોડ સ્કૅન કરો"</string>
<string name="status_bar_work" msgid="5238641949837091056">"ઑફિસની પ્રોફાઇલ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"એરપ્લેન મોડ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"તમે <xliff:g id="WHEN">%1$s</xliff:g> એ તમારો આગલો એલાર્મ સાંભળશો નહીં"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"વધુ જોવા માટે સ્વાઇપ કરો"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"સુઝાવ લોડ કરી રહ્યાં છીએ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"મીડિયા"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"શું આ મીડિયા સત્ર છુપાવીએ?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"હાલનું મીડિયા સત્ર છુપાવી શકાતું નથી."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"છોડી દો"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"છુપાવો"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ફરી શરૂ કરો"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"સેટિંગ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચાલી રહ્યું છે"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"આમાં ચલાવવા માટે ડિવાઇસને <xliff:g id="DEVICENAME">%1$s</xliff:g>ની નજીક ખસેડો"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> પર ચલાવવામાં આવી રહ્યું છે"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"આ ફોન પર ચલાવવામાં આવી રહ્યું છે"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"કંઈક ખોટું થયું"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"કંઈક ખોટું થયું. ફરી પ્રયાસ કરો."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"નિષ્ક્રિય, ઍપને ચેક કરો"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"મળ્યું નથી"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"નિયંત્રણ ઉપલબ્ધ નથી"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index d7b9f32..9f3a4f5 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"अगर आप फिर से गलत पैटर्न डालते हैं, तो आपकी वर्क प्रोफ़ाइल और उसका डेटा मिटा दिया जाएगा."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"अगर आप फिर से गलत पिन डालते हैं, तो आपकी वर्क प्रोफ़ाइल और उसका डेटा मिटा दिया जाएगा."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"अगर आप फिर से गलत पासवर्ड डालते हैं, तो आपकी वर्क प्रोफ़ाइल और उसका डेटा मिटा दिया जाएगा."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"कई बार गलत कोशिशें की गई हैं. इस डिवाइस का डेटा मिटा दिया जाएगा."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"कई बार गलत कोशिशें की गई हैं. इस उपयोगकर्ता की जानकारी मिटा दी जाएगी."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"कई बार गलत कोशिशें की गई हैं. यह वर्क प्रोफ़ाइल और इसका डेटा मिटा दिया जाएगा."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"खारिज करें"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"फ़िंगरप्रिंट सेंसर को छुएं"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"फ़िंगरप्रिंट आइकॉन"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"चेहरे की पहचान नहीं हुई. फ़िंगरप्रिंट इस्तेमाल करें."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • धीरे चार्ज हो रहा है • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> में पूरा चार्ज हो जाएगा"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • डॉक पर चार्ज हो रहा है • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> में पूरा चार्ज हो जाएगा"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"उपयोगकर्ता बदलें"</string>
- <string name="user_add_user" msgid="4336657383006913022">"उपयोगकर्ता जोड़ें"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"नया उपयोगकर्ता"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"क्या आप मेहमान को हटाना चाहते हैं?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सत्र के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"निकालें"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"मेहमान, आपका फिर से स्वागत है!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"क्या आप अपना सत्र जारी रखना चाहते हैं?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"फिर से शुरू करें"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हां, जारी रखें"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"नया उपयोगकर्ता जोड़ें?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"जब आप कोई नया उपयोगकर्ता जोड़ते हैं, तो उसे अपनी जगह सेट करनी होती है.\n\nकोई भी उपयोगकर्ता बाकी सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"अब और उपयोगकर्ता नहीं जोड़े जा सकते"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">आप ज़्यादा से ज़्यादा <xliff:g id="COUNT">%d</xliff:g> उपयोगकर्ता जोड़ सकते हैं.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"इस्तेमाल करने के लिए, डिवाइस अनलॉक करें"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"आपके कार्ड की जानकारी पाने में कोई समस्या हुई है. कृपया बाद में कोशिश करें"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"लॉक स्क्रीन की सेटिंग"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"क्यूआर कोड स्कैन करें"</string>
<string name="status_bar_work" msgid="5238641949837091056">"वर्क प्रोफ़ाइल"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"हवाई जहाज़ मोड"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"आपको <xliff:g id="WHEN">%1$s</xliff:g> पर अपना अगला अलार्म नहीं सुनाई देगा"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ज़्यादा देखने के लिए स्वाइप करें"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"सुझाव लोड हो रहे हैं"</string>
<string name="controls_media_title" msgid="1746947284862928133">"मीडिया"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"क्या आप इस मीडिया सेशन को छिपाना चाहते हैं?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"मौजूदा मीडिया सेशन को छिपाया नहीं जा सकता."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"खारिज करें"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"छिपाएं"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"फिर से शुरू करें"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> पर, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> का <xliff:g id="SONG_NAME">%1$s</xliff:g> चल रहा है"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"अपने डिवाइस पर मीडिया फ़ाइल ट्रांसफ़र करने के लिए, उसे <xliff:g id="DEVICENAME">%1$s</xliff:g> के पास ले जाएं"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> पर मीडिया चल रहा है"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"इस फ़ोन पर मीडिया चल रहा है"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"कोई गड़बड़ी हुई"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"कोई गड़बड़ी हुई. फिर से कोशिश करें."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"काम नहीं कर रहा, ऐप जांचें"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"कंट्रोल नहीं है"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"कंट्रोल मौजूद नहीं है"</string>
@@ -900,7 +891,7 @@
<string name="fgs_dot_content_description" msgid="2865071539464777240">"नई जानकारी"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ये ऐप्लिकेशन चालू हैं"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"बंद करें"</string>
- <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"रुका हुआ है"</string>
+ <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"बंद है"</string>
<string name="clipboard_edit_text_copy" msgid="770856373439969178">"कॉपी करें"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"कॉपी किया गया"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> से"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 77cf814..8004b5e 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ako pri sljedećem pokušaju unesete netočan uzorak, izbrisat će se vaš poslovni profil i njegovi podaci."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ako pri sljedećem pokušaju unesete netočan PIN, izbrisat će se vaš poslovni profil i njegovi podaci."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ako pri sljedećem pokušaju unesete netočnu zaporku, izbrisat će se vaš poslovni profil i njegovi podaci."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Previše netočnih pokušaja. S uređaja će se izbrisati podaci."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Previše netočnih pokušaja. Ovaj će se korisnik izbrisati."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Previše netočnih pokušaja. Ovaj će se poslovni profil izbrisati zajedno sa svim svojim podacima."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Odbaci"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dodirnite senzor otiska prsta"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona otiska prsta"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Prepoznavanje lica nije uspjelo. Upotrijebite otisak prsta."</string>
@@ -325,17 +321,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • sporo punjenje • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do napunjenosti"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Priključna stanica za punjenje • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do napunjenosti"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Promjena korisnika"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Dodavanje korisnika"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ukloniti gosta?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji bit će izbrisani."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli natrag, gostu!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Dodati novog korisnika?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Kada dodate novog korisnika, ta osoba mora postaviti vlastiti prostor.\n\nBilo koji korisnik može ažurirati aplikacije za sve ostale korisnike."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Dosegnuto je ograničenje korisnika"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
@@ -790,9 +781,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Prijeđite prstom da vidite više"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavanje preporuka"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Želite li sakriti medijsku sesiju?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Želite li sakriti kontroler medija za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Trenutačna medijska sesija ne može se sakriti."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Odbaci"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> reproducira se putem aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -810,7 +801,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da biste na njemu reproducirali"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducira se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Reproducira se na ovom telefonu"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Nešto nije u redu"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije u redu. Pokušajte ponovo."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, provjerite aplik."</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index f256bc1..ec9a40e 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Amennyiben helytelen mintát ad meg a következő kísérletnél, a rendszer törli munkaprofilját és a kapcsolódó adatokat."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Amennyiben helytelen PIN-kódot ad meg a következő kísérletnél, a rendszer törli munkaprofilját és a kapcsolódó adatokat."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Amennyiben helytelen jelszót ad meg a következő kísérletnél, a rendszer törli munkaprofilját és a kapcsolódó adatokat."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Túl sok sikertelen próbálkozás. A rendszer törli az adatokat az eszközről."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Túl sok sikertelen próbálkozás. A rendszer törli ezt a felhasználót."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Túl sok sikertelen próbálkozás. A rendszer törli ezt a munkaprofilt és a kapcsolódó adatokat."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Elvetés"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Érintse meg az ujjlenyomat-érzékelőt"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ujjlenyomat ikonja"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Az arc nem felismerhető. Használjon ujjlenyomatot."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Lassú töltés • A teljes töltöttségig: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Töltődokk • A teljes töltöttségig: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Felhasználóváltás"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Felhasználó hozzáadása"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Új felhasználó"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Eltávolítja a vendég munkamenetet?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eltávolítás"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Örülünk, hogy visszatért, vendég!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Folytatja a munkamenetet?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Újrakezdés"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Igen, folytatom"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Új felhasználó hozzáadása?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Ha új felhasználót ad hozzá, az illetőnek be kell állítania saját tárterületét.\n\nBármely felhasználó frissítheti az alkalmazásokat valamennyi felhasználó számára."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Maximális felhasználószám elérve"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Legfeljebb <xliff:g id="COUNT">%d</xliff:g> felhasználót adhat hozzá.</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Továbbiak megtekintéséhez csúsztasson"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Javaslatok betöltése…"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Média"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Elrejti ezt a média-munkamenetet?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Elrejti ezt a(z) <xliff:g id="APP_NAME">%1$s</xliff:g>-médiavezérlőt?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Az aktuális média-munkamenet nem rejthető el."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Elvetés"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Elrejtés"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Folytatás"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Beállítások"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> <xliff:g id="SONG_NAME">%1$s</xliff:g> című száma hallható itt: <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Menjen közelebb a(z) <xliff:g id="DEVICENAME">%1$s</xliff:g> eszközhöz, hogy itt játszhassa le a tartalmat"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lejátszás folyamatban a(z) <xliff:g id="DEVICENAME">%1$s</xliff:g> eszközön"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Lejátszás ezen a telefonon"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Hiba történt"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Hiba történt. Próbálkozzon újra."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktív, ellenőrizze az appot"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nem található"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Nem hozzáférhető vezérlő"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index a4e3b82..999a37f 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Հաջորդ փորձի ժամանակ սխալ նախշ մուտքագրելու դեպքում ձեր աշխատանքային պրոֆիլը և դրա տվյալները կջնջվեն։"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Հաջորդ փորձի ժամանակ սխալ PIN կոդ մուտքագրելու դեպքում աշխատանքային պրոֆիլը և դրա տվյալները կջնջվեն։"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Հաջորդ փորձի ժամանակ սխալ գաղտնաբառ մուտքագրելու դեպքում աշխատանքային պրոֆիլը և դրա տվյալները կջնջվեն։"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Չափից շատ սխալ փորձեր են արվել։ Այս սարքի տվյալները կջնջվեն։"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Չափից շատ սխալ փորձեր են արվել։ Oգտատիրոջ պրոֆիլը կջնջվի։"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Չափից շատ սխալ փորձեր են արվել։ Աշխատանքային պրոֆիլը և դրա տվյալները կջնջվեն։"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Փակել"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Հպեք մատնահետքի սկաներին"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Մատնահետքի պատկերակ"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Դեմքը չի հաջողվում ճանաչել։ Օգտագործեք մատնահետքը։"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Դանդաղ լիցքավորում • Մնացել է <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Լիցքավորում դոկ-կայանի միջոցով • Մնացել է <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Անջատել օգտվողին"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Ավելացնել օգտատեր"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Նոր օգտատեր"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Հեռացնե՞լ հյուրին"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր ծրագրերն ու տվյալները կջնջվեն:"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Հեռացնել"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Բարի վերադարձ, հյուր"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Շարունակե՞լ աշխատաշրջանը։"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Վերսկսել"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Այո, շարունակել"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Ավելացնե՞լ նոր օգտատեր"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Երբ նոր օգտատեր եք ավելացնում, նա պետք է կարգավորի իր պրոֆիլը:\n\nՑանկացած օգտատեր կարող է թարմացնել հավելվածները մյուս բոլոր հաշիվների համար:"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Սահմանաչափը սպառված է"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Հնարավոր է ավելացնել առավելագույնը <xliff:g id="COUNT">%d</xliff:g> օգտատեր։</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ապակողպել՝ օգտագործելու համար"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Չհաջողվեց բեռնել քարտերը։ Նորից փորձեք։"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Կողպէկրանի կարգավորումներ"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Սկանավորել QR կոդը"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Android for Work-ի պրոֆիլ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Ավիառեժիմ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Ժամը <xliff:g id="WHEN">%1$s</xliff:g>-ի զարթուցիչը չի զանգի"</string>
@@ -546,7 +536,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Մուտք"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Հետշարժ"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Նվագարկում/դադար"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Դադարեցնել"</string>
+ <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Կանգնեցնել"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Հաջորդը"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Նախորդը"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Հետ անցնել"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Սահեցրեք մատը՝ ավելին իմանալու համար"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Բեռնման խորհուրդներ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Մեդիա"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Թաքցնե՞լ մեդիայի աշխատաշրջանը"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Չհաջողվեց թաքցնել մեդիայի ընթացիկ աշխատաշրջանը։"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Փակել"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Թաքցնել"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Շարունակել"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Կարգավորումներ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Այժմ նվագարկվում է <xliff:g id="SONG_NAME">%1$s</xliff:g> երգը <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-ի կատարմամբ <xliff:g id="APP_LABEL">%3$s</xliff:g> հավելվածից"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ավելի մոտեցեք «<xliff:g id="DEVICENAME">%1$s</xliff:g>» սարքին՝ նվագարկումը սկսելու համար"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Նվագարկվում է «<xliff:g id="DEVICENAME">%1$s</xliff:g>» սարքում"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Նվագարկվում է այս հեռախոսում"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Սխալ առաջացավ"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Սխալ առաջացավ։ Նորից փորձեք։"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Ակտիվ չէ, ստուգեք հավելվածը"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Չի գտնվել"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Կառավարման տարրը հասանելի չէ"</string>
@@ -824,7 +815,7 @@
<string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Նոր սարքի զուգակցում"</string>
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Այս աշխատաշրջանը հեռարձակելու համար բացեք հավելվածը"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Անհայտ հավելված"</string>
- <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Դադարեցնել հեռարձակումը"</string>
+ <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Կանգնեցնել հեռարձակումը"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string>
<string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string>
@@ -899,7 +890,7 @@
</plurals>
<string name="fgs_dot_content_description" msgid="2865071539464777240">"Նոր տեղեկություն"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ակտիվ հավելվածներ"</string>
- <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Դադարեցնել"</string>
+ <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Կանգնեցնել"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Կանգնեցված է"</string>
<string name="clipboard_edit_text_copy" msgid="770856373439969178">"Պատճենել"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Պատճենվեց"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index c9ce287..3fb87ac 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jika Anda memasukkan pola yang salah saat mencoba lagi, profil kerja dan datanya akan dihapus."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jika Anda memasukkan PIN yang salah saat mencoba lagi, profil kerja dan datanya akan dihapus."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Jika Anda memasukkan sandi yang salah saat mencoba lagi, profil kerja dan datanya akan dihapus."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Terlalu banyak percobaan yang salah. Data perangkat ini akan dihapus."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Terlalu banyak percobaan yang salah. Pengguna ini akan dihapus."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Terlalu banyak percobaan yang salah. Profil kerja ini dan datanya akan dihapus."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Tutup"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Sentuh sensor sidik jari"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikon sidik jari"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Tidak dapat mengenali wajah. Gunakan sidik jari."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengisi daya dengan lambat • Penuh dalam waktu <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengisi Daya dengan Dok • Penuh dalam waktu <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Beralih pengguna"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Tambahkan pengguna"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Pengguna baru"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Hapus tamu?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data di sesi ini akan dihapus."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hapus"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat datang kembali, tamu!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Lanjutkan sesi Anda?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulai ulang"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ya, lanjutkan"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Tambahkan pengguna baru?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruangnya sendiri.\n\nPengguna mana pun dapat mengupdate aplikasi untuk semua pengguna lain."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Batas pengguna tercapai"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Anda dapat menambahkan hingga <xliff:g id="COUNT">%d</xliff:g> pengguna.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Buka kunci untuk menggunakan"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Terjadi masalah saat mendapatkan kartu Anda, coba lagi nanti"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Setelan layar kunci"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Pindai kode QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil kerja"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mode pesawat"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Anda tidak akan mendengar alarm berikutnya <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Geser untuk melihat selengkapnya"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Memuat rekomendasi"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Sembunyikan sesi media ini?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Sesi media aktif tidak dapat disembunyikan."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Tutup"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sembunyikan"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Lanjutkan"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Setelan"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> sedang diputar dari <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Dekatkan ke <xliff:g id="DEVICENAME">%1$s</xliff:g> untuk memutar di sini"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Diputar di <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Diputar di ponsel ini"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Terjadi error"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Terjadi error. Coba lagi."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nonaktif, periksa aplikasi"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol tidak tersedia"</string>
@@ -899,7 +890,7 @@
</plurals>
<string name="fgs_dot_content_description" msgid="2865071539464777240">"Informasi baru"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplikasi aktif"</string>
- <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Berhenti"</string>
+ <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Hentikan"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Dihentikan"</string>
<string name="clipboard_edit_text_copy" msgid="770856373439969178">"Salin"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Disalin"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 78d2ecf..39fb762 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ef þú slærð inn rangt mynstur í næstu tilraun verður vinnusniðinu þínu og gögnum þess eytt."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ef þú slærð inn rangt PIN-númer í næstu tilraun verður vinnusniðinu þínu og gögnum þess eytt."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ef þú slærð inn rangt aðgangsorð í næstu tilraun verður vinnusniðinu þínu og gögnum þess eytt."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Of margar rangar tilraunir. Gögnum tækisins verður eytt."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Of margar rangar tilraunir. Þessum notanda verður eytt."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Of margar rangar tilraunir. Þessu vinnusniði og gögnum þess verður eytt."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Loka"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Snertu fingrafaralesarann"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Fingrafaratákn"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Andlit þekkist ekki. Notaðu fingrafar í staðinn."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Hæg hleðsla • Full hleðsla eftir <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Hleður í dokku • Full hleðsla eftir <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skipta um notanda"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Bæta notanda við"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Nýr notandi"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Fjarlægja gest?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjarlægja"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkominn aftur, gestur!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Viltu halda áfram með lotuna?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Byrja upp á nýtt"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Já, halda áfram"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Bæta nýjum notanda við?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Þegar þú bætir nýjum notanda við þarf sá notandi að setja upp svæðið sitt.\n\nHvaða notandi sem er getur uppfært forrit fyrir alla aðra notendur."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Notandahámarki náð"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Þú getur bætt við allt að <xliff:g id="COUNT">%d</xliff:g> notanda.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Taktu úr lás til að nota"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Vandamál kom upp við að sækja kortin þín. Reyndu aftur síðar"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Stillingar fyrir læstan skjá"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skanna QR-kóða"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Vinnusnið"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flugstilling"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Ekki mun heyrast í vekjaranum <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Strjúktu til að sjá meira"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Hleður tillögum"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Margmiðlunarefni"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Fela þessa efnislotu?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Ekki tókst að fela opna efnislotu."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Hunsa"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fela"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Halda áfram"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Stillingar"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> með <xliff:g id="ARTIST_NAME">%2$s</xliff:g> er í spilun á <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Færðu tækið nær <xliff:g id="DEVICENAME">%1$s</xliff:g> til að spila hér"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Í spilun í <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Í spilun í þessum síma"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Eitthvað fór úrskeiðis"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Eitthvað fór úrskeiðis. Reyndu aftur."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Óvirkt, athugaðu forrit"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Fannst ekki"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Stýring er ekki tiltæk"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 9b0f917..a8d73d0 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Se al prossimo tentativo inserirai una sequenza sbagliata, il tuo profilo di lavoro e i relativi dati verranno eliminati."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Se al prossimo tentativo inserirai un PIN sbagliato, il tuo profilo di lavoro e i relativi dati verranno eliminati."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Se al prossimo tentativo inserirai una password sbagliata, il tuo profilo di lavoro e i relativi dati verranno eliminati."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Troppi tentativi sbagliati. I dati del dispositivo verranno eliminati."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Troppi tentativi sbagliati. Questo utente verrà eliminato."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Troppi tentativi sbagliati. Questo profilo di lavoro e i relativi dati verranno eliminati."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Ignora"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Tocca il sensore di impronte"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Icona dell\'impronta"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Impossibile riconoscere il volto. Usa l\'impronta."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ricarica lenta • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> alla ricarica completa"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • In carica nel dock • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> alla ricarica completa"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambio utente"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Aggiungi utente"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Nuovo utente"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Rimuovere l\'ospite?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Rimuovi"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Ti ridiamo il benvenuto alla sessione Ospite."</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vuoi continuare la sessione?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Ricomincia"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sì, continua"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Aggiungere un nuovo utente?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Il nuovo utente, una volta aggiunto, deve impostare il proprio spazio.\n\nQualsiasi utente può aggiornare le app per tutti gli altri."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Limite di utenti raggiunto"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Puoi aggiungere fino a <xliff:g id="COUNT">%d</xliff:g> utenti.</item>
@@ -784,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Scorri per vedere altro"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Caricamento dei consigli"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Contenuti multimediali"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Vuoi nascondere questa sessione multimediale?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Imposs. nascondere sessione multimediale corrente."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignora"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Nascondi"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Riprendi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Impostazioni"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> di <xliff:g id="ARTIST_NAME">%2$s</xliff:g> è in riproduzione da <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -804,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Avvicinati a <xliff:g id="DEVICENAME">%1$s</xliff:g> per riprodurre i contenuti qui"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"In riproduzione su <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"In riproduzione su questo telefono"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Si è verificato un errore"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Si è verificato un errore. Riprova."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inattivo, controlla l\'app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Controllo non trovato"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Il controllo non è disponibile"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 7dcde9cf..fc5d818 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"הזנת קו ביטול נעילה שגוי בניסיון הבא תגרום למחיקת פרופיל העבודה והנתונים המשויכים אליו."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"הזנה של קוד אימות שגוי בניסיון הבא תגרום למחיקת פרופיל העבודה והנתונים המשויכים אליו."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"הזנת סיסמה שגויה בניסיון הבא תגרום למחיקת פרופיל העבודה והנתונים המשויכים אליו."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"נעשו יותר מדי ניסיונות שגויים. הנתונים במכשיר יימחקו."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"בוצעו יותר מדי ניסיונות שגויים. המשתמש הזה יימחק."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"נעשו יותר מדי ניסיונות שגויים. פרופיל העבודה הזה והנתונים המשויכים אליו יימחקו."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"סגירה"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"יש לגעת בחיישן טביעות האצבע"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"סמל טביעת אצבע"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"לא ניתן לזהות את הפנים. יש להשתמש בטביעת אצבע במקום."</string>
@@ -327,17 +323,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • בטעינה איטית • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> עד לסיום"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • אביזר העגינה בטעינה • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> עד לסיום"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"החלפת משתמש"</string>
- <string name="user_add_user" msgid="4336657383006913022">"הוספת משתמש"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"משתמש חדש"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"להסיר אורח?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בסשן הזה יימחקו."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"הסרה"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"שמחים לראותך שוב!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"האם ברצונך להמשיך בפעילות באתר?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"סשן חדש"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"כן, להמשיך"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"להוסיף משתמש חדש?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"כשמוסיפים משתמש חדש, המשתמש הזה צריך להגדיר את השטח שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"הגעת למגבלת המשתמשים שניתן להוסיף"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="two">ניתן להוסיף עד <xliff:g id="COUNT">%d</xliff:g> משתמשים.</item>
@@ -465,8 +456,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"יש לבטל את הנעילה כדי להשתמש"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"הייתה בעיה בקבלת הכרטיסים שלך. כדאי לנסות שוב מאוחר יותר"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"הגדרות מסך הנעילה"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"סריקת קוד QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"פרופיל עבודה"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"מצב טיסה"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"לא ניתן יהיה לשמוע את ההתראה הבאה שלך <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -797,9 +787,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"יש להחליק כדי להציג עוד פריטים"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ההמלצות בטעינה"</string>
<string name="controls_media_title" msgid="1746947284862928133">"מדיה"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"להסתיר את סשן המדיה?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"לא ניתן להסתיר את סשן המדיה הנוכחי."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"סגירה"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"הסתרה"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"המשך"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"הגדרות"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> של <xliff:g id="ARTIST_NAME">%2$s</xliff:g> מופעל מ-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -817,7 +808,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"צריך להתקרב אל <xliff:g id="DEVICENAME">%1$s</xliff:g> כדי להפעיל כאן"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"פועלת ב-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"פועלת בטלפון הזה"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"משהו השתבש"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"משהו השתבש. יש לנסות שוב."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"לא פעיל, יש לבדוק את האפליקציה"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"לא נמצא"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"הפקד לא זמין"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 956826b..0f07c41 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"パターンをあと 1 回間違えると、仕事用プロファイルと関連データが削除されます。"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"PIN をあと 1 回間違えると、仕事用プロファイルと関連データが削除されます。"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"パスワードをあと 1 回間違えると、仕事用プロファイルと関連データが削除されます。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"間違えた回数が上限を超えました。このデバイスのデータが削除されます。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"間違えた回数が上限を超えました。このユーザーが削除されます。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"間違えた回数が上限を超えました。この仕事用プロファイルと関連データが削除されます。"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"閉じる"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"指紋認証センサーをタッチ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"指紋アイコン"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"顔を認識できません。指紋認証を使用してください。"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 低速充電中 • 完了まで <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ホルダーで充電中 • 完了まで <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ユーザーを切り替える"</string>
- <string name="user_add_user" msgid="4336657383006913022">"ユーザーを追加"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"新しいユーザー"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ゲストを削除しますか?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"削除"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"おかえりなさい、ゲストさん"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"セッションを続行しますか?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"最初から開始"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"続行"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"新しいユーザーを追加しますか?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"新しいユーザーを追加したら、そのユーザーは自分のスペースをセットアップする必要があります。\n\nすべてのユーザーは他のユーザーに代わってアプリを更新できます。"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"ユーザー数が上限に達しました"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">最大 <xliff:g id="COUNT">%d</xliff:g> 人のユーザーを追加できます。</item>
@@ -784,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"スワイプすると他の構造が表示されます"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"候補を読み込んでいます"</string>
<string name="controls_media_title" msgid="1746947284862928133">"メディア"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"このメディア セッションを非表示にしますか?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"現在のメディア セッションは非表示にできません。"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"閉じる"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"非表示"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"再開"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>(アーティスト名: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>)が <xliff:g id="APP_LABEL">%3$s</xliff:g> で再生中"</string>
@@ -804,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ここで再生するには<xliff:g id="DEVICENAME">%1$s</xliff:g>に近づいてください"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>で再生しています"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"このスマートフォンで再生しています"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"エラーが発生しました"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"エラーが発生しました。もう一度お試しください。"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"無効: アプリをご確認ください"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"見つかりませんでした"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"コントロールを使用できません"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 7ecdfd9..e0bf927 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"შემდეგი მცდელობისას განმბლოკავი ნიმუშის არასწორად შეყვანის შემთხვევაში, თქვენი სამსახურის პროფილი და მისი მონაცემები წაიშლება."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"შემდეგი მცდელობისას PIN-კოდის არასწორად შეყვანის შემთხვევაში, თქვენი სამსახურის პროფილი და მისი მონაცემები წაიშლება."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"შემდეგი მცდელობისას პაროლის არასწორად შეყვანის შემთხვევაში, თქვენი სამსახურის პროფილი და მისი მონაცემები წაიშლება."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"დაფიქსირდა ზედმეტად ბევრი არასწორი მცდელობა. შედეგად, ამ მოწყობილობის მონაცემები წაიშლება."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"დაფიქსირდა ზედმეტად ბევრი არასწორი მცდელობა. შედეგად, ეს მომხმარებელი წაიშლება."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"დაფიქსირდა ზედმეტად ბევრი არასწორი მცდელობა. შედეგად, სამსახურის ეს პროფილი და მისი მონაცემები წაიშლება."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"დახურვა"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"შეეხეთ თითის ანაბეჭდის სენსორს"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"თითის ანაბეჭდის ხატულა"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"სახის ამოცნობა ვერ ხერხდება. სანაცვლოდ თითის ანაბეჭდი გამოიყენეთ."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ნელა იტენება • სრულ დატენვამდე <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • დამტენი სამაგრი • დატენამდე დარჩა <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"მომხმარებლის გადართვა"</string>
- <string name="user_add_user" msgid="4336657383006913022">"მომხმარებლის დამატება"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"ახალი მომხმარებელი"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"სტუმრის ამოშლა?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ამ სესიის ყველა აპი და მონაცემი წაიშლება."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ამოშლა"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"სტუმარო, გვიხარია, რომ დაბრუნდით!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"გსურთ, თქვენი სესიის გაგრძელება?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ხელახლა დაწყება"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"დიახ, გავაგრძელოთ"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"დაემატოს ახალი მომხმარებელი?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"ახალი მომხმარებლის დამატებისას, ამ მომხმარებელს საკუთარი სივრცის შექმნა მოუწევს.\n\nნებისმიერ მომხმარებელს შეუძლია აპები ყველა სხვა მომხმარებლისათვის განაახლოს."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"მიღწეულია მომხმარებელთა ლიმიტი"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">შესაძლებელია <xliff:g id="COUNT">%d</xliff:g>-მდე მომხმარებლის დამატება.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"გამოსაყენებლად განბლოკვა"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"თქვენი ბარათების მიღებისას პრობლემა წარმოიშვა. ცადეთ ხელახლა მოგვიანებით"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ჩაკეტილი ეკრანის პარამეტრები"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR კოდის სკანირება"</string>
<string name="status_bar_work" msgid="5238641949837091056">"სამსახურის პროფილი"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"თვითმფრინავის რეჟიმი"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"ვერ გაიგონებთ მომდევნო მაღვიძარას <xliff:g id="WHEN">%1$s</xliff:g>-ზე"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"გადაფურცლეთ მეტის სანახავად"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"მიმდინარეობს რეკომენდაციების ჩატვირთვა"</string>
<string name="controls_media_title" msgid="1746947284862928133">"მედია"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"დაიმალოს მედიის ეს სესია?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"დაიმალოს მედიის ეს კონტროლერი <xliff:g id="APP_NAME">%1$s</xliff:g> აპში?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"მედიის მიმდინარე სესიის დამალვა შეუძლებელია."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"დახურვა"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"დამალვა"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"გაგრძელება"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"პარამეტრები"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, უკრავს <xliff:g id="APP_LABEL">%3$s</xliff:g>-დან"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"მიუახლოვდით <xliff:g id="DEVICENAME">%1$s</xliff:g>-ს მისი მეშვეობით დასაკრავად"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"მიმდინარეობს დაკვრა <xliff:g id="DEVICENAME">%1$s</xliff:g>-ზე"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"მიმდინარეობს დაკვრა ამ ტელეფონზე"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"რაღაც შეცდომაა"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"რაღაც შეცდომა მოხდა. ცადეთ ხელახლა."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"არააქტიურია, გადაამოწმეთ აპი"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ვერ მოიძებნა"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"კონტროლი მიუწვდომელია"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 85283de..d83420a 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Келесі әрекет кезінде қате өрнек енгізсеңіз, жұмыс профиліңіз бен оның деректері жойылады."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Келесі әрекет кезінде қате PIN кодын енгізсеңіз, жұмыс профиліңіз бен оның деректері жойылады."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Келесі әрекет кезінде қате құпия сөз енгізсеңіз, жұмыс профиліңіз бен оның деректері жойылады."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Тым көп қате әрекет жасалды. Бұл құрылғылардың деректері жойылады."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Тым көп қате әрекет жасалды. Бұл пайдаланушы жойылады."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Тым көп қате әрекет жасалды. Бұл жұмыс профилі мен оның деректері жойылады."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Жабу"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Саусақ ізін оқу сканерін түртіңіз"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Саусақ ізі белгішесі"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Бет танылмады. Орнына саусақ ізін пайдаланыңыз."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Баяу зарядталуда • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Қондыру станциясында зарядталуда • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Пайдаланушыны ауыстыру"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Пайдаланушы қосу"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Жаңа пайдаланушы"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Қонақты жою керек пе?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданбалар мен деректер жойылады."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Алып тастау"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Қош келдіңіз, қонақ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансты жалғастыру керек пе?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Қайта бастау"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Иә, жалғастыру"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Жаңа пайдаланушы қосылсын ба?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Жаңа пайдаланушыны қосқанда, сол адам өз кеңістігін реттеуі керек.\n\nКез келген пайдаланушы барлық басқа пайдаланушылар үшін қолданбаларды жаңарта алады."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Пайдаланушылар саны шегіне жетті"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other"><xliff:g id="COUNT">%d</xliff:g> пайдаланушыға дейін енгізуге болады.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Пайдалану үшін құлыпты ашу"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Карталарыңыз алынбады, кейінірек қайталап көріңіз."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Экран құлпының параметрлері"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR кодын сканерлеу"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Жұмыс профилі"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Ұшақ режимі"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Келесі <xliff:g id="WHEN">%1$s</xliff:g> дабылыңызды есітпейсіз"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Толығырақ ақпарат алу үшін сырғытыңыз."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Жүктеуге қатысты ұсыныстар"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Мультимедиа"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Бұл мультимедиа сеансы жасырылсын ба?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Ағымдағы мультимедиа сеансын жасыру мүмкін емес."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Жабу"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жасыру"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Жалғастыру"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> қолданбасында <xliff:g id="ARTIST_NAME">%2$s</xliff:g> орындайтын \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" әні ойнатылуда."</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Осы жерде ойнау үшін <xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысына жақындаңыз"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысында ойнатылуда."</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Осы телефонда ойнатылуда."</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Бірдеңе дұрыс болмады."</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Бірдеңе дұрыс болмады. Қайталап көріңіз."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Өшірулі. Қолданба тексеріңіз."</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Табылмады"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Басқару виджеті қолжетімсіз"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 9e527e4..9ca2645 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ប្រសិនបើអ្នកបញ្ចូលលំនាំមិនត្រឹមត្រូវ នៅពេលព្យាយាមបញ្ចូលលើកក្រោយ កម្រងព័ត៌មានការងាររបស់អ្នក និងទិន្នន័យរបស់កម្រងព័ត៌មាននេះនឹងត្រូវបានលុប។"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ប្រសិនបើអ្នកបញ្ចូលកូដ PIN មិនត្រឹមត្រូវ នៅពេលព្យាយាមបញ្ចូលលើកក្រោយ កម្រងព័ត៌មានការងាររបស់អ្នក និងទិន្នន័យរបស់កម្រងព័ត៌មាននេះនឹងត្រូវបានលុប។"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ប្រសិនបើអ្នកបញ្ចូលពាក្យសម្ងាត់មិនត្រឹមត្រូវ នៅពេលព្យាយាមបញ្ចូលលើកក្រោយ កម្រងព័ត៌មានការងាររបស់អ្នក និងទិន្នន័យរបស់កម្រងព័ត៌មាននេះនឹងត្រូវបានលុប។"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"ដោយសារមានការព្យាយាមដោះសោមិនត្រឹមត្រូវច្រើនដងពេក ទិន្នន័យរបស់ឧបករណ៍នេះនឹងត្រូវបានលុប។"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"ដោយសារមានការព្យាយាមដោះសោមិនត្រឹមត្រូវច្រើនដងពេក អ្នកប្រើប្រាស់នេះនឹងត្រូវបានដកចេញ។"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"ដោយសារមានការព្យាយាមដោះសោមិនត្រឹមត្រូវច្រើនដងពេក កម្រងព័ត៌មានការងារនេះ និងទិន្នន័យរបស់វានឹងត្រូវបានលុប។"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"ច្រានចោល"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ប៉ះឧបករណ៍ចាប់ស្នាមម្រាមដៃ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"រូបស្នាមម្រាមដៃ"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"មិនអាចសម្គាល់មុខបានទេ។ សូមប្រើស្នាមម្រាមដៃជំនួសវិញ។"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • កំពុងសាកថ្មយឺត • ពេញក្នុងរយៈពេល <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ឧបករណ៍ភ្ជាប់សាកថ្ម • ពេញក្នុងរយៈពេល <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ទៀត"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ប្ដូរអ្នកប្រើ"</string>
- <string name="user_add_user" msgid="4336657383006913022">"បញ្ចូលអ្នកប្រើ"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"អ្នកប្រើថ្មី"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ដកភ្ញៀវចេញឬ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"កម្មវិធី និងទិន្នន័យទាំងអស់ក្នុងវគ្គនេះនឹងត្រូវលុប។"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ដកចេញ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"សូមស្វាគមន៍ការត្រឡប់មកវិញ, ភ្ញៀវ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"តើអ្នកចង់បន្តវគ្គរបស់អ្នកទេ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ចាប់ផ្ដើមសាជាថ្មី"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"បាទ/ចាស បន្ត"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"បញ្ចូលអ្នកប្រើថ្មីឬ?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"នៅពេលអ្នកបញ្ចូលអ្នកប្រើថ្មី អ្នកប្រើនោះត្រូវរៀបចំកន្លែងរបស់គេ។\n\nអ្នកប្រើណាក៏អាចដំឡើងកំណែកម្មវិធីសម្រាប់អ្នកប្រើទាំងអស់ផ្សេងទៀតបានដែរ។"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"បានឈានដល់ចំនួនកំណត់អ្នកប្រើប្រាស់"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">អ្នកអាចបញ្ចូលអ្នកប្រើប្រាស់បានរហូតដល់ <xliff:g id="COUNT">%d</xliff:g> នាក់។</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ដោះសោដើម្បីប្រើប្រាស់"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"មានបញ្ហាក្នុងការទាញយកកាតរបស់អ្នក សូមព្យាយាមម្ដងទៀតនៅពេលក្រោយ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ការកំណត់អេក្រង់ចាក់សោ"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"ស្កេនកូដ QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"ប្រវត្តិរូបការងារ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ពេលជិះយន្តហោះ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"អ្នកនឹងមិនលឺម៉ោងរោទ៍ <xliff:g id="WHEN">%1$s</xliff:g> បន្ទាប់របស់អ្នកទេ"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"អូសដើម្បីមើលច្រើនទៀត"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"កំពុងផ្ទុកការណែនាំ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"មេឌៀ"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"លាក់វគ្គមេឌៀនេះឬ?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"មិនអាចលាក់វគ្គមេឌៀបច្ចុប្បន្នបានទេ។"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ច្រានចោល"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"លាក់"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"បន្ត"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ការកំណត់"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ច្រៀងដោយ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> កំពុងចាក់ពី <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"រំកិលឱ្យកាន់តែជិត <xliff:g id="DEVICENAME">%1$s</xliff:g> ដើម្បីចាក់នៅទីនេះ"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"កំពុងចាក់នៅលើ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"កំពុងចាក់នៅលើទូរសព្ទនេះ"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"មានអ្វីមួយខុសប្រក្រតី"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"មានអ្វីមួយខុសប្រក្រតី។ សូមព្យាយាមម្ដងទៀត។"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"អសកម្ម ពិនិត្យមើលកម្មវិធី"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"រកមិនឃើញទេ"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"មិនអាចគ្រប់គ្រងបានទេ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index ce0ca0e..1a19968 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ಮುಂದಿನ ಪ್ರಯತ್ನದಲ್ಲಿ ನೀವು ತಪ್ಪಾದ ಪ್ಯಾಟರ್ನ್ ನಮೂದಿಸಿದರೆ, ನಿಮ್ಮ ಉದ್ಯೋಗದ ಪ್ರೊಫೈಲ್ ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ಮುಂದಿನ ಪ್ರಯತ್ನದಲ್ಲಿ ನೀವು ತಪ್ಪಾದ ಪಿನ್ ನಮೂದಿಸಿದರೆ, ನಿಮ್ಮ ಉದ್ಯೋಗದ ಪ್ರೊಫೈಲ್ ಮತ್ತು ಅದರ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ಮುಂದಿನ ಪ್ರಯತ್ನದಲ್ಲಿ ನೀವು ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್ ನಮೂದಿಸಿದರೆ, ನಿಮ್ಮ ಉದ್ಯೋಗದ ಪ್ರೊಫೈಲ್ ಮತ್ತು ಅದರ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"ಹಲವಾರು ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಈ ಸಾಧನದ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"ಹಲವಾರು ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಈ ಬಳಕೆದಾರರನ್ನು ಅಳಿಸಲಾಗುವುದು."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"ಹಲವಾರು ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಈ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಮತ್ತು ಅದರ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"ವಜಾಗೊಳಿಸಿ"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಐಕಾನ್"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ಮುಖ ಗುರುತಿಸಲಾಗುತ್ತಿಲ್ಲ ಬದಲಿಗೆ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಬಳಸಿ."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ನಿಧಾನವಾಗಿ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ಸಮಯದಲ್ಲಿ ಪೂರ್ಣಗೊಳ್ಳುತ್ತದೆ"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ಡಾಕ್ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ದಲ್ಲಿ ಚಾರ್ಜ್ ಪೂರ್ಣಗೊಳ್ಳುತ್ತದೆ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
- <string name="user_add_user" msgid="4336657383006913022">"ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"ಹೊಸ ಬಳಕೆದಾರರು"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಷನ್ನಲ್ಲಿನ ಎಲ್ಲ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ತೆಗೆದುಹಾಕಿ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ಮತ್ತೆ ಸುಸ್ವಾಗತ, ಅತಿಥಿ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ನಿಮ್ಮ ಸೆಷನ್ ಮುಂದುವರಿಸಲು ಇಚ್ಚಿಸುವಿರಾ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ಪ್ರಾರಂಭಿಸಿ"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ಹೌದು, ಮುಂದುವರಿಸಿ"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸುವುದೇ?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"ನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಸ್ಥಾಪಿಸಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಬಹುದು."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"ಬಳಕೆದಾರರ ಮಿತಿ ತಲುಪಿದೆ"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">ನೀವು <xliff:g id="COUNT">%d</xliff:g> ಬಳಕೆದಾರರವರೆಗೆ ಸೇರಿಸಬಹುದು.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ಬಳಸಲು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"ನಿಮ್ಮ ಕಾರ್ಡ್ಗಳನ್ನು ಪಡೆಯುವಾಗ ಸಮಸ್ಯೆ ಉಂಟಾಗಿದೆ, ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ಲಾಕ್ ಸ್ಕ್ರ್ರೀನ್ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR ಕೋಡ್ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ"</string>
<string name="status_bar_work" msgid="5238641949837091056">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ಏರ್ಪ್ಲೇನ್ ಮೋಡ್"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"ನಿಮ್ಮ ಮುಂದಿನ <xliff:g id="WHEN">%1$s</xliff:g> ಅಲಾರಮ್ ಅನ್ನು ನೀವು ಆಲಿಸುವುದಿಲ್ಲ"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ಇನ್ನಷ್ಟು ನೋಡಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ಶಿಫಾರಸುಗಳು ಲೋಡ್ ಆಗುತ್ತಿವೆ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ಮಾಧ್ಯಮ"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"ಈ ಮಾಧ್ಯಮ ಸೆಶನ್ ಅನ್ನು ಮರೆಮಾಡಬೇಕೆ?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗಾಗಿ ಈ ಮಾಧ್ಯಮ ಕಂಟ್ರೋಲ್ಗಳನ್ನು ಮರೆಮಾಡಬೇಕೆ?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"ಪ್ರಸ್ತುತ ಮಾಧ್ಯಮ ಸೆಶನ್ ಅನ್ನು ಮರೆಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ವಜಾಗೊಳಿಸಿ"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ಮರೆಮಾಡಿ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ಪುನರಾರಂಭಿಸಿ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ಅವರ <xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%3$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ಇಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು <xliff:g id="DEVICENAME">%1$s</xliff:g> ಸಮೀಪಕ್ಕೆ ಹೋಗಿ"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಆಗುತ್ತಿದೆ"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ಈ ಫೋನ್ನಲ್ಲಿ ಪ್ಲೇ ಆಗುತ್ತಿದೆ"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"ಏನೋ ತಪ್ಪಾಗಿದೆ"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"ಏನೋ ತಪ್ಪಾಗಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ನಿಷ್ಕ್ರಿಯ, ಆ್ಯಪ್ ಪರಿಶೀಲಿಸಿ"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ಕಂಡುಬಂದಿಲ್ಲ"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"ನಿಯಂತ್ರಣ ಲಭ್ಯವಿಲ್ಲ"</string>
@@ -900,7 +890,7 @@
<string name="fgs_dot_content_description" msgid="2865071539464777240">"ಹೊಸ ಮಾಹಿತಿ"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ಸಕ್ರಿಯ ಆ್ಯಪ್ಗಳು"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ನಿಲ್ಲಿಸಿ"</string>
- <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ನಿಲ್ಲಿಸಿದೆ"</string>
+ <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ನಿಲ್ಲಿಸಲಾಗಿದೆ"</string>
<string name="clipboard_edit_text_copy" msgid="770856373439969178">"ನಕಲಿಸಿ"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"ನಕಲಿಸಲಾಗಿದೆ"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"<xliff:g id="APPNAME">%1$s</xliff:g> ನಿಂದ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 8705e71..cc4ecdf 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"다음번 시도에서 잘못된 패턴을 입력하면 직장 프로필 및 관련 데이터가 삭제됩니다."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"다음번 시도에서 잘못된 PIN을 입력하면 직장 프로필 및 관련 데이터가 삭제됩니다."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"다음번 시도에서 잘못된 비밀번호를 입력하면 직장 프로필 및 관련 데이터가 삭제됩니다."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"잘못된 시도 횟수가 너무 많습니다. 이 기기의 데이터가 삭제됩니다."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"잘못된 시도 횟수가 너무 많습니다. 이 사용자가 삭제됩니다."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"잘못된 시도 횟수가 너무 많습니다. 이 직장 프로필 및 관련 데이터가 삭제됩니다."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"닫기"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"지문 센서를 터치하세요."</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"지문 아이콘"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"얼굴을 인식할 수 없습니다. 대신 지문을 사용하세요."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 저속 충전 중 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> 후 충전 완료"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 충전 거치대 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> 후 충전 완료"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"사용자 전환"</string>
- <string name="user_add_user" msgid="4336657383006913022">"사용자 추가"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"신규 사용자"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"게스트를 삭제하시겠습니까?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"삭제"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"게스트 세션 진행"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"세션을 계속 진행하시겠습니까?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"다시 시작"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"계속 진행"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"신규 사용자를 추가할까요?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"추가된 새로운 사용자는 자신의 공간을 설정해야 합니다.\n\n사용자라면 누구든 다른 사용자를 위해 앱을 업데이트할 수 있습니다."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"사용자 제한 도달"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">사용자를 <xliff:g id="COUNT">%d</xliff:g>명까지 추가할 수 있습니다.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"잠금 해제하여 사용"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"카드를 가져오는 중에 문제가 발생했습니다. 나중에 다시 시도해 보세요."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"잠금 화면 설정"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR 코드 스캔"</string>
<string name="status_bar_work" msgid="5238641949837091056">"직장 프로필"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"비행기 모드"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g>에 다음 알람을 들을 수 없습니다."</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"자세히 보려면 스와이프하세요."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"추천 제어 기능 로드 중"</string>
<string name="controls_media_title" msgid="1746947284862928133">"미디어"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"이 미디어 세션을 숨기시겠습니까?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"현재 미디어 세션은 숨길 수 없습니다."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"닫기"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"숨기기"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"다시 시작"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"설정"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>에서 <xliff:g id="ARTIST_NAME">%2$s</xliff:g>의 <xliff:g id="SONG_NAME">%1$s</xliff:g> 재생 중"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"현재 기기에서 재생하려면 <xliff:g id="DEVICENAME">%1$s</xliff:g>에 더 가까이 이동합니다."</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>에서 재생 중"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"휴대전화에서 재생 중"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"문제가 발생했습니다."</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"문제가 발생했습니다. 다시 시도해 주세요."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"비활성. 앱을 확인하세요."</string>
<string name="controls_error_removed" msgid="6675638069846014366">"찾을 수 없음"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"컨트롤을 사용할 수 없음"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 6187f3a..f2807c2 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Эгер графикалык ачкычты дагы бир жолу туура эмес киргизсеңиз, жумуш профилиңиз жана андагы маалыматтын баары өчөт."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Эгер PIN кодду дагы бир жолу туура эмес киргизсеңиз, жумуш профилиңиз жана андагы маалыматтын баары өчөт."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Эгер сырсөздү дагы бир жолу туура эмес киргизсеңиз, жумуш профилиңиз жана андагы маалыматтын баары өчөт."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Өтө көп жолу жаңылдыңыз. Бул түзмөктөгү дайын-даректер өчүрүлөт."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Өтө көп жолу жаңылдыңыз. Бул колдонуучу өчүрүлөт."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Өтө көп жолу жаңылдыңыз. Бул жумуш профили жана андагы маалымат өчүрүлөт."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Жабуу"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Манжа изинин сенсорун басыңыз"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Манжа изинин сүрөтчөсү"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Жүз таанылбай жатат. Манжа изин колдонуңуз."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Жай кубатталууда • Толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> калды"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Кубаттоо догу • Толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> калды"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Колдонуучуну которуу"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Колдонуучу кошуу"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Жаңы колдонуучу"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Конокту алып саласызбы?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана маалыматтар өчүрүлөт."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Өчүрүү"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Кайтып келишиңиз менен!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансыңызды улантасызбы?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Кайра баштоо"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ооба, уланта берели"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Жаңы колдонуучу кошосузбу?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Жаңы колдонуучу кошулганда, ал өз мейкиндигин түзүп алышы керек.\n\nКолдонмолорду бир колдонуучу жаңыртканда, ал калган бардык колдонуучулар үчүн да жаңырат."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Дагы колдонуучу кошууга болбойт"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other"><xliff:g id="COUNT">%d</xliff:g> колдонуучуга чейин кошууга болот.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Колдонуу үчүн кулпусун ачыңыз"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Кыйытмаларды алууда ката кетти. Бир аздан кийин кайталап көрүңүз."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Кулпуланган экран жөндөөлөрү"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR кодун скандоо"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Жумуш профили"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Учак режими"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g> боло турган кийинки эскертмени укпайсыз"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Дагы көрүү үчүн экранды сүрүп коюңуз"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Сунуштар жүктөлүүдө"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медиа"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Бул медиа сеансы жашырылсынбы?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> үчүн бул медиафайлдарды башкаруу жашырылсынбы?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Учурдагы медиа сеансын жашыруу мүмкүн эмес."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Жабуу"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жашыруу"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Улантуу"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Жөндөөлөр"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ыры (аткаруучу: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) <xliff:g id="APP_LABEL">%3$s</xliff:g> колдонмосунан ойнотулуп жатат"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Бул жерде ойнотуу үчүн <xliff:g id="DEVICENAME">%1$s</xliff:g> түзмөгүнө жакындатыңыз"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> аркылуу ойнотулууда"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Ушул телефондо ойнотулууда"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Бир жерден ката кетти"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Бир жерден ката кетти. Кайра аракет кылыңыз."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Жигерсиз. Колдонмону текшериңиз"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Табылган жок"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Башкара албайсыз"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 3343bcf..ffdb491 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ຫາກທ່ານໃສ່ຣູບແບບຜິດໃນຄວາມພະຍາຍາມເທື່ອຕໍ່ໄປ, ໂປຣໄຟລ໌ບ່ອນເຣັດວຽກຂອງທ່ານ ແລະ ຂໍ້ມູນຂອງມັນຈະຖືກລຶບອອກ."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ຫາກທ່ານໃສ່ລະຫັດ PIN ຜິດໃນຄວາມພະຍາຍາມເທື່ອຕໍ່ໄປ, ໂປຣໄຟລ໌ບ່ອນເຣັດວຽກຂອງທ່ານ ແລະ ຂໍ້ມູນຂອງມັນຈະຖືກລຶບອອກ."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ຫາກທ່ານໃສ່ລະຫັດຜິດໃນຄວາມພະຍາຍາມເທື່ອຕໍ່ໄປ, ໂປຣໄຟລ໌ບ່ອນເຣັດວຽກຂອງທ່ານ ແລະ ຂໍ້ມູນຂອງມັນຈະຖືກລຶບອອກ."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"ພະຍາຍາມປົດລັອກບໍ່ສຳເລັດຫຼາຍເທື່ອເກີນໄປ. ອຸປະກອນນີ້ຈະຖືກລຶບຂໍ້ມູນອອກ."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"ພະຍາຍາມປົດລັອກບໍ່ສຳເລັດຫຼາຍເທື່ອເກີນໄປ. ຜູ້ໃຊ້ນີ້ຈະຖືກລຶບຂໍ້ມູນອອກ."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"ພະຍາຍາມປົດລັອກບໍ່ສຳເລັດຫຼາຍເທື່ອເກີນໄປ. ໂປຣໄຟລ໌ບ່ອນເຣັດວຽກ ແລະ ຂໍ້ມູນຂອງມັນຈະຖືກລຶບອອກ."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"ປິດໄວ້"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ແຕະໃສ່ເຊັນເຊີລາຍນິ້ວມື"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"ໄອຄອນລາຍນິ້ວມື"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ບໍ່ສາມາດຈຳແນກໜ້າໄດ້. ກະລຸນາໃຊ້ລາຍນິ້ວມືແທນ."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ກຳລັງສາກໄຟແບບຊ້າ • ຈະເຕັມໃນອີກ <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ກຳລັງສາກໄຟຜ່ານດັອກ • ຈະເຕັມໃນອີກ <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ສະຫຼັບຜູ້ໃຊ້"</string>
- <string name="user_add_user" msgid="4336657383006913022">"ເພີ່ມຜູ້ໃຊ້"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"ຜູ່ໃຊ້ໃໝ່"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ລຶບແຂກບໍ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ແອັບຯແລະຂໍ້ມູນທັງໝົດໃນເຊດຊັນນີ້ຈະຖືກລຶບອອກ."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ລຶບ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ຍິນດີຕ້ອນຮັບກັບມາ, ຜູ້ຢ້ຽມຢາມ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ທ່ານຕ້ອງການສືບຕໍ່ເຊດຊັນຂອງທ່ານບໍ່?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ເລີ່ມຕົ້ນໃຫມ່"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ຕົກລົງ, ດຳເນີນການຕໍ່"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"ເພີ່ມຜູ້ໃຊ້ໃໝ່ບໍ?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"ເມື່ອທ່ານເພີ່ມຜູ້ໃຊ້ໃໝ່, ຜູ້ໃຊ້ນັ້ນຈະຕ້ອງຕັ້ງຄ່າພື້ນທີ່ບ່ອນຈັດເກັບຂໍ້ມູນຂອງລາວ.\n\nຜູ້ໃຊ້ທຸກຄົນສາມາດອັບເດດແອັບຂອງຜູ້ໃຊ້ຄົນອື່ນທັງໝົດໄດ້."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"ຮອດຂີດຈຳກັດຜູ້ໃຊ້ແລ້ວ"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">ທ່ານສາມາດເພີ່ມໄດ້ສູງສຸດ <xliff:g id="COUNT">%d</xliff:g> ຄົນ.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ປົດລັອກເພື່ອໃຊ້"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"ເກີດບັນຫາໃນການໂຫຼດບັດຂອງທ່ານ, ກະລຸນາລອງໃໝ່ໃນພາຍຫຼັງ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ການຕັ້ງຄ່າໜ້າຈໍລັອກ"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"ສະແກນລະຫັດ QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ໂໝດເຮືອບິນ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"ທ່ານຈະບໍ່ໄດ້ຍິນສຽງໂມງປ <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ປັດເພື່ອເບິ່ງເພີ່ມເຕີມ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ກຳລັງໂຫຼດຄຳແນະນຳ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ມີເດຍ"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"ເຊື່ອງເຊດຊັນມີເດຍນີ້ບໍ?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"ບໍ່ສາມາດເຊື່ອງເຊດຊັນມີເດຍປັດຈຸບັນໄດ້."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ປິດໄວ້"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ເຊື່ອງ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ສືບຕໍ່"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ການຕັ້ງຄ່າ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ໂດຍ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ກຳລັງຫຼິ້ນຈາກ <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ກະລຸນາຍ້າຍເຂົ້າໃກ້ <xliff:g id="DEVICENAME">%1$s</xliff:g> ເພື່ອຫຼິ້ນຢູ່ບ່ອນນີ້"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"ກຳລັງຫຼິ້ນຢູ່ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ກຳລັງຫຼິ້ນຢູ່ໂທລະສັບນີ້"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"ມີບາງຢ່າງຜິດພາດເກີດຂຶ້ນ"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"ມີບາງຢ່າງຜິດພາດເກີດຂຶ້ນ. ກະລຸນາລອງໃໝ່."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ບໍ່ເຮັດວຽກ, ກະລຸນາກວດສອບແອັບ"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ບໍ່ພົບ"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"ບໍ່ສາມາດໃຊ້ການຄວບຄຸມໄດ້"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 547d250..99395909 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jei kitu bandymu nupiešite netinkamą atrakinimo piešinį, darbo profilis ir jo duomenys bus ištrinti."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jei kitu bandymu įvesite netinkamą PIN kodą, darbo profilis ir jo duomenys bus ištrinti."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Jei kitu bandymu įvesite netinkamą slaptažodį, darbo profilis ir jo duomenys bus ištrinti."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Per daug netinkamų bandymų. Šio įrenginio duomenys bus ištrinti."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Per daug netinkamų bandymų. Šis naudotojas bus ištrintas."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Per daug netinkamų bandymų. Šis darbo profilis ir jo duomenys bus ištrinti."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Atsisakyti"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Palieskite piršto antspaudo jutiklį"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Piršto antspaudo piktograma"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Veidas neatpažintas. Naudokite kontrolinį kodą."</string>
@@ -327,17 +323,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Lėtai įkraunama • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> iki visiško įkrovimo"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Įkraunama doke • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> iki visiško įkrovimo"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Perjungti naudotoją"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Pridėti naudotoją"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Naujas naudotojas"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Pašalinti svečią?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bus ištrintos visos šios sesijos programos ir duomenys."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Pašalinti"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Sveiki sugrįžę, svety!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Ar norite tęsti sesiją?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Pradėti iš naujo"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Taip, tęsti"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Pridėti naują naudotoją?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Kai pridedate naują naudotoją, šis asmuo turi nustatyti savo erdvę.\n\nBet kuris naudotojas gali atnaujinti visų kitų naudotojų programas."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Pasiekta naudotojų riba"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Galite pridėti iki <xliff:g id="COUNT">%d</xliff:g> naudotojo.</item>
@@ -465,8 +456,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Atrakinti, kad būtų galima naudoti"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Gaunant korteles kilo problema, bandykite dar kartą vėliau"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Užrakinimo ekrano nustatymai"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR kodo nuskaitymas"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Darbo profilis"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lėktuvo režimas"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Negirdėsite kito signalo <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -797,9 +787,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Perbraukite, kad peržiūrėtumėte daugiau"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Įkeliamos rekomendacijos"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medija"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Slėpti šį medijos seansą?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Dabartinio medijos seanso negalima paslėpti."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Atsisakyti"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Slėpti"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Tęsti"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nustatymai"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> – „<xliff:g id="SONG_NAME">%1$s</xliff:g>“ leidžiama iš „<xliff:g id="APP_LABEL">%3$s</xliff:g>“"</string>
@@ -817,7 +808,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Perkelkite arčiau „<xliff:g id="DEVICENAME">%1$s</xliff:g>“, kad būtų galima leisti čia"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Leidžiama įrenginyje „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Leidžiama šiame telefone"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Kažkas ne taip"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Kažkas ne taip. Bandykite dar kartą."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktyvu, patikrinkite progr."</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nerasta"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Valdiklis nepasiekiamas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 5e79f75..3ac9579 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -114,7 +114,7 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"Tālruņa numurs"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Balss palīgs"</string>
<string name="accessibility_wallet_button" msgid="1458258783460555507">"Maks"</string>
- <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Ātrās atbildes koda skeneris"</string>
+ <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Kvadrātkoda skeneris"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"Atbloķēt"</string>
<string name="accessibility_lock_icon" msgid="661492842417875775">"Ierīce ir bloķēta"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Sejas skenēšana"</string>
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ja nākamajā mēģinājumā ievadīsiet nepareizu kombināciju, jūsu darba profils un ar to saistītie dati tiks dzēsti."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ja nākamajā mēģinājumā ievadīsiet nepareizu PIN, jūsu darba profils un ar to saistītie dati tiks dzēsti."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ja nākamajā mēģinājumā ievadīsiet nepareizu paroli, jūsu darba profils un ar to saistītie dati tiks dzēsti."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Pārāk daudz neveiksmīgu mēģinājumu. Dati šajā ierīcē tiks dzēsti."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Pārāk daudz neveiksmīgu mēģinājumu. Šis lietotājs tiks dzēsts."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Pārāk daudz neveiksmīgu mēģinājumu. Šis darba profils un ar to saistītie dati tiks dzēsti."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Nerādīt"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Pieskarieties pirksta nospieduma sensoram"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Pirksta nospieduma ikona"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Nevar atpazīt seju. Lietojiet pirksta nospiedumu."</string>
@@ -325,17 +321,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Lēnā uzlāde • Laiks līdz pilnai uzlādei: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Notiek uzlāde dokā • Līdz pilnai uzlādei atlicis: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mainīt lietotāju"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Lietotāja pievienošana"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Jauns lietotājs"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vai noņemt viesi?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tiks dzēstas visas šīs sesijas lietotnes un dati."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Noņemt"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Laipni lūdzam atpakaļ, viesi!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vai vēlaties turpināt savu sesiju?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Sākt no sākuma"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Jā, turpināt"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Vai pievienot jaunu lietotāju?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Kad pievienosiet jaunu lietotāju, viņam būs jāizveido savs profils.\n\nIkviens lietotājs var atjaunināt lietotnes citu lietotāju vietā."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Sasniegts lietotāju ierobežojums"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="zero">Varat pievienot ne vairāk kā <xliff:g id="COUNT">%d</xliff:g> lietotājus.</item>
@@ -462,8 +453,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lai izmantotu, atbloķējiet ekrānu"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Ienesot jūsu kartes, radās problēma. Lūdzu, vēlāk mēģiniet vēlreiz."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Bloķēšanas ekrāna iestatījumi"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Kvadrātkoda skenēšana"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Darba profils"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Lidojuma režīms"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nākamais signāls (<xliff:g id="WHEN">%1$s</xliff:g>) netiks atskaņots."</string>
@@ -791,9 +781,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Velciet, lai skatītu citus vienumus"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Notiek ieteikumu ielāde"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multivide"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Vai paslēpt šo multivides sesiju?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Pašreizējo multivides sesiju nevar paslēpt."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Nerādīt"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Paslēpt"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Atsākt"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Iestatījumi"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tiek atskaņots fails “<xliff:g id="SONG_NAME">%1$s</xliff:g>” (izpildītājs: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) no lietotnes <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
@@ -811,7 +802,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Pārvietojieties tuvāk ierīcei “<xliff:g id="DEVICENAME">%1$s</xliff:g>”, lai atskaņotu šeit"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Notiek atskaņošana ierīcē <xliff:g id="DEVICENAME">%1$s</xliff:g>."</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Notiek atskaņošana šajā tālrunī"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Radās problēma"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Radās kļūda. Mēģiniet vēlreiz."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktīva, pārbaudiet lietotni"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Netika atrasta"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Vadīkla nav pieejama"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 0bde00b..289fcdf 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ако внесете погрешна шема при следниот обид, работниот профил и неговите податоци ќе се избришат."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ако внесете погрешен PIN при следниот обид, работниот профил и неговите податоци ќе се избришат."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ако внесете погрешна лозинка при следниот обид, работниот профил и неговите податоци ќе се избришат."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Премногу погрешни обиди. Податоците на уредов ќе се избришат."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Премногу погрешни обиди. Корисникот ќе се избрише."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Премногу погрешни обиди. Работниот профил и неговите податоци ќе се избришат."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Отфрли"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Допрете го сензорот за отпечатоци"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Икона за отпечаток"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Не се препознава ликот. Користете отпечаток."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Се полни бавно • Полна по <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Се полни на док • Полн за <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Промени го корисникот"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Додај корисник"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Нов корисник"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Да се отстрани гостинот?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијата ќе се избришат."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Отстрани"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Добре дојде пак, гостине!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Дали сакате да продолжите со сесијата?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни одново"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продолжи"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Да се додаде нов корисник?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Кога додавате нов корисник, тоа лице треба да го постави својот простор.\n\nСекој корисник може да ажурира апликации за сите други корисници."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнато ограничување на корисник"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Може да додадете најмногу <xliff:g id="COUNT">%d</xliff:g> корисник.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Отклучете за да користите"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Имаше проблем при преземањето на картичките. Обидете се повторно подоцна"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Поставки за заклучен екран"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Скенирајте QR-код"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Работен профил"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Авионски режим"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Нема да го слушнете следниот аларм <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Повлечете за да видите повеќе"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Се вчитуваат препораки"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Аудиовизуелни содржини"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Да се сокрие аудиовизуелнава сесија?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Да се сокрие контролоров за аудиовизуелни содржини за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Аудиовизуелнава сесија не може да се сокрие."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Отфрли"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сокриј"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Продолжи"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Поставки"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> од <xliff:g id="ARTIST_NAME">%2$s</xliff:g> е пуштено на <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближете се до <xliff:g id="DEVICENAME">%1$s</xliff:g> за да пуштите тука"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Пуштено на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Пуштено на овој телефон"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Нешто тргна наопаку"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Нешто не е во ред. Обидете се повторно."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивна, провери апликација"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Не е најдено"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е достапна"</string>
@@ -899,7 +889,7 @@
</plurals>
<string name="fgs_dot_content_description" msgid="2865071539464777240">"Нови информации"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активни апликации"</string>
- <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Крај"</string>
+ <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"Запри"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"Запрено"</string>
<string name="clipboard_edit_text_copy" msgid="770856373439969178">"Копирај"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"Копирано"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index e7ccae0..c08c1bc 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"അടുത്ത തവണയും നിങ്ങൾ തെറ്റായ പാറ്റേൺ നൽകിയാൽ, നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലും അതിന്റെ ഡാറ്റയും ഇല്ലാതാക്കപ്പെടും."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"അടുത്ത തവണയും നിങ്ങൾ തെറ്റായ പിൻ നൽകിയാൽ, നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലും അതിന്റെ ഡാറ്റയും ഇല്ലാതാക്കപ്പെടും."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"അടുത്ത തവണയും നിങ്ങൾ തെറ്റായ പാസ്വേഡ് നൽകിയാൽ, നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലും അതിന്റെ ഡാറ്റയും ഇല്ലാതാക്കപ്പെടും."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"ഒരുപാട് തെറ്റായ ശ്രമങ്ങൾ. ഈ ഉപകരണത്തിലെ ഡാറ്റ ഇല്ലാതാക്കപ്പെടും."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"ഒരുപാട് തെറ്റായ ശ്രമങ്ങൾ. ഈ ഉപയോക്താവ് ഇല്ലാതാക്കപ്പെടും."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"ഒരുപാട് തെറ്റായ ശ്രമങ്ങൾ. ഈ ഔദ്യോഗിക പ്രൊഫൈലും അതിന്റെ ഡാറ്റയും ഇല്ലാതാക്കപ്പെടും."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"ഡിസ്മിസ് ചെയ്യുക"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ഫിംഗർപ്രിന്റ് സെൻസർ സ്പർശിക്കുക"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"ഫിംഗർപ്രിന്റ് ഐക്കൺ"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"മുഖം തിരിച്ചറിയാനായില്ല. പകരം ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കൂ."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • പതുക്കെ ചാർജ് ചെയ്യുന്നു • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-ൽ പൂർത്തിയാകും"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ചാർജിംഗ് ഡോക്ക് • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-ൽ പൂർത്തിയാകും"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ഉപയോക്താവ് മാറുക"</string>
- <string name="user_add_user" msgid="4336657383006913022">"ഉപയോക്താവിനെ ചേര്ക്കുക"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"പുതിയ ഉപയോക്താവ്"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"അതിഥിയെ നീക്കംചെയ്യണോ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"നീക്കംചെയ്യുക"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"അതിഥി, വീണ്ടും സ്വാഗതം!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"നിങ്ങളുടെ സെഷൻ തുടരണോ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"പുനരാംരംഭിക്കുക"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"അതെ, തുടരുക"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"പുതിയ ഉപയോക്താവിനെ ചേർക്കണോ?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"നിങ്ങൾ പുതിയൊരു ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തിക്ക് അവരുടെ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\nമറ്റ് എല്ലാ ഉപയോക്താക്കൾക്കുമായി ഏതൊരു ഉപയോക്താവിനും ആപ്പുകൾ അപ്ഡേറ്റ് ചെയ്യാനാവും."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"ഉപയോക്തൃ പരിധി എത്തി"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">നിങ്ങൾക്ക് <xliff:g id="COUNT">%d</xliff:g> ഉപയോക്താക്കളെ വരെ ചേർക്കാനാവും.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ഉപയോഗിക്കാൻ അൺലോക്ക് ചെയ്യുക"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"നിങ്ങളുടെ കാർഡുകൾ ലഭ്യമാക്കുന്നതിൽ ഒരു പ്രശ്നമുണ്ടായി, പിന്നീട് വീണ്ടും ശ്രമിക്കുക"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ലോക്ക് സ്ക്രീൻ ക്രമീകരണം"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR കോഡ് സ്കാൻ ചെയ്യുക"</string>
<string name="status_bar_work" msgid="5238641949837091056">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ഫ്ലൈറ്റ് മോഡ്"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g>-നുള്ള നിങ്ങളുടെ അടുത്ത അലാറം കേൾക്കില്ല"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"കൂടുതൽ കാണാൻ സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"നിർദ്ദേശങ്ങൾ ലോഡ് ചെയ്യുന്നു"</string>
<string name="controls_media_title" msgid="1746947284862928133">"മീഡിയ"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"ഈ മീഡിയ സെഷൻ മറയ്ക്കണോ?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"നിലവിലെ മീഡിയ സെഷൻ മറയ്ക്കാനാകില്ല."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ഡിസ്മിസ് ചെയ്യുക"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"മറയ്ക്കുക"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"പുനരാരംഭിക്കുക"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ക്രമീകരണം"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> എന്ന ആർട്ടിസ്റ്റിന്റെ <xliff:g id="SONG_NAME">%1$s</xliff:g> എന്ന ഗാനം <xliff:g id="APP_LABEL">%3$s</xliff:g> ആപ്പിൽ പ്ലേ ചെയ്യുന്നു"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ഇവിടെ പ്ലേ ചെയ്യാൻ <xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിന് അടുത്തേക്ക് നീക്കുക"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിൽ പ്ലേ ചെയ്യുന്നു"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ഈ ഫോണിൽ പ്ലേ ചെയ്യുന്നു"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"എന്തോ കുഴപ്പമുണ്ടായി"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"എന്തോ കുഴപ്പമുണ്ടായി. വീണ്ടും ശ്രമിക്കുക."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"നിഷ്ക്രിയം, ആപ്പ് പരിശോധിക്കൂ"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"കണ്ടെത്തിയില്ല"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"നിയന്ത്രണം ലഭ്യമല്ല"</string>
@@ -894,8 +885,8 @@
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ടൈൽ ചേർക്കരുത്"</string>
<string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ഉപയോക്താവിനെ തിരഞ്ഞെടുക്കൂ"</string>
<plurals name="fgs_manager_footer_label" formatted="false" msgid="9091110396713032871">
- <item quantity="other">സജീവമായ <xliff:g id="COUNT_1">%s</xliff:g> ആപ്പുകൾ</item>
- <item quantity="one">സജീവമായ <xliff:g id="COUNT_0">%s</xliff:g> ആപ്പ്</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> സജീവ ആപ്പുകൾ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> സജീവ ആപ്പ്</item>
</plurals>
<string name="fgs_dot_content_description" msgid="2865071539464777240">"പുതിയ വിവരങ്ങൾ"</string>
<string name="fgs_manager_dialog_title" msgid="5879184257257718677">"സജീവമായ ആപ്പുകൾ"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index b136674..30a45ed 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Та дараагийн оролдлогоор буруу хээ оруулбал таны ажлын профайлыг өгөгдөлтэй нь цуг устгах болно."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Та дараагийн оролдлогоор буруу ПИН оруулбал таны ажлын профайлыг өгөгдөлтэй нь цуг устгах болно."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Та дараагийн оролдлогоор буруу нууц үг оруулбал таны ажлын профайлыг өгөгдөлтэй нь цуг устгах болно."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Түгжээг хэт олон удаа буруу оруулсан тул энэ төхөөрөмжийн өгөгдлийг устгах болно."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Түгжээг хэт олон удаа буруу оруулсан тул энэ хэрэглэгчийг устгах болно."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Түгжээг хэт олон удаа буруу оруулсан тул энэ ажлын профайл, түүний өгөгдлийн устгах болно."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Хаах"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Хурууны хээ мэдрэгчид хүрэх"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Хурууны хээний дүрс тэмдэг"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Царай таних боломжгүй. Оронд нь хурууны хээ ашигла"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Удаан цэнэглэж байна • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-н дараа дүүрнэ"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Цэнэглэх холбогч • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-н дараа дүүрнэ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Хэрэглэгчийг сэлгэх"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Хэрэглэгч нэмэх"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Шинэ хэрэглэгч"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Зочныг хасах уу?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ харилцан үйлдлийн бүх апп болон дата устах болно."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Хасах"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Эргэн тавтай морилно уу!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Та үргэлжлүүлэхийг хүсэж байна уу?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Дахин эхлүүлэх"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Тийм, үргэлжлүүлэх"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Шинэ хэрэглэгч нэмэх үү?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Та шинэ хэрэглэгч нэмбэл тухайн хүн өөрийн профайлыг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бүх хэрэглэгчийн аппуудыг шинэчлэх боломжтой."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Хэрэглэгчийн хязгаарт хүрсэн"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Та <xliff:g id="COUNT">%d</xliff:g> хүртэлх хэрэглэгч нэмэх боломжтой.</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Илүү ихийг харахын тулд шударна уу"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Зөвлөмжүүдийг ачаалж байна"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медиа"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Энэ медиа харилцан үйлдлийг нуух уу?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Энэ медиа хяналтыг <xliff:g id="APP_NAME">%1$s</xliff:g>-д нуух уу?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Одоогийн медиа харилцан үйлдлийг нуух боломжгүй."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Хаах"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Нуух"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Үргэлжлүүлэх"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Тохиргоо"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> дээр тоглуулж буй <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-н <xliff:g id="SONG_NAME">%1$s</xliff:g>"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Энд тоглуулахын тулд <xliff:g id="DEVICENAME">%1$s</xliff:g>-д ойртоно уу"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> дээр тоглуулж байна"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Энэ утсан дээр тоглуулж байна"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Алдаа гарлаа"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Алдаа гарлаа. Дахин оролдоно уу."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Идэвхгүй байна, аппыг шалгана уу"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Олдсонгүй"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Хяналт боломжгүй байна"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 721368a..6352e21 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"तुम्ही पुढील प्रयत्नात चुकीचा पॅटर्न एंटर केल्यास, तुमची कार्य प्रोफाइल आणि तिचा डेटा हटवला जाईल."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"तुम्ही पुढील प्रयत्नात चुकीचा पिन एंटर केल्यास, तुमची कार्य प्रोफाइल आणि तिचा डेटा हटवला जाईल."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"तुम्ही पुढील प्रयत्नात चुकीचा पासवर्ड एंटर केल्यास, तुमची कार्य प्रोफाइल आणि तिचा डेटा हटवला जाईल."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"बरेच चुकीचे प्रयत्न. या डिव्हाइसचा डेटा हटवला जाईल."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"बरेच चुकीचे प्रयत्न. हा वापरकर्ता हटवला जाईल."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"बरेच चुकीचे प्रयत्न. ही कार्य प्रोफाइल आणि त्यामधील डेटा हटवला जाईल."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"डिसमिस करा"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"फिंगरप्रिंट सेन्सरला स्पर्श करा"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"फिंगरप्रिंट आयकन"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"चेहरा ओळखू शकत नाही. त्याऐवजी फिंगरप्रिंट वापरा."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • हळू चार्ज होत आहे • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> मध्ये पूर्ण होईल"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • चार्जिंग डॉक • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> मध्ये पूर्ण होईल"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"वापरकर्ता स्विच करा"</string>
- <string name="user_add_user" msgid="4336657383006913022">"वापरकर्ता जोडा"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"नवीन वापरकर्ता"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथी काढायचे?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अॅप्स आणि डेटा हटवला जाईल."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"काढा"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"अतिथी, तुमचे पुन्हा स्वागत आहे!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"तुम्ही तुमचे सत्र सुरू ठेवू इच्छिता?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"येथून सुरू करा"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"होय, सुरू ठेवा"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"नवीन वापरकर्ता जोडायचा?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"तुम्ही एक नवीन वापरकर्ता जोडता तेव्हा, त्या व्यक्तीने त्यांचे स्थान सेट करणे आवश्यक असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अॅप्स अपडेट करू शकतो."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"वापरकर्ता मर्यादा गाठली"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">तुम्ही <xliff:g id="COUNT">%d</xliff:g> वापरकर्त्यांपर्यंत जोडू शकता.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"वापरण्यासाठी अनलॉक करा"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"तुमची कार्ड मिळवताना समस्या आली, कृपया नंतर पुन्हा प्रयत्न करा"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"लॉक स्क्रीन सेटिंग्ज"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR कोड स्कॅन करा"</string>
<string name="status_bar_work" msgid="5238641949837091056">"कार्य प्रोफाईल"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"विमान मोड"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"तुम्ही तुमचा <xliff:g id="WHEN">%1$s</xliff:g> वाजता होणारा पुढील अलार्म ऐकणार नाही"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"अधिक पाहण्यासाठी स्वाइप करा"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"शिफारशी लोड करत आहे"</string>
<string name="controls_media_title" msgid="1746947284862928133">"मीडिया"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"हे मीडिया सेशन लपवायचे आहे का?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी हा मीडिया नियंत्रक लपवायचा आहे का?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"सध्याचे मीडिया सेशन लपवू शकत नाही."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"डिसमिस करा"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"लपवा"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"पुन्हा सुरू करा"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग्ज"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> मध्ये <xliff:g id="ARTIST_NAME">%2$s</xliff:g> चे <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले होत आहे"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"येथे प्ले करण्यासाठी <xliff:g id="DEVICENAME">%1$s</xliff:g> च्या जवळ जा"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> वर प्ले केला जात आहे"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"या फोनवर प्ले होत आहे"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"काहीतरी चूक झाली"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"काहीतरी चूक झाली. पुन्हा प्रयत्न करा."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय, ॲप तपासा"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"आढळले नाही"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"नियंत्रण उपलब्ध नाही"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index b34a312..f0e48d4 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jika anda memasukkan corak yang salah pada percubaan seterusnya, profil kerja anda dan data profil itu akan dipadamkan."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jika anda memasukkan PIN yang salah pada percubaan seterusnya, profil kerja anda dan data profil itu akan dipadamkan."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Jika anda memasukkan kata laluan yang salah pada percubaan seterusnya, profil kerja anda dan data profil itu akan dipadamkan."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Terlalu banyak percubaan yang salah. Data peranti ini akan dipadamkan."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Terlalu banyak percubaan yang salah. Pengguna ini akan dipadamkan."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Terlalu banyak percubaan yang salah. Profil kerja ini dan data profil itu akan dipadamkan."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Ketepikan"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Sentuh penderia cap jari"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikon cap jari"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Tidak mengenali wajah. Gunakan cap jari."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengecas dengan perlahan • Penuh dalam masa <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengecas dengan Dok • Penuh dalam masa <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Tukar pengguna"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Tambah pengguna"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Pengguna baharu"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Alih keluar tetamu?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alih keluar"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat kembali, tetamu!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Adakah anda ingin meneruskan sesi anda?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulakan semula"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ya, teruskan"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Tambah pengguna baharu?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Apabila anda menambah pengguna baharu, orang itu perlu menyediakan ruang mereka.\n\nMana-mana pengguna boleh mengemas kini apl untuk semua pengguna lain."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Had pengguna dicapai"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Anda boleh menambah sehingga <xliff:g id="COUNT">%d</xliff:g> pengguna.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Buka kunci untuk menggunakan"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Terdapat masalah sewaktu mendapatkan kad anda. Sila cuba sebentar lagi"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Tetapan skrin kunci"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Imbas kod QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil kerja"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mod pesawat"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Anda tidak akan mendengar penggera yang seterusnya <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Leret untuk melihat selanjutnya"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Memuatkan cadangan"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Sembunyikan sesi media ini?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Sesi media semasa tidak dapat disembunyikan."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Tolak"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sembunyikan"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Sambung semula"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Tetapan"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> dimainkan daripada <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Dekatkan dengan <xliff:g id="DEVICENAME">%1$s</xliff:g> untuk bermain di sini"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Dimainkan pada <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Dimainkan pada telefon ini"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Ralat telah berlaku"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Kesilapan telah berlaku. Cuba lagi."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Tidak aktif, semak apl"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kawalan tidak tersedia"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index b1b2ceb9b..8a0250e 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"မှားယွင်းသည့် ပုံစံကို နောက်တစ်ကြိမ်ထည့်သွင်းပါက သင်၏အလုပ်ပရိုဖိုင်နှင့် ၎င်း၏ ဒေတာများကို ဖျက်လိုက်ပါမည်။"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"မှားယွင်းသည့် ပင်နံပါတ်ကို နောက်တစ်ကြိမ်ထည့်သွင်းပါက သင်၏အလုပ်ပရိုဖိုင်နှင့် ၎င်း၏ဒေတာများကို ဖျက်လိုက်ပါမည်။"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"မှားယွင်းသည့် စကားဝှက်ကို နောက်တစ်ကြိမ်ထည့်သွင်းပါက သင်၏အလုပ်ပရိုဖိုင်နှင့် ၎င်း၏ ဒေတာများကို ဖျက်လိုက်ပါမည်။"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"မှားယွင်းသည့် အကြိမ်ရေ အလွန်များနေပါပြီ။ ဤစက်၏ ဒေတာကို ဖျက်လိုက်ပါမည်။"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"မှားယွင်းသည့် အကြိမ်ရေ အလွန်များနေပါပြီ။ ဤအသုံးပြုသူကို ဖျက်လိုက်ပါမည်။"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"မှားယွင်းသည့် အကြိမ်ရေ အလွန်များနေပါပြီ။ ဤအလုပ်ပရိုဖိုင်နှင့် ၎င်း၏ ဒေတာကို ဖျက်လိုက်ပါမည်။"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"ပယ်ရန်"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"လက်ဗွေအာရုံခံကိရိယာကို တို့ပါ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"လက်ဗွေ သင်္ကေတ"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"မျက်နှာကို မမှတ်မိပါ။ လက်ဗွေကို အစားထိုးသုံးပါ။"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • နှေးကွေးစွာ အားသွင်းနေသည် • အားပြည့်ရန် <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> လိုသည်"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • အားသွင်းအထိုင် • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> တွင် ပြည့်မည်"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"အသုံးပြုသူကို ပြောင်းလဲရန်"</string>
- <string name="user_add_user" msgid="4336657383006913022">"အသုံးပြုသူ ထည့်ရန်"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"အသုံးပြုသူ အသစ်"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ဧည့်သည်ကို ဖယ်မလား။"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ဖယ်ထုတ်ပါ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ဧည့်သည်ကို ပြန်လည် ကြိုဆိုပါသည်။"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"သင်၏ စက်ရှင်ကို ဆက်လုပ်လိုပါသလား။"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ပြန်စပါ"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ဆက်လုပ်ပါ"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"အသုံးပြုသူအသစ်ကို ထည့်မလား။"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"သင်ထည့်လိုက်သော အသုံးပြုသူအသစ်သည် ၎င်း၏နေရာကို သတ်မှတ်စီစဉ်ရန် လိုအပ်သည်။\n\nမည်သည့်အသုံးပြုသူမဆို ကျန်သူများအားလုံးအတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်ပေးနိုင်သည်။"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"အသုံးပြုသူ အကန့်အသတ် ပြည့်သွားပါပြီ"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">အသုံးပြုသူ <xliff:g id="COUNT">%d</xliff:g> ဦးအထိ ထည့်နိုင်သည်။</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"သုံးရန် လော့ခ်ဖွင့်ပါ"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"သင်၏ကတ်များ ရယူရာတွင် ပြဿနာရှိနေသည်၊ နောက်မှ ထပ်စမ်းကြည့်ပါ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"လော့ခ်မျက်နှာပြင် ဆက်တင်များ"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR ကုဒ် စကင်ဖတ်ခြင်း"</string>
<string name="status_bar_work" msgid="5238641949837091056">"အလုပ် ပရိုဖိုင်"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"လေယာဉ်ပျံမုဒ်"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g> ၌သင့်နောက်ထပ် နှိုးစက်ကို ကြားမည်မဟုတ်ပါ"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ပိုကြည့်ရန် ပွတ်ဆွဲပါ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"အကြံပြုချက်များ ဖွင့်နေသည်"</string>
<string name="controls_media_title" msgid="1746947284862928133">"မီဒီယာ"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"ဤမီဒီယာစက်ရှင်ကို ဝှက်မလား။"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"လက်ရှိ မီဒီယာစက်ရှင်ကို ဝှက်၍မရပါ။"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ပယ်ရန်"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ဖျောက်ထားမည်"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ဆက်လုပ်ရန်"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ဆက်တင်များ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ၏ <xliff:g id="SONG_NAME">%1$s</xliff:g> ကို <xliff:g id="APP_LABEL">%3$s</xliff:g> တွင် ဖွင့်ထားသည်"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ဤနေရာတွင်ဖွင့်ရန် <xliff:g id="DEVICENAME">%1$s</xliff:g> အနီးသို့တိုးပါ"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> တွင် ဖွင့်နေသည်"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ဤဖုန်းတွင် ဖွင့်နေသည်"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"တစ်ခုခုမှားသွားသည်"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"တစ်ခုခုမှားသွားသည်။ ထပ်စမ်းကြည့်ပါ။"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ရပ်နေသည်၊ အက်ပ်ကို စစ်ဆေးပါ"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"မတွေ့ပါ"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"ထိန်းချုပ်မှု မရနိုင်ပါ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 745454c..bbceca7 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Hvis du oppgir feil mønster på neste forsøk, slettes jobbprofilen din og tilknyttede data."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Hvis du skriver inn feil PIN-kode på neste forsøk, slettes jobbprofilen din og tilknyttede data."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Hvis du skriver inn feil passord på neste forsøk, slettes jobbprofilen din og tilknyttede data."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"For mange mislykkede forsøk. Dataene på denne enheten blir slettet."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"For mange mislykkede forsøk. Denne brukeren blir slettet."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"For mange mislykkede forsøk. Denne jobbprofilen og tilknyttede data blir slettet."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Avvis"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Trykk på fingeravtrykkssensoren"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikon for fingeravtrykk"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ansiktet gjenkjennes ikke. Bruk fingeravtrykk."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Lader sakte • Fulladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ladedokk • Fulladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Bytt bruker"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Legg til brukere"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Ny bruker"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vil du fjerne gjesten?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle appene og all informasjon i denne økten slettes."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkommen tilbake, gjest!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsette økten?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start på nytt"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsett"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Vil du legge til en ny bruker?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Når du legger til en ny bruker, må vedkommende konfigurere sitt eget område.\n\nAlle brukere kan oppdatere apper for alle andre brukere."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Grensen for antall brukere er nådd"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Du kan legge til opptil <xliff:g id="COUNT">%d</xliff:g> brukere.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lås opp for å bruke"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Det oppsto et problem med henting av kortene. Prøv igjen senere"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Innstillinger for låseskjermen"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skann QR-koden"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Work-profil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flymodus"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Du hører ikke neste innstilte alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Sveip for å se flere"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Laster inn anbefalinger"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medier"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Vil du skjule denne medieøkten?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Den nåværende medieøkten kan ikke skjules."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Lukk"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skjul"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Gjenoppta"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Innstillinger"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> av <xliff:g id="ARTIST_NAME">%2$s</xliff:g> spilles av fra <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Flytt deg nærmere <xliff:g id="DEVICENAME">%1$s</xliff:g> for å spille av her"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Spilles av på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Spilles av på denne telefonen"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Noe gikk galt"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Noe gikk galt. Prøv på nytt."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Sjekk appen"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ikke funnet"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrollen er utilgjengelig"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index bfe29aa..a7879e6 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"तपाईंले अर्को पटक पनि गलत ढाँचा प्रविष्टि गर्नुभयो भने यो कार्य प्रोफाइल र त्यहाँको डेटा मेटाइने छ।"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"तपाईंले अर्को पटक पनि गलत PIN प्रविष्टि गर्नुभयो भने तपाईंको कार्य प्रोफाइल र त्यहाँको डेटा मेटाइने छ।"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"तपाईंले अर्को पटक पनि गलत पासवर्ड प्रविष्टि गर्नुभयो भने तपाईंको कार्य प्रोफाइल र त्यहाँको डेटा मेटाइने छ।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"अनलक गर्ने अत्यधिक गलत प्रयासहरू भए। यो डिभाइसको डेटा मेटाइने छ।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"अनलक गर्ने अत्यधिक गलत प्रयासहरू भए। यो प्रयोगकर्तालाई हटाइने छ।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"अनलक गर्ने अत्यधिक गलत प्रयासहरू भए। यो कार्यलयको प्रोफाइल र यसको डेटा मेटाइने छ।"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"हटाउनुहोस्"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"फिंगरप्रिन्ट सेन्सरमा छुनुहोस्"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"फिंगरप्रिन्ट जनाउने आइकन"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"अनुहार पहिचान गर्न सकिएन। बरु फिंगरप्रिन्ट प्रयोग गर्नुहोस्।"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • बिस्तारै चार्ज हुँदै छ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> मा पूरै चार्ज हुन्छ"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • डक चार्ज हुँदै छ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> मा पूरै चार्ज हुन्छ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"प्रयोगकर्ता फेर्नुहोस्"</string>
- <string name="user_add_user" msgid="4336657383006913022">"प्रयोगकर्ता थप्नुहोस्"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"नयाँ प्रयोगकर्ता"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथि हटाउने हो?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यो सत्रमा भएका सबै एपहरू र डेटा मेटाइने छ।"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"हटाउनुहोस्"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"तपाईंलाई फेरि स्वागत छ, अतिथि"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"तपाईं आफ्नो सत्र जारी गर्न चाहनुहुन्छ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"सुरु गर्नुहोस्"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हो, जारी राख्नुहोस्"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"नयाँ प्रयोगकर्ता थप्ने हो?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"जब तपाईँले नयाँ प्रयोगकर्ता थप्नुहुन्छ, त्यस प्रयोगकर्ताले आफ्नो स्थान स्थापना गर्न पर्ने छ।\n\nसबै प्रयोगकर्ताले अरू प्रयोगकर्ताका एपहरू अपडेट गर्न सक्छन्।"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"प्रयोगकर्ताको सीमा पुग्यो"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">तपाईं अधिकतम <xliff:g id="COUNT">%d</xliff:g> प्रयोगहरू मात्र थप्न सक्नुहुन्छ।</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"थप हेर्न स्वाइप गर्नुहोस्"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"सिफारिसहरू लोड गर्दै"</string>
<string name="controls_media_title" msgid="1746947284862928133">"मिडिया"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"यो मिडिया सत्र लुकाउने हो?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> का हकमा यो मिडिया कन्ट्रोल लुकाउने हो?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"हालको मिडिया सत्र लुकाउन मिल्दैन।"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"हटाउनुहोस्"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"लुकाउनुहोस्"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"सुचारु गर्नुहोस्"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिङ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> को <xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%3$s</xliff:g> मा बज्दै छ"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"तपाईं यहाँ प्ले गर्न चाहनुहुन्छ भने आफ्नो डिभाइसलाई <xliff:g id="DEVICENAME">%1$s</xliff:g> नजिकै लैजानुहोस्"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> मा प्ले गरिँदै छ"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"यो फोनमा प्ले गरिँदै छ"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"केही चिज गडबड भयो"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"केही चिज गडबड भयो। फेरि प्रयास गर्नुहोस्।"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, एप जाँच गर्नु…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"फेला परेन"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"नियन्त्रण उपलब्ध छैन"</string>
diff --git a/packages/SystemUI/res/values-night/styles.xml b/packages/SystemUI/res/values-night/styles.xml
index f7261e7..cf49728 100644
--- a/packages/SystemUI/res/values-night/styles.xml
+++ b/packages/SystemUI/res/values-night/styles.xml
@@ -51,6 +51,10 @@
<item name="overlayButtonTextColor">?android:attr/textColorPrimaryInverse</item>
</style>
+ <style name="EditTextActivityButton" parent="@android:style/Widget.DeviceDefault.Button.Colored">
+ <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+ </style>
+
<style name="Theme.PeopleTileConfigActivity" parent="@style/Theme.SystemUI">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 0f49b75..46e190e 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Als je bij de volgende poging een onjuist patroon opgeeft, worden je werkprofiel en de bijbehorende gegevens verwijderd."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Als je bij de volgende poging een onjuiste pincode opgeeft, worden je werkprofiel en de bijbehorende gegevens verwijderd."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Als je bij de volgende poging een onjuist wachtwoord opgeeft, worden je werkprofiel en de bijbehorende gegevens verwijderd."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Te veel onjuiste pogingen. De gegevens van dit apparaat worden verwijderd."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Te veel onjuiste pogingen. Deze gebruiker wordt verwijderd."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Te veel onjuiste pogingen. Dit werkprofiel en de bijbehorende gegevens worden verwijderd."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Sluiten"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Raak de vingerafdruksensor aan"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Vingerafdrukpictogram"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Gezicht niet herkend. Gebruik je vingerafdruk."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Langzaam opladen • Vol over <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Oplaaddock • Vol over <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Gebruiker wijzigen"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Gebruiker toevoegen"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Nieuwe gebruiker"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gast verwijderen?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Verwijderen"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welkom terug, gast!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Wil je doorgaan met je sessie?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Opnieuw starten"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, doorgaan"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Nieuwe gebruiker toevoegen?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Als je een nieuwe gebruiker toevoegt, moet die persoon zijn eigen profiel instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Gebruikerslimiet bereikt"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Je kunt maximaal <xliff:g id="COUNT">%d</xliff:g> gebruikers toevoegen.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ontgrendelen om te gebruiken"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Er is een probleem opgetreden bij het ophalen van je kaarten. Probeer het later opnieuw."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Instellingen voor vergrendelscherm"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR-code scannen"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Werkprofiel"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Vliegtuigmodus"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Je hoort je volgende wekker niet <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe om meer te zien"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Aanbevelingen laden"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Deze mediasessie verbergen?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Deze mediabediening verbergen voor <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"De huidige mediasessie kan niet worden verborgen."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Sluiten"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Verbergen"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Hervatten"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Instellingen"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> van <xliff:g id="ARTIST_NAME">%2$s</xliff:g> wordt afgespeeld via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ga dichter bij <xliff:g id="DEVICENAME">%1$s</xliff:g> staan om hier af te spelen"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Afspelen op <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Afspelen op deze telefoon"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Er is iets misgegaan"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Er is iets misgegaan. Probeer het opnieuw."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactief, check de app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Niet gevonden"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Beheeroptie niet beschikbaar"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index ed1fbbc..3893174 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ଆପଣ ପରବର୍ତ୍ତୀ ପ୍ରଚେଷ୍ଟାରେ ଏକ ଭୁଲ ପାଟର୍ନ ପ୍ରବେଶ କଲେ, ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଏବଂ ଏହାର ଡାଟାକୁ ଡିଲିଟ୍ କରିଦିଆଯିବ।"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ଆପଣ ପରବର୍ତ୍ତୀ ପ୍ରଚେଷ୍ଟାରେ ଏକ ଭୁଲ PIN ଲେଖିଲେ, ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଏବଂ ଏହାର ଡାଟାକୁ ଡିଲିଟ୍ କରିଦିଆଯିବ।"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ଆପଣ ପରବର୍ତ୍ତୀ ପ୍ରଚେଷ୍ଟାରେ ଏକ ଭୁଲ ପାସୱାର୍ଡ ଲେଖିଲେ, ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଓ ଏହାର ଡାଟାକୁ ଡିଲିଟ୍ କରିଦିଆଯିବ।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"ଅନେକଗୁଡ଼ିଏ ଭୁଲ ପ୍ରଚେଷ୍ଟା। ଏହି ଡିଭାଇସର ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"ଅନେକଗୁଡ଼ିଏ ଭୁଲ ପ୍ରଚେଷ୍ଟା। ଏହି ଉପଯୋଗକର୍ତ୍ତା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"ଅନେକଗୁଡ଼ିଏ ଭୁଲ ପ୍ରଚେଷ୍ଟା। ଏହି ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଏବଂ ଏହାର ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"ଖାରଜ କରନ୍ତୁ"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ଟିପଚିହ୍ନ ସେନସର୍କୁ ଛୁଅଁନ୍ତୁ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"ଟିପଚିହ୍ନ ଆଇକନ୍"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ଫେସ୍ ଚିହ୍ନଟ କରିହେବ ନାହିଁ। ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ଧୀରେ ଚାର୍ଜ ହେଉଛି • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>ରେ ସମ୍ପୂର୍ଣ୍ଣ ହେବ"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ଡକରୁ ଚାର୍ଜ ହେଉଛି • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>ରେ ସମ୍ପୂର୍ଣ୍ଣ ହେବ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ୟୁଜର୍ ବଦଳାନ୍ତୁ"</string>
- <string name="user_add_user" msgid="4336657383006913022">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରନ୍ତୁ"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ଅତିଥିଙ୍କୁ କାଢ଼ିଦେବେ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ସେସନର ସମସ୍ତ ଆପ୍ ଓ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"କାଢ଼ିଦିଅନ୍ତୁ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ପୁଣି ସ୍ୱାଗତ, ଅତିଥି!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ଆପଣ ନିଜର ସେସନ୍ ଜାରି ରଖିବାକୁ ଚାହାଁନ୍ତି କି?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ହଁ, ଜାରି ରଖନ୍ତୁ"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"ନୂତନ ଉପଯୋଗକର୍ତ୍ତା ଯୋଗ କରିବେ?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"ଆପଣ ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କଲେ,ତାଙ୍କୁ ସ୍ପେସ୍ ସେଟ୍ ଅପ୍ କରିବାକୁ ପଡ଼ିବ। \n \n ଅନ୍ୟ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଯେ କୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଆପଗୁଡ଼ିକୁ ଅପଡେଟ୍ କରିପାରିବେ।"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"ଉପଯୋଗକର୍ତ୍ତା ସୀମାରେ ପହଞ୍ଚିଛି"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">କେବଳ <xliff:g id="COUNT">%d</xliff:g> ଉପଯୋଗକର୍ତ୍ତା ହିଁ ତିଆରି କରିହେବ।</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ବ୍ୟବହାର କରିବାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"ଆପଣଙ୍କ କାର୍ଡଗୁଡ଼ିକ ପାଇବାରେ ଏକ ସମସ୍ୟା ହୋଇଥିଲା। ଦୟାକରି ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ସ୍କ୍ରିନ୍ ଲକ୍ ସେଟିଂସ୍"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR କୋଡ ସ୍କାନ କରନ୍ତୁ"</string>
<string name="status_bar_work" msgid="5238641949837091056">"ୱର୍କ ପ୍ରୋଫାଇଲ୍"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ଏରୋପ୍ଲେନ୍ ମୋଡ୍"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g>ବେଳେ ଆପଣ ନିଜର ପରବର୍ତ୍ତୀ ଆଲାର୍ମ ଶୁଣିପାରିବେ ନାହିଁ"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ଅଧିକ ଦେଖିବାକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ସୁପାରିଶଗୁଡ଼ିକ ଲୋଡ୍ କରାଯାଉଛି"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ମିଡିଆ"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"ଏହି ମିଡିଆ ସେସନକୁ ଲୁଚାଇବେ?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"ବର୍ତ୍ତମାନର ମିଡିଆ ସେସନକୁ ଲୁଚାଯାଇପାରିବ ନାହିଁ।"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ଖାରଜ କରନ୍ତୁ"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ଲୁଚାନ୍ତୁ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ପୁଣି ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ସେଟିଂସ୍"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ରୁ <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ଙ୍କ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ଏଠାରେ ଚଲାଇବା ପାଇଁ <xliff:g id="DEVICENAME">%1$s</xliff:g>ର ପାଖକୁ ମୁଭ କରନ୍ତୁ"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ରେ ଚାଲୁଛି"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ଏହି ଫୋନରେ ଚାଲୁଛି"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"କିଛି ତ୍ରୁଟି ହୋଇଛି"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"କିଛି ତ୍ରୁଟି ହୋଇଛି। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ମିଳିଲା ନାହିଁ"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"ନିୟନ୍ତ୍ରଣ ଉପଲବ୍ଧ ନାହିଁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index beda960..6e2d33a 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ਜੇ ਤੁਸੀਂ ਅਗਲੀ ਕੋਸ਼ਿਸ਼ ਵਿੱਚ ਕੋਈ ਗਲਤ ਪੈਟਰਨ ਦਾਖਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਇਸ ਦਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ਜੇ ਤੁਸੀਂ ਅਗਲੀ ਕੋਸ਼ਿਸ਼ ਵਿੱਚ ਕੋਈ ਗਲਤ ਪਿੰਨ ਦਾਖਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਇਸ ਦਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ਜੇ ਤੁਸੀਂ ਅਗਲੀ ਕੋਸ਼ਿਸ਼ ਵਿੱਚ ਕੋਈ ਗਲਤ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਇਸ ਦਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"ਬਹੁਤ ਸਾਰੀਆਂ ਗਲਤ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਸ ਡੀਵਾਈਸ ਦਾ ਡਾਟਾ ਮਿਟਾਇਆ ਜਾਵੇਗਾ।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"ਬਹੁਤ ਸਾਰੀਆਂ ਗਲਤ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਮਿਟਾਇਆ ਜਾਵੇਗਾ।"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"ਬਹੁਤ ਸਾਰੀਆਂ ਗਲਤ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਹ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਇਸਦਾ ਡਾਟਾ ਮਿਟਾਇਆ ਜਾਵੇਗਾ।"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"ਖਾਰਜ ਕਰੋ"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਪ੍ਰਤੀਕ"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ਚਿਹਰਾ ਨਹੀਂ ਪਛਾਣ ਸਕਦੇ। ਇਸਦੀ ਬਜਾਏ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੋ।"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ਵਿੱਚ ਪੂਰਾ ਚਾਰਜ ਹੋਵੇਗਾ"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ਡੌਕ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ਵਿੱਚ ਪੂਰਾ ਚਾਰਜ ਹੋਵੇਗਾ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ਵਰਤੋਂਕਾਰ ਸਵਿੱਚ ਕਰੋ"</string>
- <string name="user_add_user" msgid="4336657383006913022">"ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰੋ"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ਕੀ ਮਹਿਮਾਨ ਹਟਾਉਣਾ ਹੈ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿੱਚ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਏਗਾ।"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ਹਟਾਓ"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ਮਹਿਮਾਨ, ਫਿਰ ਤੁਹਾਡਾ ਸੁਆਗਤ ਹੈ!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਸੈਸ਼ਨ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ਹਾਂ, ਜਾਰੀ ਰੱਖੋ"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"ਕੀ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਨਾ ਹੈ?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"ਜਦੋਂ ਤੁਸੀਂ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣੀ ਜਗ੍ਹਾ ਸਥਾਪਤ ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।\n\nਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਹੋਰ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਸੀਮਾ ਪੂਰੀ ਹੋਈ"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">ਤੁਸੀਂ <xliff:g id="COUNT">%d</xliff:g> ਤੱਕ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੇ ਹੋ।</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ਵਰਤਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"ਤੁਹਾਡੇ ਕਾਰਡ ਪ੍ਰਾਪਤ ਕਰਨ ਵਿੱਚ ਕੋਈ ਸਮੱਸਿਆ ਆਈ, ਕਿਰਪਾ ਕਰਕੇ ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"ਲਾਕ ਸਕ੍ਰੀਨ ਸੈਟਿੰਗਾਂ"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR ਕੋਡ ਸਕੈਨ ਕਰੋ"</string>
<string name="status_bar_work" msgid="5238641949837091056">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"ਤੁਸੀਂ <xliff:g id="WHEN">%1$s</xliff:g> ਵਜੇ ਆਪਣਾ ਅਗਲਾ ਅਲਾਰਮ ਨਹੀਂ ਸੁਣੋਗੇ"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ਹੋਰ ਦੇਖਣ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ਸਿਫ਼ਾਰਸ਼ਾਂ ਲੋਡ ਹੋ ਰਹੀਆਂ ਹਨ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ਮੀਡੀਆ"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"ਕੀ ਇਹ ਮੀਡੀਆ ਸੈਸ਼ਨ ਲੁਕਾਉਣਾ ਹੈ?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"ਮੌਜੂਦਾ ਮੀਡੀਆ ਸੈਸ਼ਨ ਲੁਕਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ਖਾਰਜ ਕਰੋ"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ਲੁਕਾਓ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ਸੈਟਿੰਗਾਂ"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ਤੋਂ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ਦਾ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ਇੱਥੇ ਚਲਾਉਣ ਲਈ <xliff:g id="DEVICENAME">%1$s</xliff:g> ਦੇ ਨੇੜੇ ਜਾਓ"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> \'ਤੇ ਚਲਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ਇਸ ਫ਼ੋਨ \'ਤੇ ਚਲਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ਨਹੀਂ ਮਿਲਿਆ"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"ਕੰਟਰੋਲ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index a2f94fc..9b2e901 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jeśli następnym razem podasz nieprawidłowy wzór, profil służbowy oraz powiązane z nim dane zostaną usunięte."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jeśli następnym razem podasz nieprawidłowy kod PIN, profil służbowy oraz powiązane z nim dane zostaną usunięte."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Jeśli następnym razem podasz nieprawidłowe hasło, profil służbowy oraz powiązane z nim dane zostaną usunięte."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Zbyt wiele nieudanych prób. Dane na urządzeniu zostaną usunięte."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Zbyt wiele nieudanych prób. Użytkownik zostanie usunięty."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Zbyt wiele nieudanych prób. Profil służbowy i powiązane z nim dane zostaną usunięte."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Zamknij"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dotknij czytnika linii papilarnych"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona odcisku palca"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Nie rozpoznaję twarzy. Użyj odcisku palca."</string>
@@ -327,17 +323,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Wolne ładowanie • Pełne naładowanie za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ładowanie na stacji dokującej • Pełne naładowanie za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Przełącz użytkownika"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Dodaj użytkownika"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Nowy użytkownik"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Usunąć gościa?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Usuń"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Witaj ponownie, Gościu!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcesz kontynuować sesję?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Rozpocznij nową"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Tak, kontynuuj"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Dodać nowego użytkownika?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Gdy dodasz nowego użytkownika, musi on skonfigurować swój profil.\n\nKażdy użytkownik może aktualizować aplikacje wszystkich innych użytkowników."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Osiągnięto limit użytkowników"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="few">Możesz dodać maksymalnie <xliff:g id="COUNT">%d</xliff:g> użytkowników.</item>
@@ -465,8 +456,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Odblokuj, aby użyć"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Podczas pobierania kart wystąpił problem. Spróbuj ponownie później."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Ustawienia ekranu blokady"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Zeskanuj kod QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil służbowy"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Tryb samolotowy"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nie usłyszysz swojego następnego alarmu <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -797,9 +787,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Przesuń palcem, by zobaczyć więcej"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Wczytuję rekomendacje"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimedia"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Ukryć tę sesję multimediów?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Nie można ukryć tej sesji multimediów."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Odrzuć"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ukryj"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Wznów"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ustawienia"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Aplikacja <xliff:g id="APP_LABEL">%3$s</xliff:g> odtwarza utwór <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>)"</string>
@@ -817,7 +808,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Zbliż do urządzenia <xliff:g id="DEVICENAME">%1$s</xliff:g>, aby na nim odtwarzać"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Odtwarzam na ekranie <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Odtwarzam na tym telefonie"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Coś poszło nie tak"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Coś poszło nie tak. Spróbuj ponownie."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nieaktywny, sprawdź aplikację"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nie znaleziono"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Element jest niedostępny"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index adc33a7..306f9c0 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Se você informar um padrão incorreto na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Se você informar um PIN incorreto na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Se você informar uma senha incorreta na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Excesso de tentativas incorretas. Os dados deste dispositivo serão excluídos."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Excesso de tentativas incorretas. O usuário será excluído."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Excesso de tentativas incorretas. Este perfil de trabalho e os dados dele serão excluídos."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Dispensar"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toque no sensor de impressão digital"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ícone de impressão digital"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Não foi possível reconhecer o rosto Use a impressão digital."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carga lenta • Conclusão em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregando na base • Carga completa em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Adicionar usuário"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuário"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover visitante?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Você voltou, visitante!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Adicionar novo usuário?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Quando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para os demais usuários."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de usuários atingido"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">É possível adicionar até <xliff:g id="COUNT">%d</xliff:g> usuário.</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Deslize para ver mais"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregando recomendações"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mídia"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Ocultar a sessão de mídia?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Ocultar este controle de mídia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Não é possível ocultar a sessão de mídia atual."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dispensar"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tocando <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para abrir a mídia aqui"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Mídia aberta no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Mídia aberta neste smartphone"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Algo deu errado"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Algo deu errado. Tente novamente."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"O controle está indisponível"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 79f33fb..01cfbbb 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Se introduzir um padrão incorreto na tentativa seguinte, o seu perfil de trabalho e os respetivos dados serão eliminados."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Se introduzir um PIN incorreto na tentativa seguinte, o seu perfil de trabalho e os respetivos dados serão eliminados."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Se introduzir uma palavra-passe incorreta na tentativa seguinte, o seu perfil de trabalho e os respetivos dados serão eliminados."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Demasiadas tentativas incorretas. Os dados deste dispositivo serão eliminados."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Demasiadas tentativas incorretas. Este utilizador será eliminado."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Demasiadas tentativas incorretas. Este perfil de trabalho e os respetivos dados serão eliminados."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Ignorar"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toque no sensor de impressões digitais."</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ícone de impressão digital"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Impos. reconh. rosto. Utilize a impressão digital."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • A carregar lentamente • Carga completa em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • A carregar na estação de ancoragem • Carga completa em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mudar utilizador"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Adicionar utilizador"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Novo utilizador"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover o convidado?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Bem-vindo de volta, convidado!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Pretende continuar a sessão?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Adicionar um novo utilizador?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar apps para todos os outros utilizadores."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de utilizadores alcançado"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Pode adicionar até <xliff:g id="COUNT">%d</xliff:g> utilizadores.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para utilizar"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Ocorreu um problema ao obter os seus cartões. Tente novamente mais tarde."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Definições do ecrã de bloqueio"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Leia o código QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabalho"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modo de avião"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Não vai ouvir o próximo alarme às <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Deslize rapidamente para ver mais."</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"A carregar recomendações…"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Multimédia"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Pretende ocultar esta sessão de multimédia?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Não pode ocultar a sessão de multimédia atual."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignorar"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Definições"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> em reprodução a partir da app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para reproduzir aqui"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"A reproduzir no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"A reproduzir neste telemóvel"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Algo correu mal"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Algo correu mal. Tente novamente."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativa. Consulte a app."</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado."</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"O controlo está indisponível"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index adc33a7..306f9c0 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Se você informar um padrão incorreto na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Se você informar um PIN incorreto na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Se você informar uma senha incorreta na próxima tentativa, seu perfil de trabalho e os dados dele serão excluídos."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Excesso de tentativas incorretas. Os dados deste dispositivo serão excluídos."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Excesso de tentativas incorretas. O usuário será excluído."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Excesso de tentativas incorretas. Este perfil de trabalho e os dados dele serão excluídos."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Dispensar"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Toque no sensor de impressão digital"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ícone de impressão digital"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Não foi possível reconhecer o rosto Use a impressão digital."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carga lenta • Conclusão em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregando na base • Carga completa em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Adicionar usuário"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuário"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover visitante?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Você voltou, visitante!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Adicionar novo usuário?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Quando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para os demais usuários."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de usuários atingido"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">É possível adicionar até <xliff:g id="COUNT">%d</xliff:g> usuário.</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Deslize para ver mais"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Carregando recomendações"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Mídia"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Ocultar a sessão de mídia?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Ocultar este controle de mídia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Não é possível ocultar a sessão de mídia atual."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dispensar"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tocando <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para abrir a mídia aqui"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Mídia aberta no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Mídia aberta neste smartphone"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Algo deu errado"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Algo deu errado. Tente novamente."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"O controle está indisponível"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index f57aa71..53d4526 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Dacă la următoarea încercare introduceți un model incorect, profilul de serviciu și datele sale vor fi șterse."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Dacă la următoarea încercare introduceți un cod PIN incorect, profilul de serviciu și datele sale vor fi șterse."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Dacă la următoarea încercare introduceți o parolă incorectă, profilul de serviciu și datele sale vor fi șterse."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Prea multe încercări incorecte. Datele de pe acest dispozitiv vor fi șterse."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Prea multe încercări incorecte. Acest utilizator va fi șters."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Prea multe încercări incorecte. Acest profil de serviciu și datele sale vor fi șterse."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Închideți"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Atingeți senzorul de amprente"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Pictograma amprentă"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Chipul nu a fost recunoscut. Folosiți amprenta."</string>
@@ -325,17 +321,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Se încarcă lent • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> până la încărcarea completă"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Suport de încărcare • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> până la încărcarea completă"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Comutați între utilizatori"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Adăugați un utilizator"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Utilizator nou"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ștergeți invitatul?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ștergeți"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Bine ați revenit în sesiunea pentru invitați!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vreți să continuați sesiunea?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Începeți din nou"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, continuați"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Adăugați un utilizator nou?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Când adăugați un utilizator nou, acesta trebuie să-și configureze spațiul.\n\nOrice utilizator poate actualiza aplicațiile pentru toți ceilalți utilizatori."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Ați atins limita de utilizatori"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="few">Puteți adăuga maximum <xliff:g id="COUNT">%d</xliff:g> utilizatori.</item>
@@ -462,8 +453,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Deblocați pentru a folosi"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"A apărut o problemă la preluarea cardurilor. Încercați din nou mai târziu"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Setările ecranului de blocare"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Scanați codul QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil de serviciu"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Mod Avion"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nu veți auzi următoarea alarmă <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -791,9 +781,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Glisați pentru a vedea mai multe"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Se încarcă recomandările"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Ascundeți sesiunea media?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Ascundeți comanda media pentru <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Sesiunea media actuală nu se poate ascunde."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Închideți"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ascunde"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reia"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Setări"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> de la <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se redă în <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -811,7 +801,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Mergeți mai aproape de <xliff:g id="DEVICENAME">%1$s</xliff:g> ca să redați acolo"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Se redă pe <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Se redă pe acest telefon"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"A apărut o eroare"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"A apărut o eroare. Încercați din nou."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactiv, verificați aplicația"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nu s-a găsit"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Comanda este indisponibilă"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index de09d76..fc99fcb 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Если вы неправильно введете графический ключ ещё раз, ваш рабочий профиль и его данные будут удалены."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Если вы неправильно введете PIN-код ещё раз, ваш рабочий профиль и его данные будут удалены."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Если вы неправильно введете пароль ещё раз, ваш рабочий профиль и его данные будут удалены."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Слишком много неудачных попыток. С устройства будут удалены все данные."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Слишком много неудачных попыток. Этот пользователь будет удален."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Слишком много неудачных попыток. Этот рабочий профиль и его данные будут удалены."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Закрыть"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Прикоснитесь к сканеру отпечатков пальцев."</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Значок отпечатка пальца"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Не удалось распознать лицо. Используйте отпечаток."</string>
@@ -327,17 +323,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Медленная зарядка • Осталось <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Зарядка от док-станции • Ещё <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Сменить пользователя."</string>
- <string name="user_add_user" msgid="4336657383006913022">"Добавить пользователя"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Новый пользователь"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Удалить аккаунт гостя?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Удалить"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Рады видеть вас снова!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Продолжить сеанс?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Начать заново"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продолжить"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Добавить пользователя?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Когда вы добавите пользователя, ему потребуется настроить профиль.\n\nЛюбой пользователь устройства может обновлять приложения для всех аккаунтов."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнут лимит"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Можно добавить не более <xliff:g id="COUNT">%d</xliff:g> пользователя.</item>
@@ -465,8 +456,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Разблокировать для использования"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Не удалось получить информацию о картах. Повторите попытку позже."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Настройки заблокированного экрана"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Сканировать QR-код"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Рабочий профиль"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Режим полета"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Следующий будильник: <xliff:g id="WHEN">%1$s</xliff:g>. Звук отключен."</string>
@@ -797,9 +787,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Проведите по экрану, чтобы увидеть больше"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Загрузка рекомендаций…"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медиа"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Скрыть этот мультимедийный сеанс?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Этот мультимедийный сеанс невозможно скрыть."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Скрыть"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скрыть"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Возобновить"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Воспроизводится медиафайл \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" (исполнитель: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) из приложения \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\"."</string>
@@ -817,7 +808,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Для воспроизведения на этом устройстве подойдите ближе к другому (<xliff:g id="DEVICENAME">%1$s</xliff:g>)."</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Воспроизводится на устройстве \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\"."</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Воспроизводится на этом телефоне."</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Произошла ошибка."</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Произошла ошибка. Повторите попытку."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Нет ответа. Проверьте приложение."</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Не найдено."</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Управление недоступно"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index cdb0896..51d28f3 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"ඔබ ඊළඟ උත්සාහයේදී වැරදි රටාවක් ඇතුළු කළහොත්, ඔබේ කාර්යාල පැතිකඩ සහ එහි දත්ත මකනු ඇත."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"ඔබ ඊළඟ උත්සාහයේදී වැරදි PIN එකක් ඇතුළු කළහොත්, ඔබේ කාර්යාල පැතිකඩ සහ එහි දත්ත මකනු ඇත."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"ඔබ ඊළඟ උත්සාහයේදී වැරදි මුරපදයක් ඇතුළු කළහොත්, ඔබේ කාර්යාල පැතිකඩ සහ එහි දත්ත මකනු ඇත."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"වැරදි උත්සාහයන් ඉතා වැඩි ගණනකි. මෙම උපාංගයෙහි දත්ත මකනු ඇත."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"වැරදි උත්සාහයන් ඉතා වැඩි ගණනකි. මෙම පරිශීලකයා මකනු ඇත."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"වැරදි උත්සාහයන් ඉතා වැඩි ගණනකි. මෙම කාර්යාල පැතිකඩ සහ එහි දත්ත මකනු ඇත."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"ඉවත ලන්න"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"ඇඟිලි සලකුණු නිරූපකය"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"මුහුණ හැඳිනිය නොහැක. ඒ වෙනුවට ඇඟිලි සලකුණ භාවිත ක."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • සෙමින් ආරෝපණය වෙමින් • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>කින් සම්පූර්ණ වේ"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ආරෝපණ ඩොකය • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>කින් සම්පූර්ණ වේ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"පරිශීලක මාරුව"</string>
- <string name="user_add_user" msgid="4336657383006913022">"පරිශීලකයෙක් එක් කරන්න"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"නව පරිශීලකයා"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"අමුත්තාන් ඉවත් කරන්නද?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ඉවත් කරන්න"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"නැවත සාදරයෙන් පිළිගනිමු, අමුත්තා!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"ඔබගේ සැසිය දිගටම කරගෙන යෑමට ඔබට අවශ්යද?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"යළි මුල සිට අරඹන්න"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ඔව්, දිගටම කරගෙන යන්න"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"අලුත් පරිශීලකයෙක් එක් කරන්නද?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"ඔබ අලුත් පරිශීලකයෙක් එකතු කරන විට, එම පුද්ගලයා ඔහුගේ වැඩ කරන ඉඩ සකසා ගත යුතුය.\n\nසියළුම අනෙක් පරිශීලකයින් සඳහා ඕනෑම පරිශීලකයෙකුට යාවත්කාලීන කළ හැක."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"පරිශීලක සීමාවට ළඟා විය"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">ඔබට පරිශීලකයින් <xliff:g id="COUNT">%d</xliff:g>ක් දක්වා එක් කළ හැකිය.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"භාවිත කිරීමට අගුලු හරින්න"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"ඔබගේ කාඩ්පත ලබා ගැනීමේ ගැටලුවක් විය, කරුණාකර පසුව නැවත උත්සාහ කරන්න"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"අගුලු තිර සැකසීම්"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR කේතය ස්කෑන් කරන්න"</string>
<string name="status_bar_work" msgid="5238641949837091056">"කාර්යාල පැතිකඩ"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ගුවන්යානා ප්රකාරය"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"ඔබට ඔබේ ඊළඟ එලාමය <xliff:g id="WHEN">%1$s</xliff:g> නොඇසෙනු ඇත"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"තව බැලීමට ස්වයිප් කරන්න"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"නිර්දේශ පූරණය කරමින්"</string>
<string name="controls_media_title" msgid="1746947284862928133">"මාධ්ය"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"මෙම මාධ්ය සැසිය සඟවන්නද?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"වත්මන් මාධ්ය සැසිය සැඟවිය නොහැකිය."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ඉවත ලන්න"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"සඟවන්න"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"නැවත පටන් ගන්න"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"සැකසීම්"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>ගේ <xliff:g id="SONG_NAME">%1$s</xliff:g> ගීතය <xliff:g id="APP_LABEL">%3$s</xliff:g> වෙතින් ධාවනය වෙමින් පවතී"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"මෙහි ක්රීඩා කිරීමට <xliff:g id="DEVICENAME">%1$s</xliff:g> වෙත වඩා සමීප වන්න"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> හි වාදනය කරමින්"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"මෙම දුරකථනයෙහි වාදනය කරමින්"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"යම් දෙයක් වැරදිණි"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"යම් දෙයක් වැරදිණි. නැවත උත්සාහ කරන්න."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"අක්රියයි, යෙදුම පරීක්ෂා කරන්න"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"හමු නොවිණි"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"පාලනය ලබා ගත නොහැකිය"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 5e29c93..1738420 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ak pri ďalšom pokuse zadáte nesprávny vzor, váš pracovný profil a jeho dáta budú odstránené."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ak pri ďalšom pokuse zadáte nesprávny PIN, váš pracovný profil a jeho dáta budú odstránené."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ak pri ďalšom pokuse zadáte nesprávne heslo, váš pracovný profil a jeho dáta budú odstránené."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Príliš veľa chybných pokusov. Dáta tohto zariadenia budú odstránené."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Príliš veľa chybných pokusov. Tento používateľ bude odstránený."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Príliš veľa chybných pokusov. Tento pracovný profil a jeho dáta budú odstránené."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Zrušiť"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dotknite sa senzora odtlačkov prstov"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona odtlačku prsta"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Tvár sa nedá rozpoznať. Použite odtlačok prsta."</string>
@@ -327,17 +323,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Nabíja sa pomaly • Do úplného nabitia zostáva <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Nabíjací dok • Do úplného nabitia zostáva <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Prepnutie používateľa"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Pridať používateľa"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Nový používateľ"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Odstrániť hosťa?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrániť"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Hosť, vitajte späť!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relácii pokračovať?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začať odznova"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Áno, pokračovať"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Pridať nového používateľa?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor.\n\nKtorýkoľvek používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Dosiahnutý limit počtu používateľov"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="few">Môžete pridať maximálne <xliff:g id="COUNT">%d</xliff:g> používateľov.</item>
@@ -796,9 +787,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Potiahnutím zobrazíte ďalšie položky"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Načítavajú sa odporúčania"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Médiá"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Chcete skryť túto reláciu média?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Aktuálna relácia média sa nedá skryť."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Zavrieť"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skryť"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Pokračovať"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavenia"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> sa prehráva z aplikácie <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -816,7 +808,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ak chcete prehrávať v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>, priblížte sa k nemu"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Prehráva sa v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Prehráva sa v tomto telefóne"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Vyskytol sa problém"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Niečo sa pokazilo. Skúste to znova."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktívne, preverte aplikáciu"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nenájdené"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Ovládač nie je k dispozícii"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index cf9cb1c..ec68ce6 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Če pri naslednjem poskusu vnesete napačen vzorec, bodo delovni profil in podatki v njem izbrisani."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Če pri naslednjem poskusu vnesete napačno kodo PIN, bodo delovni profil in podatki v njem izbrisani."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Če pri naslednjem poskusu vnesete napačno geslo, bodo delovni profil in podatki v njem izbrisani."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Preveč napačnih poskusov. Podatki v napravi bodo izbrisani."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Preveč napačnih poskusov. Uporabnik bo izbrisan."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Preveč napačnih poskusov. Delovni profil in podatki v njem bodo izbrisani."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Opusti"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Dotaknite se tipala prstnih odtisov"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona prstnih odtisov"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Obraza ni mogoče prepoznati. Uporabite prstni odtis."</string>
@@ -327,17 +323,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Počasno polnjenje • Napolnjeno čez <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Polnjenje na nosilcu • Polno čez <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Preklop med uporabniki"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Dodajanje uporabnika"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Nov uporabnik"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite odstraniti gosta?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrani"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Znova pozdravljeni, gost!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite nadaljevati sejo?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začni znova"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nadaljuj"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Dodajanje novega uporabnika?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Ko dodate novega uporabnika, mora ta nastaviti svoj prostor.\n\nVsak uporabnik lahko posodobi aplikacije za vse druge uporabnike."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Omejitev uporabnikov je dosežena"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Dodate lahko do <xliff:g id="COUNT">%d</xliff:g> uporabnika.</item>
@@ -465,8 +456,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Odklenite za uporabo"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Pri pridobivanju kartic je prišlo do težave. Poskusite znova pozneje."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Nastavitve zaklepanja zaslona"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Optično branje kode QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profil za Android Work"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Način za letalo"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Naslednjega alarma ob <xliff:g id="WHEN">%1$s</xliff:g> ne boste slišali"</string>
@@ -797,9 +787,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Če si želite ogledati več, povlecite"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Nalaganje priporočil"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Predstavnost"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Želite skriti to sejo predstavnosti?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Trenutne seje predstavnosti ni mogoče skriti."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Opusti"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrij"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nadaljuj"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavitve"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Skladba <xliff:g id="SONG_NAME">%1$s</xliff:g> izvajalca <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se predvaja iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
@@ -817,7 +808,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približajte napravi <xliff:g id="DEVICENAME">%1$s</xliff:g> za predvajanje v tej napravi"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Predvajanje v napravi <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Predvajanje v tem telefonu"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Prišlo je do težave"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Prišlo je do napake. Poskusite znova."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, poglejte aplikacijo"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ni mogoče najti"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolnik ni na voljo"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index fcf8868..1156572 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Nëse fut një motiv të pasaktë në tentativën tjetër, profili yt i punës dhe të dhënat e tij do të fshihen."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Nëse fut një kod PIN të pasaktë në tentativën tjetër, profili yt i punës dhe të dhënat e tij do të fshihen."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Nëse fut një fjalëkalim të pasaktë në tentativën tjetër, profili yt i punës dhe të dhënat e tij do të fshihen."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Shumë tentativa të pasakta. Të dhënat e kësaj pajisjeje do të fshihen."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Shumë tentativa të pasakta. Ky përdorues do të fshihet."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Shumë tentativa të pasakta. Ky profil pune dhe të dhënat e tij do të fshihen."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Hiq"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Prek sensorin e gjurmës së gishtit"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikona e gjurmës së gishtit"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Nuk mund ta dallojë fytyrën. Përdor më mirë gjurmën e gishtit."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet ngadalë • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet në stacion • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Ndërro përdorues"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Shto përdorues"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Përdorues i ri"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Të hiqet i ftuari?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hiq"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Mirë se erdhe, i ftuar!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Dëshiron ta vazhdosh sesionin tënd?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Fillo nga e para"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Po, vazhdo"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Të shtohet përdorues i ri?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Kur shton një përdorues të ri, ai person duhet të konfigurojë hapësirën e vet.\n\nÇdo përdorues mund t\'i përditësojë aplikacionet për të gjithë përdoruesit e tjerë."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"U arrit kufiri i përdoruesve"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Mund të shtosh deri në <xliff:g id="COUNT">%d</xliff:g> përdorues.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Shkyçe për ta përdorur"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Pati një problem me marrjen e kartave të tua. Provo përsëri më vonë"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Cilësimet e ekranit të kyçjes"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skano kodin QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profili i punës"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Modaliteti i aeroplanit"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nuk do ta dëgjosh alarmin e radhës në <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Rrëshqit shpejt për të shikuar më shumë"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Po ngarkon rekomandimet"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Të fshihet kjo seancë media?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Seanca aktuale e medias nuk mund të fshihet."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Hiq"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fshih"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Vazhdo"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Cilësimet"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> nga <xliff:g id="ARTIST_NAME">%2$s</xliff:g> po luhet nga <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Afrohu te <xliff:g id="DEVICENAME">%1$s</xliff:g> për ta luajtur këtu"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Po luhet në <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Po luhet në këtë telefon"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Ndodhi një gabim"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Ndodhi një gabim. Provo përsëri."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Joaktive, kontrollo aplikacionin"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nuk u gjet"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolli është i padisponueshëm"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 1025552..9fbef66 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ако унесете нетачан шаблон при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ако унесете нетачан PIN при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ако унесете нетачну лозинку при следећем покушају, избрисаћемо пословни профил и његове податке."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Превише нетачних покушаја. Избрисаћемо податке са овог уређаја."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Превише нетачних покушаја. Избрисаћемо овог корисника."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Превише нетачних покушаја. Избрисаћемо овај пословни профил и његове податке."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Одбаци"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Додирните сензор за отисак прста"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Икона отиска прста"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Лице није препознато. Користите отисак прста."</string>
@@ -325,17 +321,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Споро се пуни • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Базна станица за пуњење • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Замени корисника"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Додај корисника"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Нови корисник"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Желите ли да уклоните госта?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Уклони"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Добро дошли назад, госте!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Желите ли да наставите сесију?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни из почетка"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, настави"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Додајете новог корисника?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Када додате новог корисника, та особа треба да подеси свој простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнут максимални број корисника"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Можете да додате највише <xliff:g id="COUNT">%d</xliff:g> корисника.</item>
@@ -790,9 +781,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Превуците да бисте видели још"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Учитавају се препоруке"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медији"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Желите ли да сакријете ову сесију медија?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Актуелна сесија медија не може да буде сакривена."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Одбаци"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сакриј"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Настави"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Подешавања"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се пушта из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -810,7 +802,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближите се уређају <xliff:g id="DEVICENAME">%1$s</xliff:g> да бисте на њему пуштали"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Пушта се на уређају <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Пушта се на овом телефону"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Дошло је до грешке"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Дошло је до грешке. Пробајте поново."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Није пронађено"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Контрола није доступна"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index ed89872..ffcb699 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jobbprofilen och dess data raderas om du ritar fel mönster vid nästa försök."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jobbprofilen och dess data raderas om du anger fel pinkod vid nästa försök."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Din jobbprofil och dess data raderas om du anger fel lösenord vid nästa försök."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"För många felaktiga försök. Enhetens data raderas."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"För många felaktiga försök. Den här användaren raderas."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"För många felaktiga försök. Den här jobbprofilen och dess data raderas."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Stäng"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Tryck på fingeravtryckssensorn"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Ikon för fingeravtryck"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ansiktet kändes inte igen. Använd fingeravtryck."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Laddas långsamt • Fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Dockningsstation • Fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Byt användare"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Lägg till användare"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Ny användare"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vill du ta bort gästen?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alla appar och data i denna session kommer att raderas."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ta bort"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Välkommen tillbaka som gäst!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Vill du fortsätta sessionen?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Börja om"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsätt"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Lägga till ny användare?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"När du lägger till en ny användare måste den personen konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användares räkning."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Användargränsen har nåtts"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Det går att lägga till upp till <xliff:g id="COUNT">%d</xliff:g> användare.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lås upp för att använda"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Det gick inte att hämta dina kort. Försök igen senare."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Inställningar för låsskärm"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skanna QR-kod"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Jobbprofil"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Flygplansläge"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Nästa alarm, kl. <xliff:g id="WHEN">%1$s</xliff:g>, kommer inte att höras"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Svep om du vill se mer"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Rekommendationer läses in"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Vill du dölja mediesessionen?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Den aktuella mediesessionen kan inte döljas."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Stäng"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Dölj"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Återuppta"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Inställningar"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> med <xliff:g id="ARTIST_NAME">%2$s</xliff:g> spelas upp från <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Flytta dig närmare <xliff:g id="DEVICENAME">%1$s</xliff:g> om du vill spela här"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Spelas upp på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Spelas upp på denna telefon"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Något gick fel"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Något gick fel. Försök igen."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv, kolla appen"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Hittades inte"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Styrning är inte tillgänglig"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 2f184a1..9ad8f78 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ukiweka mchoro usio sahihi utakapojaribu tena, wasifu wako wa kazini utafutwa pamoja na data yake."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ukiweka PIN isiyo sahihi utakapojaribu tena, wasifu wako wa kazini utafutwa pamoja na data yake."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ukiweka nenosiri lisilo sahihi utakapojaribu tena, wasifu wako wa kazini utafutwa pamoja na data yake."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Umejaribu kufungua mara nyingi mno kwa njia isiyo sahihi. Data iliyo kwenye kifaa hiki itafutwa."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Umejaribu kufungua mara nyingi mno kwa njia isiyo sahihi. Maelezo ya mtumiaji huyu yatafutwa."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Umejaribu kufungua mara nyingi mno kwa njia isiyo sahihi. Wasifu huu wa kazini utafutwa pamoja na data yake."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Ondoa"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Gusa kitambua alama ya kidole"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Aikoni ya alama ya kidole"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Imeshindwa kutambua uso. Tumia alama ya kidole."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Inachaji polepole • Itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Kituo cha Kuchaji • Itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Badili mtumiaji"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Ongeza mtumiaji"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Mtumiaji mpya"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ungependa kumwondoa mgeni?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ondoa"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Karibu tena mgeni!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Je, unataka kuendelea na kipindi chako?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Anza upya"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ndiyo, endelea"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Ungependa kuongeza mtumiaji?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Mtumiaji mpya utakayemwongeza atahitaji kuongeza akaunti yake.\n\nMtumiaji yoyote anaweza kusasisha programu kwa niaba ya wengine wote."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Umefikia kima cha juu cha watumiaji"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Unaruhusiwa kuongeza hadi watumiaji <xliff:g id="COUNT">%d</xliff:g>.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Fungua ili utumie"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Hitilafu imetokea wakati wa kuleta kadi zako, tafadhali jaribu tena baadaye"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Mipangilio ya kufunga skrini"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Changanua msimbo wa QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Wasifu wa kazini"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Hali ya ndegeni"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Hutasikia kengele yako inayofuata ya saa <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Telezesha kidole ili uone zaidi"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Inapakia mapendekezo"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Maudhui"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Ungependa kuficha kipindi hiki cha maudhui?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Kipindi cha sasa cha maudhui hakiwezi kufichwa."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ondoa"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ficha"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Endelea"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Mipangilio"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ulioimbwa na <xliff:g id="ARTIST_NAME">%2$s</xliff:g> unacheza katika <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Sogeza karibu na <xliff:g id="DEVICENAME">%1$s</xliff:g> ili kucheza hapa"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Inacheza kwenye <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Inacheza kwenye simu hii"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Hitilafu fulani imetokea"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Hitilafu fulani imetokea. Jaribu tena."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Haitumiki, angalia programu"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Hakipatikani"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kidhibiti hakipatikani"</string>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index 9f14d2f2..b3da144 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -38,6 +38,8 @@
<dimen name="status_bar_header_height_keyguard">42dp</dimen>
+ <dimen name="lockscreen_shade_max_over_scroll_amount">32dp</dimen>
+
<!-- Distance that the full shade transition takes in order to complete by tapping on a button
like "expand". -->
<dimen name="lockscreen_shade_transition_by_tap_distance">200dp</dimen>
@@ -86,5 +88,11 @@
whether the progress is > 0, therefore this value is not very important. -->
<dimen name="lockscreen_shade_status_bar_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+ <dimen name="lockscreen_shade_keyguard_transition_distance">@dimen/lockscreen_shade_media_transition_distance</dimen>
+
+ <!-- Roughly the same distance as media on LS to media on QS. We will translate by this value
+ when media is not showing. -->
+ <dimen name="lockscreen_shade_keyguard_transition_vertical_offset">83dp</dimen>
+
<dimen name="notification_panel_margin_horizontal">24dp</dimen>
</resources>
diff --git a/packages/ConnectivityT/framework-t/aidl-export/android/net/NetworkStats.aidl b/packages/SystemUI/res/values-sw600dp-land/integers.xml
similarity index 71%
rename from packages/ConnectivityT/framework-t/aidl-export/android/net/NetworkStats.aidl
rename to packages/SystemUI/res/values-sw600dp-land/integers.xml
index d06ca65..919d605 100644
--- a/packages/ConnectivityT/framework-t/aidl-export/android/net/NetworkStats.aidl
+++ b/packages/SystemUI/res/values-sw600dp-land/integers.xml
@@ -1,5 +1,6 @@
-/**
- * Copyright (c) 2011, The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2006, 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.
@@ -12,8 +13,8 @@
* 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.net;
-
-parcelable NetworkStats;
+*/
+-->
+<resources>
+ <integer name="lockscreen_shade_over_scroll_release_duration">500</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
index 72a71b0..4d4f520 100644
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
@@ -25,5 +25,11 @@
<dimen name="status_bar_header_height_keyguard">56dp</dimen>
- <dimen name="qs_media_session_height_expanded">184dp</dimen>
+ <dimen name="qs_media_session_height_expanded">251dp</dimen>
+
+ <dimen name="lockscreen_shade_max_over_scroll_amount">42dp</dimen>
+
+ <!-- Roughly the same distance as media on LS to media on QS. We will translate by this value
+ when media is not showing. -->
+ <dimen name="lockscreen_shade_keyguard_transition_vertical_offset">93dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index cd40c79..41824e6 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -88,7 +88,7 @@
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ஸ்க்ரீன் ரெக்கார்டிங் செயலாக்கப்படுகிறது"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string>
<string name="screenrecord_start_label" msgid="1750350278888217473">"ரெக்கார்டிங்கைத் தொடங்கவா?"</string>
- <string name="screenrecord_description" msgid="1123231719680353736">"ரெக்கார்டு செய்யும்போது, உங்கள் திரையில் தோன்றக்கூடிய அல்லது சாதனத்தில் பிளே ஆகக்கூடிய ஏதேனும் அதிமுக்கியத் தகவலை Android சிஸ்டம் படமெடுக்க முடியும். கடவுச்சொற்கள், பேமெண்ட் தகவல், படங்கள், மெசேஜ்கள், ஆடியோ ஆகியவை இதில் அடங்கும்."</string>
+ <string name="screenrecord_description" msgid="1123231719680353736">"ரெக்கார்டு செய்யும்போது, உங்கள் திரையில் தோன்றக்கூடிய அல்லது சாதனத்தில் பிளே ஆகக்கூடிய பாதுகாக்கப்பட வேண்டிய தகவலை Android சிஸ்டம் படமெடுக்க முடியும். கடவுச்சொற்கள், பேமெண்ட் தகவல், படங்கள், மெசேஜ்கள், ஆடியோ ஆகியவை இதில் அடங்கும்."</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"ஆடியோவை ரெக்கார்டு செய்"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"சாதன ஆடியோ"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"இசை, அழைப்புகள், ரிங்டோன்கள் போன்ற உங்கள் சாதனத்திலிருந்து வரும் ஒலி"</string>
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"அடுத்த முறை தவறான பேட்டர்னை வரைந்தால் உங்கள் பணிக் கணக்கும் அதன் தரவும் நீக்கப்படும்."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"அடுத்த முறை தவறான பின்னை உள்ளிட்டால் உங்கள் பணிக் கணக்கும் அதன் தரவும் நீக்கப்படும்."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"அடுத்த முறை தவறான கடவுச்சொல்லை உள்ளிட்டால் உங்கள் பணிக் கணக்கும் அதன் தரவும் நீக்கப்படும்."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"பலமுறை தவறாக முயன்ற காரணத்தால் இந்தச் சாதனத்தின் தரவு நீக்கப்படும்."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"பலமுறை தவறாக முயன்ற காரணத்தால் இந்தப் பயனர் நீக்கப்படுவார்."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"பலமுறை தவறாக முயன்றதால், இந்தப் பணிக் கணக்கும் அதன் தரவும் நீக்கப்படும்"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"நிராகரி"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"கைரேகை சென்சாரைத் தொடவும்"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"கைரேகை ஐகான்"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"முகத்தை அடையாளம் காண முடியவில்லை. கைரேகையைப் பயன்படுத்தவும்."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • மெதுவாக சார்ஜாகிறது • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> இல் முழுதும் சார்ஜாகும்"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • டாக் மூலம் சார்ஜாகிறது • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> இல் முழுமையாகச் சார்ஜாகிவிடும்"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"பயனரை மாற்று"</string>
- <string name="user_add_user" msgid="4336657383006913022">"பயனரைச் சேர்"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"புதியவர்"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"கெஸ்ட்டை அகற்றவா?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா ஆப்ஸும் தரவும் நீக்கப்படும்."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"அகற்று"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"நல்வரவு!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"உங்கள் அமர்வைத் தொடர விருப்பமா?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"மீண்டும் தொடங்கு"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"தொடரவும்"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"புதியவரைச் சேர்க்கவா?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"புதிய பயனரைச் சேர்க்கும்போது, அவர் தனக்கான இடத்தை அமைக்க வேண்டும்.\n\nஎந்தவொரு பயனரும், மற்ற எல்லா பயனர்களுக்காகவும் ஆப்ஸைப் புதுப்பிக்கலாம்."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"பயனர் வரம்பை அடைந்துவிட்டீர்கள்"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other"><xliff:g id="COUNT">%d</xliff:g> பயனர்கள் வரை சேர்க்க முடியும்.</item>
@@ -784,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"மேலும் பார்க்க ஸ்வைப் செய்யவும்"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"பரிந்துரைகளை ஏற்றுகிறது"</string>
<string name="controls_media_title" msgid="1746947284862928133">"மீடியா"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"இந்த மீடியா அமர்வை மறைக்க வேண்டுமா?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸுக்கான இந்த மீடியா கட்டுப்பாடுகளை மறைக்கவா?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"தற்போதைய மீடியா அமர்வை மறைக்க முடியாது."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"மூடுக"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"மறை"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"தொடர்க"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"அமைப்புகள்"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> இன் <xliff:g id="SONG_NAME">%1$s</xliff:g> பாடல் <xliff:g id="APP_LABEL">%3$s</xliff:g> ஆப்ஸில் பிளேயாகிறது"</string>
@@ -804,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"இங்கு பிளே செய்ய உங்கள் சாதனத்தை <xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்திற்கு அருகில் நகர்த்துங்கள்"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்தில் பிளே ஆகிறது"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"இந்த மொபைலில் பிளே ஆகிறது"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"ஏதோ தவறாகிவிட்டது"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"ஏதோ தவறாகிவிட்டது. மீண்டும் முயலவும்."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"செயலில் இல்லை , சரிபார்க்கவும்"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"இல்லை"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"கட்டுப்பாடு இல்லை"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 222da19..38489a2 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"మీరు ఒకవేళ తర్వాతి ప్రయత్నంలో తప్పు ఆకృతిని ఎంటర్ చేస్తే, మీ కార్యాలయ ప్రొఫైల్, అలాగే దాని డేటా తొలగించబడతాయి."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"మీరు ఒకవేళ తర్వాతి ప్రయత్నంలో తప్పు పిన్ను ఎంటర్ చేస్తే, మీ కార్యాలయ ప్రొఫైల్, అలాగే దాని డేటా తొలగించబడతాయి."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"మీరు ఒకవేళ తర్వాతి ప్రయత్నంలో తప్పు పాస్వర్డ్ను ఎంటర్ చేస్తే, మీ కార్యాలయ ప్రొఫైల్, అలాగే దాని డేటా తొలగించబడతాయి."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"చాలా ఎక్కువ తప్పు ప్రయత్నాలు చేశారు. ఈ పరికరం యొక్క డేటా తొలగించబడుతుంది."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"చాలా ఎక్కువ తప్పు ప్రయత్నాలు చేశారు. ఈ యూజర్ తొలగించబడతారు."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"చాలా ఎక్కువ తప్పు ప్రయత్నాలు చేశారు. ఈ కార్యాలయ ప్రొఫైల్ మరియు దీని డేటా తొలగించబడతాయి."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"తీసివేయి"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"వేలిముద్ర సెన్సార్ను తాకండి"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"వేలిముద్ర చిహ్నం"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ముఖం గుర్తించలేము. బదులుగా వేలిముద్ర ఉపయోగించండి."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • నెమ్మదిగా ఛార్జ్ అవుతోంది • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>లో పూర్తి ఛార్జ్"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ఛార్జింగ్ డాక్ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"వినియోగదారుని మార్చు"</string>
- <string name="user_add_user" msgid="4336657383006913022">"యూజర్ను జోడించండి"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"కొత్త వినియోగదారు"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"గెస్ట్ను తీసివేయాలా?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్లోని అన్ని యాప్లు మరియు డేటా తొలగించబడతాయి."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"తీసివేయి"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"గెస్ట్కు తిరిగి స్వాగతం!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"మీరు మీ సెషన్ని కొనసాగించాలనుకుంటున్నారా?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"మొదటి నుండి ప్రారంభించు"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"అవును, కొనసాగించు"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"కొత్త యూజర్ను జోడించాలా?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"ఒక కొత్త యూజర్ను మీరు జోడించినప్పుడు, ఆ వ్యక్తి తన స్పేస్ను సెటప్ చేసుకోవాలి.\n\nఏ యూజర్ అయినా మిగతా అందరు యూజర్ల కోసం యాప్లను అప్డేట్ చేయగలరు."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"వినియోగదారు పరిమితిని చేరుకున్నారు"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">మీరు <xliff:g id="COUNT">%d</xliff:g> వినియోగదారుల వరకు జోడించవచ్చు.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ఉపయోగించడానికి అన్లాక్ చేయండి"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"మీ కార్డ్లను పొందడంలో సమస్య ఉంది, దయచేసి తర్వాత మళ్లీ ట్రై చేయండి"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"లాక్ స్క్రీన్ సెట్టింగ్లు"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR కోడ్ను స్కాన్ చేయండి"</string>
<string name="status_bar_work" msgid="5238641949837091056">"ఆఫీస్ ప్రొఫైల్"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ఎయిర్ప్లేన్ మోడ్"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"మీరు <xliff:g id="WHEN">%1$s</xliff:g> సెట్ చేసిన మీ తర్వాత అలారం మీకు వినిపించదు"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"మరిన్నింటిని చూడటం కోసం స్వైప్ చేయండి"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"సిఫార్సులు లోడ్ అవుతున్నాయి"</string>
<string name="controls_media_title" msgid="1746947284862928133">"మీడియా"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"ఈ మీడియా సెషన్ను దాచాలా?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం ఈ మీడియా కంట్రోల్ను దాచాలా?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"ప్రస్తుత మీడియా సెషన్ను దాచడం సాధ్యం కాదు."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"విస్మరించు"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"దాచు"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"కొనసాగించండి"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"సెట్టింగ్లు"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి ప్లే అవుతోంది"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ఇక్కడ ప్లే చేయడానికి <xliff:g id="DEVICENAME">%1$s</xliff:g>కి దగ్గరగా వెళ్లండి"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>లో ప్లే అవుతోంది"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ఈ ఫోన్లో ప్లే అవుతోంది"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"ఏదో తప్పు జరిగింది"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"ఏదో తప్పు జరిగింది. మళ్లీ ట్రై చేయండి."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ఇన్యాక్టివ్, యాప్ చెక్ చేయండి"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"కనుగొనబడలేదు"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"కంట్రోల్ అందుబాటులో లేదు"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 120d870..3daf67f 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"หากคุณป้อนรูปแบบไม่ถูกต้องในความพยายามครั้งถัดไป ระบบจะลบโปรไฟล์งานและข้อมูลในโปรไฟล์"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"หากคุณป้อน PIN ไม่ถูกต้องในความพยายามครั้งถัดไป ระบบจะลบโปรไฟล์งานและข้อมูลในโปรไฟล์"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"หากคุณป้อนรหัสผ่านไม่ถูกต้องในความพยายามครั้งถัดไป ระบบจะลบโปรไฟล์งานและข้อมูลในโปรไฟล์"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"ใช้ความพยายามหลายครั้งเกินไป ระบบจะลบข้อมูลในอุปกรณ์เครื่องนี้"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"ใช้ความพยายามหลายครั้งเกินไป ระบบจะลบผู้ใช้รายนี้"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"ใช้ความพยายามหลายครั้งเกินไป ระบบจะลบโปรไฟล์งานนี้และข้อมูลในโปรไฟล์"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"ปิด"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"แตะเซ็นเซอร์ลายนิ้วมือ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"ไอคอนลายนิ้วมือ"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"ไม่รู้จักใบหน้า ใช้ลายนิ้วมือแทน"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • กำลังชาร์จอย่างช้าๆ • จะเต็มในอีก <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • กำลังชาร์จบนแท่นชาร์จ • จะเต็มในอีก <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"สลับผู้ใช้"</string>
- <string name="user_add_user" msgid="4336657383006913022">"เพิ่มผู้ใช้"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"ผู้ใช้ใหม่"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ต้องการนำผู้ใช้ชั่วคราวออกไหม"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"นำออก"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"ยินดีต้อนรับผู้เข้าร่วมกลับมาอีกครั้ง"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"คุณต้องการอยู่ในเซสชันต่อไปไหม"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"เริ่มต้นใหม่"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ใช่ ดำเนินการต่อ"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"ต้องการเพิ่มผู้ใช้ใหม่ใช่ไหม"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"เมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตนเอง\n\nผู้ใช้ทุกคนสามารถอัปเดตแอปสำหรับผู้ใช้รายอื่นทุกคนได้"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"ถึงขีดจำกัดผู้ใช้แล้ว"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">คุณเพิ่มผู้ใช้ได้สูงสุด <xliff:g id="COUNT">%d</xliff:g> คน</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ปลดล็อกเพื่อใช้"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"เกิดปัญหาในการดึงข้อมูลบัตรของคุณ โปรดลองอีกครั้งในภายหลัง"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"การตั้งค่าหน้าจอล็อก"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"สแกนคิวอาร์โค้ด"</string>
<string name="status_bar_work" msgid="5238641949837091056">"โปรไฟล์งาน"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"โหมดบนเครื่องบิน"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"คุณจะไม่ได้ยินเสียงปลุกครั้งถัดไปในเวลา <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"เลื่อนเพื่อดูเพิ่มเติม"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"กำลังโหลดคำแนะนำ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"สื่อ"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"ซ่อนเซสชันสื่อนี้ไหม"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"ซ่อนตัวควบคุมสื่อนี้สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"ซ่อนเซสชันสื่อในปัจจุบันไม่ได้"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"ปิด"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ซ่อน"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"เล่นต่อ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"การตั้งค่า"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"กำลังเปิดเพลง <xliff:g id="SONG_NAME">%1$s</xliff:g> ของ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> จาก <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ขยับไปใกล้ <xliff:g id="DEVICENAME">%1$s</xliff:g> มากขึ้นเพื่อเล่นที่นี่"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"กำลังเล่นใน <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"กำลังเล่นในโทรศัพท์เครื่องนี้"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"เกิดข้อผิดพลาด"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"เกิดข้อผิดพลาด โปรดลองอีกครั้ง"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ไม่มีการใช้งาน โปรดตรวจสอบแอป"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ไม่พบ"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"ใช้การควบคุมไม่ได้"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 4d5655c..0ae3292 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Kung maling pattern ang mailalagay mo sa susunod na pagsubok, made-delete ang iyong profile sa trabaho at ang data nito."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Kung maling PIN ang mailalagay mo sa susunod na pagsubok, made-delete ang iyong profile sa trabaho at ang data nito."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Kung maling password ang mailalagay mo sa susunod na pagsubok, made-delete ang iyong profile sa trabaho at ang data nito."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Masyadong maraming maling pagsubok. Made-delete ang data ng device na ito."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Masyadong maraming maling pagsubok. Made-delete ang user na ito."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Masyadong maraming maling pagsubok. Made-delete ang profile sa trabaho na ito at ang data nito."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"I-dismiss"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Pindutin ang fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Icon ng fingerprint"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Hindi makilala ang mukha. Gumamit ng fingerprint."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mabagal na nagcha-charge • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> na lang para mapuno"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging Dock • Mapupuno sa loob ng <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Magpalit ng user"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Magdagdag ng user"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Bagong user"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Alisin ang bisita?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alisin"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome ulit, bisita!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Gusto mo bang ipagpatuloy ang iyong session?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Magsimulang muli"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oo, magpatuloy"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Magdagdag ng bagong user?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Kapag nagdagdag ka ng bagong user, kailangang i-set up ng taong iyon ang kanyang espasyo.\n\nAng sinumang user ay maaaring mag-update ng mga app para sa lahat ng iba pang user."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Naabot na ang limitasyon sa user"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Maaari kang magdagdag ng hanggang <xliff:g id="COUNT">%d</xliff:g> user.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"I-unlock para magamit"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Nagkaproblema sa pagkuha ng iyong mga card, pakisubukan ulit sa ibang pagkakataon"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Mga setting ng lock screen"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"I-scan ang QR code"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Profile sa trabaho"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Airplane mode"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Hindi mo maririnig ang iyong susunod na alarm ng <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Mag-swipe para tumingin ng higit pa"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Nilo-load ang rekomendasyon"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Itago ang session ng media na ito?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"itago ang kontrol sa media na ito para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Hindi maitatago ang kasalukuyang session ng media."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"I-dismiss"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Itago"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Ituloy"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Mga Setting"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Nagpe-play ang <xliff:g id="SONG_NAME">%1$s</xliff:g> ni/ng <xliff:g id="ARTIST_NAME">%2$s</xliff:g> mula sa <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Lumapit sa <xliff:g id="DEVICENAME">%1$s</xliff:g> para mag-play rito"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Nagpe-play sa <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Nagpe-play sa teleponong ito"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Nagkaproblema"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Nagkaproblema. Subukan ulit."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Hindi aktibo, tingnan ang app"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Hindi nahanap"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Hindi available ang kontrol"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 170d582..8fe3e34 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Bir sonraki denemenizde yanlış desen girerseniz iş profiliniz ve verileri silinir."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Bir sonraki denemenizde yanlış PIN girerseniz iş profiliniz ve verileri silinir."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Bir sonraki denemenizde yanlış şifre girerseniz iş profiliniz ve verileri silinir."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Çok fazla sayıda hatalı deneme yapıldı. Bu cihazın verileri silinecek."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Çok fazla sayıda hatalı deneme yapıldı. Bu kullanıcı silinecek."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Çok fazla sayıda hatalı denemede yapıldı. İş profiliniz ve verileri silinecek."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Kapat"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Parmak izi sensörüne dokunun"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Parmak izi simgesi"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Yüz tanınamadı. Bunun yerine parmak izi kullanın."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Yavaş şarj oluyor • Dolmasına <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> kaldı"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Yuvada Şarj Oluyor • Dolmasına <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> kaldı"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kullanıcı değiştirme"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Kullanıcı ekle"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Yeni kullanıcı"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Misafir oturumu kaldırılsın mı?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kaldır"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Misafir kullanıcı, tekrar hoşgeldiniz"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Oturumunuza devam etmek istiyor musunuz?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Baştan başla"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Evet, devam et"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Yeni kullanıcı eklensin mi?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Yeni bir kullanıcı eklediğinizde, bu kişinin kendi alanını ayarlaması gerekir.\n\nHerhangi bir kullanıcı, diğer tüm kullanıcılar için uygulamaları güncelleyebilir."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Kullanıcı sınırına ulaşıldı"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">En fazla <xliff:g id="COUNT">%d</xliff:g> kullanıcı ekleyebilirsiniz.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Kullanmak için kilidi aç"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Kartlarınız alınırken bir sorun oluştu. Lütfen daha sonra tekrar deneyin"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Kilit ekranı ayarları"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR kodunu tara"</string>
<string name="status_bar_work" msgid="5238641949837091056">"İş profili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Uçak modu"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"<xliff:g id="WHEN">%1$s</xliff:g> olarak ayarlanmış bir sonraki alarmınızı duymayacaksınız"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Diğer öğeleri görmek için hızlıca kaydırın"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Öneriler yükleniyor"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medya"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Bu medya oturumu gizlensin mi?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Geçerli medya oturumu gizlenemez."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Kapat"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Gizle"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Devam ettir"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> uygulamasından <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, <xliff:g id="SONG_NAME">%1$s</xliff:g> şarkısı çalıyor"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Burada oynatmak için <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaklaşın"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oynatılıyor"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Bu telefonda oynatılıyor"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Hata oluştu"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Bir sorun oldu. Tekrar deneyin."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Devre dışı, uygulamaya bakın"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Bulunamadı"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol kullanılamıyor"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 87ea462..b234dee 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Якщо наступного разу ви введете неправильний ключ, ваш робочий профіль і його дані буде видалено."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Якщо наступного разу ви введете неправильний PIN-код, ваш робочий профіль і його дані буде видалено."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Якщо наступного разу ви введете неправильний пароль, ваш робочий профіль і його дані буде видалено."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Забагато невдалих спроб. Дані на цьому пристрої буде видалено."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Забагато невдалих спроб. Цього користувача буде видалено."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Забагато невдалих спроб. Цей робочий профіль і його дані буде видалено."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Закрити"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Торкніться сканера відбитків пальців"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Значок відбитка пальця"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Обличчя не розпізнано. Скористайтеся відбитком пальця."</string>
@@ -327,17 +323,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Повільне заряджання • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до повного заряду"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Док-станція для заряджання • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до повного заряду"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Змінити користувача"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Додати користувача"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Новий користувач"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Видалити гостя?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усі додатки й дані з цього сеансу буде видалено."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Вийти"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"З поверненням!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Продовжити сеанс?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почати знову"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Так, продовжити"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Додати нового користувача?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Користувач має налаштувати свій профіль після створення.\n\nБудь-який користувач пристрою може оновлювати додатки для решти користувачів."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Ви досягли ліміту користувачів"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Можна додати до <xliff:g id="COUNT">%d</xliff:g> користувача.</item>
@@ -465,8 +456,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Розблокувати, щоб використовувати"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Не вдалось отримати ваші картки. Повторіть спробу пізніше."</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Параметри блокування екрана"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Сканувати QR-код"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Робочий профіль"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Режим польоту"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Наступний сигнал о <xliff:g id="WHEN">%1$s</xliff:g> не пролунає"</string>
@@ -797,9 +787,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Гортайте, щоб переглянути інші"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Завантаження рекомендацій"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Медіа"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Приховати цей медіасеанс?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Поточний медіасеанс не можна приховати."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Закрити"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Приховати"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Відновити"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Налаштування"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Пісня \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", яку виконує <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, грає в додатку <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -817,7 +808,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Наблизьтеся до пристрою <xliff:g id="DEVICENAME">%1$s</xliff:g>, щоб відтворити медіафайли на ньому"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Відтворюється на пристрої <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Відтворюється на цьому телефоні"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Сталася помилка"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Сталася помилка. Повторіть спробу."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, перейдіть у додаток"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Не знайдено"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Елемент керування недоступний"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index cb1cbdd..0ee6b54 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"اگر آپ نے اگلی کوشش میں غلط پیٹرن درج کیا تو آپ کی دفتری پروفائل اور اس کا ڈیٹا حذف کر دیا جائے گا۔"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"اگر آپ نے اگلی کوشش میں غلط PIN درج کیا تو آپ کی دفتری پروفائل اور اس کا ڈیٹا حذف کر دیا جائے گا۔"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"اگر آپ نے اگلی کوشش میں غلط پاس ورڈ درج کیا تو آپ کی دفتری پروفائل اور اس کا ڈیٹا حذف کر دیا جائے گا۔"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"بہت زیادہ غلط کوششیں۔ اس آلے کا ڈیٹا حذف کر دیا جائے گا۔"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"بہت زیادہ غلط کوششیں۔ اس صارف کو حذف کر دیا جائے گا۔"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"بہت زیادہ غلط کوششیں۔ یہ دفتری پروفائل اور اس کا ڈیٹا حذف کر دیا جائے گا۔"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"برخاست کریں"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"فنگر پرنٹ سینسر پر ٹچ کریں"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"فنگر پرنٹ آئیکن"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"چہرے کی شناخت نہیں ہو سکی۔ اس کے بجائے فنگر پرنٹ استعمال کریں۔"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • آہستہ چارج ہو رہا ہے • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> میں مکمل"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ڈاک چارج ہو رہا ہے • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> میں مکمل"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"صارف سوئچ کریں"</string>
- <string name="user_add_user" msgid="4336657383006913022">"صارف کو شامل کریں"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"نیا صارف"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"مہمان کو ہٹائیں؟"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ہٹائیں"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"مہمان، پھر سے خوش آمدید!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"کیا آپ اپنا سیشن جاری رکھنا چاہتے ہیں؟"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"دوبارہ شروع کریں"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ہاں، جاری رکھیں"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"نیا صارف شامل کریں؟"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"جب آپ ایک نیا صارف شامل کرتے ہیں تو اس شخص کو اپنی جگہ کو ترتیب دینے کی ضرورت ہوتی ہے۔\n\nکوئی بھی صارف دیگر سبھی صارفین کیلئے ایپس کو اپ ڈیٹ کر سکتا ہے۔"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"صارف کی حد مکمل ہو گئی"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">صرف <xliff:g id="COUNT">%d</xliff:g> صارفین بنائے جا سکتے ہیں۔</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"استعمال کرنے کے لیے غیر مقفل کریں"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"آپ کے کارڈز حاصل کرنے میں ایک مسئلہ درپیش تھا، براہ کرم بعد میں دوبارہ کوشش کریں"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"مقفل اسکرین کی ترتیبات"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR کوڈ اسکین کریں"</string>
<string name="status_bar_work" msgid="5238641949837091056">"دفتری پروفائل"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"ہوائی جہاز وضع"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"آپ کو <xliff:g id="WHEN">%1$s</xliff:g> بجے اپنا اگلا الارم سنائی نہیں دے گا"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"مزید دیکھنے کیلئے سوائپ کریں"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"تجاویز لوڈ ہو رہی ہیں"</string>
<string name="controls_media_title" msgid="1746947284862928133">"میڈیا"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"اس میڈیا سیشن کو چھپائیں؟"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"میڈیا کے موجودہ سیشن کو چھپایا نہیں جا سکتا۔"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"برخاست کریں"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"چھپائیں"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"دوبارہ شروع کریں"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ترتیبات"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> سے <xliff:g id="ARTIST_NAME">%2$s</xliff:g> کا <xliff:g id="SONG_NAME">%1$s</xliff:g> چل رہا ہے"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"یہاں چلانے کے ليے <xliff:g id="DEVICENAME">%1$s</xliff:g> کے قریب جائیں"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> پر چل رہا ہے"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"اس فون پر چل رہا ہے"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"کچھ غلط ہو گیا"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"کچھ غلط ہوگیا۔ پھر کوشش کریں۔"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غیر فعال، ایپ چیک کریں"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"نہیں ملا"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"کنٹرول دستیاب نہیں ہے"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 1128b297..95111c7 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Agar grafik kalitni xato kiritsangiz, ish profili va undagi maʼlumotlar oʻchirib tashlanadi."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Agar PIN kodni xato kiritsangiz, ish profili va undagi maʼlumotlar oʻchirib tashlanadi."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Agar parolni xato kiritsangiz, ish profili va undagi maʼlumotlar oʻchirib tashlanadi."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Juda koʻp marta muvaffaqiyatsiz urindingiz. Bu qurilmadagi maʼlumotlar oʻchirib tashlanadi."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Juda koʻp marta muvaffaqiyatsiz urindingiz. Bu foydalanuvchi oʻchirib tashlanadi."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Juda koʻp marta muvaffaqiyatsiz urindingiz. Bu ish profili va undagi maʼlumotlar oʻchirib tashlanadi."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Yopish"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Barmoq izi skaneriga tegining"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Barmoq izi belgisi"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Bu yuz notanish. Barmoq izi orqali urining."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Sekin quvvat olmoqda • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> qoldi"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Dok-stansiya • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> qoldi"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Foydalanuvchini almashtirish"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Foydalanuvchi"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Yangi foydalanuvchi"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Mehmon olib tashlansinmi?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Olib tashlash"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Xush kelibsiz, mehmon!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Seansni davom ettirmoqchimisiz?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Boshidan boshlansin"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ha, davom ettirilsin"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Foydalanuvchi qo‘shilsinmi?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Yangi profil qo‘shilgach, uni sozlash lozim.\n\nQurilmaning istalgan foydalanuvchisi ilovalarni barcha hisoblar uchun yangilashi mumkin."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Limitga yetib keldi"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other"><xliff:g id="COUNT">%d</xliff:g> tagacha foydalanuvchi qo‘shish mumkin.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Foydalanish uchun qulfdan chiqarish"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Bildirgilarni yuklashda xatolik yuz berdi, keyinroq qaytadan urining"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Qulflangan ekran sozlamalari"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"QR kodni skanerlash"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Ish profili"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Parvoz rejimi"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Keyingi signal (<xliff:g id="WHEN">%1$s</xliff:g>) chalinmaydi"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Batafsil axborot olish uchun suring"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Tavsiyalar yuklanmoqda"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Media"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Bu media seansi berkitilsinmi?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Joriy media seansi berkitilmadi."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Yopish"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Berkitish"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Davom etish"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Sozlamalar"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ilovasida ijro etilmoqda: <xliff:g id="SONG_NAME">%1$s</xliff:g> – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Bu yerda ijro qilish uchun <xliff:g id="DEVICENAME">%1$s</xliff:g>qurilmasiga yaqinlashtiring"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> qurilmasida ijro qilinmoqda"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Bu telefonda ijro etilmoqda"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Xatolik yuz berdi"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Xatolik yuz berdi. Qayta urining."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nofaol. Ilovani tekshiring"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Topilmadi"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Boshqarish imkonsiz"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 068127b..b88e838 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Nếu bạn nhập hình mở khóa không chính xác vào lần thử tiếp theo, thì hồ sơ công việc của bạn và dữ liệu của hồ sơ công việc sẽ bị xóa."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Nếu bạn nhập mã PIN không chính xác vào lần thử tiếp theo, thì hồ sơ công việc của bạn và dữ liệu của hồ sơ công việc sẽ bị xóa."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Nếu bạn nhập mật khẩu không chính xác vào lần thử tiếp theo, thì hồ sơ công việc của bạn và dữ liệu của hồ sơ công việc sẽ bị xóa."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Dữ liệu trên thiết bị này sẽ bị xóa do có quá nhiều lần nhập sai khóa thiết bị."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Người dùng này sẽ bị xóa do có quá nhiều lần nhập sai khóa người dùng."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Hồ sơ công việc này và dữ liệu của hồ sơ công việc sẽ bị xóa do có quá nhiều lần nhập sai khóa công việc."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Đóng"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Chạm vào cảm biến vân tay"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Biểu tượng vân tay"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Không thể nhận dạng khuôn mặt. Hãy dùng vân tay."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Đang sạc chậm • Sẽ đầy sau <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Đế sạc • Sạc đầy sau <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Chuyển đổi người dùng"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Thêm người dùng"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Người dùng mới"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Xóa phiên khách?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tất cả ứng dụng và dữ liệu trong phiên này sẽ bị xóa."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Xóa"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Chào mừng bạn trở lại!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Bạn có muốn tiếp tục phiên của mình không?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Bắt đầu lại"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Có, tiếp tục"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Thêm người dùng mới?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Khi bạn thêm người dùng mới, họ cần thiết lập không gian của mình.\n\nMọi người dùng đều có thể cập nhật ứng dụng cho tất cả người dùng khác."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Đã đạt đến giới hạn người dùng"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">Bạn có thể thêm tối đa <xliff:g id="COUNT">%d</xliff:g> người dùng.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Mở khóa để sử dụng"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Đã xảy ra sự cố khi tải thẻ của bạn. Vui lòng thử lại sau"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Cài đặt màn hình khóa"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Quét mã QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Hồ sơ công việc"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Chế độ máy bay"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Bạn sẽ không nghe thấy báo thức tiếp theo lúc <xliff:g id="WHEN">%1$s</xliff:g> của mình"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Vuốt để xem thêm"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Đang tải các đề xuất"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Nội dung nghe nhìn"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Ẩn phiên phát nội dung nghe nhìn này?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"Không thể ẩn phiên phát nội dung nghe nhìn hiện tại."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Đóng"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ẩn"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Tiếp tục"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Cài đặt"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"Đang phát <xliff:g id="SONG_NAME">%1$s</xliff:g> của <xliff:g id="ARTIST_NAME">%2$s</xliff:g> trên <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Di chuyển đến gần <xliff:g id="DEVICENAME">%1$s</xliff:g> hơn để phát tại đây"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Đang phát trên <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Đang phát trên điện thoại này"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Đã xảy ra lỗi"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Đã xảy ra lỗi. Hãy thử lại."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Không hoạt động, hãy kiểm tra ứng dụng"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Không tìm thấy"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Không có chức năng điều khiển"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index b5671e6..69536f1 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"如果您下次绘制的解锁图案仍然有误,您的工作资料及其相关数据将会被删除。"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"如果您下次输入的 PIN 码仍然有误,您的工作资料及其相关数据将会被删除。"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"如果您下次输入的密码仍然有误,您的工作资料及其相关数据将会被删除。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"错误次数过多。系统将删除此设备上的数据。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"错误次数过多。系统将删除此用户。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"错误次数过多。系统将删除此工作资料和相关数据。"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"关闭"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"请触摸指纹传感器"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"指纹图标"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"无法识别人脸。请改用指纹。"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 正在慢速充电 • 将于 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>后充满"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 正在基座上充电 • 将于 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>后充满"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切换用户"</string>
- <string name="user_add_user" msgid="4336657383006913022">"添加用户"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"新用户"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"要移除访客吗?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"访客,欢迎回来!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"要继续您的会话吗?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新开始"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是,继续"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"要添加新用户吗?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"当您添加新用户时,该用户必须设置自己的空间。\n\n任何用户均可为其他所有用户更新应用。"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"已达到用户数上限"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">您最多可以添加 <xliff:g id="COUNT">%d</xliff:g> 位用户。</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"解锁设备即可使用"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"获取您的卡片时出现问题,请稍后重试"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"锁定屏幕设置"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"扫描二维码"</string>
<string name="status_bar_work" msgid="5238641949837091056">"工作资料"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"飞行模式"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"您在<xliff:g id="WHEN">%1$s</xliff:g>将不会听到下次闹钟响铃"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑动可查看更多结构"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在加载推荐内容"</string>
<string name="controls_media_title" msgid="1746947284862928133">"媒体"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"要隐藏此媒体会话吗?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"无法隐藏当前的媒体会话。"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"关闭"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隐藏"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"继续播放"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"设置"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"正在通过<xliff:g id="APP_LABEL">%3$s</xliff:g>播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"若要在此设备上播放,请靠近“<xliff:g id="DEVICENAME">%1$s</xliff:g>”"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在“<xliff:g id="DEVICENAME">%1$s</xliff:g>”上播放"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"正在此手机上播放"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"出了点问题"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"出了点问题,请重试。"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"无效,请检查应用"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"未找到"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"控件不可用"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 718d5e1..ec282c3 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"如果您下次畫出錯誤的上鎖圖案,系統將會刪除工作設定檔和相關資料。"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"如果您下次輸入錯誤的 PIN,系統將會刪除工作設定檔和相關資料。"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"如果您下次輸入錯誤的密碼,系統將會刪除工作設定檔和相關資料。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"錯誤次數太多,系統將會刪除此裝置上的資料。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"錯誤次數太多,系統將會刪除此使用者。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"錯誤次數太多,系統將會刪除此工作設定檔和相關資料。"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"關閉"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"請輕觸指紋感應器"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"指紋圖示"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"無法辨識面孔,請改用指紋完成驗證。"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 慢速充電中 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充滿電"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 正在插座上充電 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充滿電"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
- <string name="user_add_user" msgid="4336657383006913022">"加入使用者"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"新使用者"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"移除訪客?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"訪客您好,歡迎回來!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"您要繼續您的工作階段嗎?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是的,請繼續"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"新增使用者?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"新增的使用者需要自行設定個人空間。\n\n任何使用者均可為所有其他使用者更新應用程式。"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"已達到使用者上限"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">您可以加入多達 <xliff:g id="COUNT">%d</xliff:g> 個使用者。</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"解鎖即可使用"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"擷取資訊卡時發生問題,請稍後再試。"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"上鎖畫面設定"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"掃瞄 QR 碼"</string>
<string name="status_bar_work" msgid="5238641949837091056">"工作設定檔"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"飛行模式"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"您不會<xliff:g id="WHEN">%1$s</xliff:g>聽到鬧鐘"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑動以查看更多"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在載入建議"</string>
<string name="controls_media_title" msgid="1746947284862928133">"媒體"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"要隱藏此媒體工作階段嗎?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"無法隱藏目前的媒體工作階段。"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"關閉"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"正在透過 <xliff:g id="APP_LABEL">%3$s</xliff:g> 播放 <xliff:g id="ARTIST_NAME">%2$s</xliff:g> 的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"如要在此裝置上播放,請靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"正在此手機上播放"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"發生錯誤"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"已停用,請檢查應用程式"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"找不到"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制功能"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index dcb74b3..e28cb15 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"如果下次輸入的解鎖圖案仍不正確,系統將刪除你的工作資料夾和相關資料。"</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"如果下次輸入的 PIN 碼仍不正確,系統將刪除你的工作資料夾和相關資料。"</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"如果下次輸入的密碼仍不正確,系統將刪除你的工作資料夾和相關資料。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"錯誤次數過多,系統將刪除這部裝置中的資料。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"錯誤次數過多,系統將刪除這位使用者。"</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"錯誤次數過多,系統將刪除這個工作資料夾和相關資料。"</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"關閉"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"請輕觸指紋感應器"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"指紋圖示"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"無法辨識臉孔,請改用指紋完成驗證。"</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 慢速充電中 • 將於 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充飽"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 正在座架上充電 • 將於 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充飽"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
- <string name="user_add_user" msgid="4336657383006913022">"新增使用者"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"新使用者"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"移除訪客?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會遭到刪除。"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"訪客你好,歡迎回來!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"你要繼續這個工作階段嗎?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是,繼續"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"要新增使用者嗎?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"新增的使用者需要自行設定個人空間。\n\n任何使用者皆可為其他所有使用者更新應用程式。"</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"已達使用者數量上限"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="other">最多可新增 <xliff:g id="COUNT">%d</xliff:g> 位使用者。</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"解鎖即可使用"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"擷取卡片時發生問題,請稍後再試"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"螢幕鎖定設定"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"掃描 QR 圖碼"</string>
<string name="status_bar_work" msgid="5238641949837091056">"工作資料夾"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"飛航模式"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"你不會聽到下一個<xliff:g id="WHEN">%1$s</xliff:g> 的鬧鐘"</string>
@@ -785,9 +775,10 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"滑動即可查看其他結構"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在載入建議控制項"</string>
<string name="controls_media_title" msgid="1746947284862928133">"媒體"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"要隱藏這個媒體工作階段嗎?"</string>
+ <!-- no translation found for controls_media_close_session (4780485355795635052) -->
+ <skip />
<string name="controls_media_active_session" msgid="3146882316024153337">"無法隱藏目前的媒體工作階段。"</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"關閉"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"系統正透過「<xliff:g id="APP_LABEL">%3$s</xliff:g>」播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的〈<xliff:g id="SONG_NAME">%1$s</xliff:g>〉"</string>
@@ -805,7 +796,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"如要在這部裝置上播放,請移到更靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」的位置"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"正在這支手機上播放"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"發生錯誤"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"無效,請查看應用程式"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"找不到控制項"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制項"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index f26ef0e..510a529 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -151,10 +151,6 @@
<string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Uma ufaka iphethini engalungile kumzamo olandelayo, iphrofayela yakho yomsebenzi nedatha yayo izosuswa."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Uma ufaka iphinikhodi engalungile kumzamo olandelayo, iphrofayela yakho yomsebenzi nedatha yayo izosuswa."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Uma ufake iphasiwedi engalungile kumzamo olandelayo, iphrofayela yakho yomsebenzi nedatha yayo izosuswa."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"Imizamo eminingi kakhulu engalungile. Le datha yedivayisi izosuswa."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_user" msgid="7015008539146949115">"Imizamo eminingi kakhulu engalungile. Lo msebenzisi uzosuswa."</string>
- <string name="biometric_dialog_failed_attempts_now_wiping_profile" msgid="5239378521440749682">"Imizamo eminingi kakhulu engalungile. Le phrofayela yomsebenzi nedatha yayo kuzosuswa."</string>
- <string name="biometric_dialog_now_wiping_dialog_dismiss" msgid="7189432882125106154">"Cashisa"</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Thinta inzwa yesigxivizo zeminwe"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="4465698996175640549">"Isithonjana sezigxivizo zeminwe"</string>
<string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ayibazi ubuso. Sebenzisa izigxivizo zeminwe kunalokho."</string>
@@ -323,17 +319,12 @@
<string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ishaja kancane • Izogcwala ngo-<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ukushaja Idokhi • Izogcwala ngo-<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Shintsha umsebenzisi"</string>
- <string name="user_add_user" msgid="4336657383006913022">"Engeza umsebenzisi"</string>
- <string name="user_new_user_name" msgid="2019166282704195789">"Umsebenzisi omusha"</string>
- <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Susa isivakashi?"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Zonke izinhlelo zokusebenza nedatha kulesi sikhathi zizosuswa."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Susa"</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"Siyakwamukela futhi, sivakashi!"</string>
<string name="guest_wipe_session_message" msgid="3393823610257065457">"Ingabe ufuna ukuqhubeka ngesikhathi sakho?"</string>
<string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Qala phansi"</string>
<string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yebo, qhubeka"</string>
- <string name="user_add_user_title" msgid="4172327541504825032">"Engeza umsebenzisi omusha?"</string>
- <string name="user_add_user_message_short" msgid="2599370307878014791">"Uma ungeza umsebenzisi omusha, loyo muntu udinga ukusetha isikhala sakhe.\n\nNoma yimuphi umsebenzisi angabuyekeza izinhlelo zokusebenza kubo bonke abasebenzisi."</string>
<string name="user_limit_reached_title" msgid="2429229448830346057">"Kufinyelelwe kumkhawulo womsebenzisi"</string>
<plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
<item quantity="one">Ungangeza kufikela kubasebenzisi abangu-<xliff:g id="COUNT">%d</xliff:g>.</item>
@@ -459,8 +450,7 @@
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Vula ukuze usebenzise"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Kube khona inkinga yokuthola amakhadi akho, sicela uzame futhi ngemuva kwesikhathi"</string>
<string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Amasethingi okukhiya isikrini"</string>
- <!-- no translation found for qr_code_scanner_title (5290201053875420785) -->
- <skip />
+ <string name="qr_code_scanner_title" msgid="5290201053875420785">"Skena ikhodi ye-QR"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Iphrofayela yomsebenzi"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Imodi yendiza"</string>
<string name="zen_alarm_warning" msgid="7844303238486849503">"Ngeke uzwe i-alamu yakho elandelayo ngo-<xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -785,9 +775,9 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Swayipha ukuze ubone okuningi"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Ilayisha izincomo"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Imidiya"</string>
- <string name="controls_media_close_session" msgid="1193000643003066508">"Fihla le seshini yemidiya?"</string>
+ <string name="controls_media_close_session" msgid="4780485355795635052">"Fihlela i-<xliff:g id="APP_NAME">%1$s</xliff:g> lesi silawuli semidiya?"</string>
<string name="controls_media_active_session" msgid="3146882316024153337">"Iseshini yamanje yemidiya ayikwazi ukufihlwa."</string>
- <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Cashisa"</string>
+ <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fihla"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Qalisa kabusha"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Izilungiselelo"</string>
<string name="controls_media_playing_item_description" msgid="4531853311504359098">"I-<xliff:g id="SONG_NAME">%1$s</xliff:g> ka-<xliff:g id="ARTIST_NAME">%2$s</xliff:g> idlala kusuka ku-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -805,7 +795,7 @@
<string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Sondela eduze ne-<xliff:g id="DEVICENAME">%1$s</xliff:g> ukuze udlale lapha"</string>
<string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Idlala ku-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
<string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Okudlala kule foni"</string>
- <string name="media_transfer_failed" msgid="2640354446629980227">"Kukhona okungahambanga kahle"</string>
+ <string name="media_transfer_failed" msgid="7955354964610603723">"Kukhona okungahambanga kahle. Zama futhi."</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Akusebenzi, hlola uhlelo lokusebenza"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ayitholakali"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"Ukulawula akutholakali"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 49fc848..50fdc7b 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -138,7 +138,8 @@
<color name="udfps_enroll_icon">#7DA7F1</color>
<color name="udfps_moving_target_fill">#475670</color>
<color name="udfps_enroll_progress">#7DA7F1</color>
- <color name="udfps_enroll_progress_help">#ffEE675C</color>
+ <color name="udfps_enroll_progress_help">#607DA7F1</color>
+ <color name="udfps_enroll_progress_help_with_talkback">#ffEE675C</color>
<!-- Floating overlay actions -->
<color name="overlay_button_ripple">#1f000000</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index a309cc4..e187cd3 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1170,13 +1170,19 @@
whether the progress is > 0, therefore this value is not very important. -->
<dimen name="lockscreen_shade_status_bar_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
+ <!-- Distance that the full shade transition takes in order for the keyguard elements to fully
+ translate into their final position. -->
+ <dimen name="lockscreen_shade_keyguard_transition_distance">@dimen/lockscreen_shade_media_transition_distance</dimen>
+
+ <!-- The amount of vertical offset for the keyguard during the full shade transition. -->
+ <dimen name="lockscreen_shade_keyguard_transition_vertical_offset">0dp</dimen>
+
<!-- Distance that the full shade transition takes in order for media to fully transition to
the shade -->
<dimen name="lockscreen_shade_media_transition_distance">120dp</dimen>
- <!-- Maximum overshoot for the topPadding of notifications when transitioning to the full
- shade -->
- <dimen name="lockscreen_shade_notification_movement">24dp</dimen>
+ <!-- Maximum over scroll amount for the shade when transition to the full shade. -->
+ <dimen name="lockscreen_shade_max_over_scroll_amount">24dp</dimen>
<!-- Maximum overshoot for the pulse expansion -->
<dimen name="pulse_expansion_max_top_overshoot">32dp</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 096b9a0..926734c 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -167,11 +167,5 @@
<item type="id" name="action_move_bottom_right"/>
<item type="id" name="action_move_to_edge_and_hide"/>
<item type="id" name="action_move_out_edge_and_show"/>
-
- <!-- rounded corner view id -->
- <item type="id" name="rounded_corner_top_left"/>
- <item type="id" name="rounded_corner_top_right"/>
- <item type="id" name="rounded_corner_bottom_left"/>
- <item type="id" name="rounded_corner_bottom_right"/>
</resources>
diff --git a/packages/SystemUI/res/values/integers.xml b/packages/SystemUI/res/values/integers.xml
index f0f7a19..3164ed1 100644
--- a/packages/SystemUI/res/values/integers.xml
+++ b/packages/SystemUI/res/values/integers.xml
@@ -25,4 +25,7 @@
See com.android.systemui.volume.VolumeDialogImpl.
Value 21 corresponds to RIGHT|CENTER_VERTICAL. -->
<integer name="volume_dialog_gravity">21</integer>
+
+ <!-- The time it takes for the over scroll release animation to complete, in milli seconds. -->
+ <integer name="lockscreen_shade_over_scroll_release_duration">0</integer>
</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d3b76d9..e00c7bd 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -87,6 +87,18 @@
<!-- Checkbox label for USB device dialogs with warning text for USB device dialogs. [CHAR LIMIT=200]-->
<string name="usb_device_permission_prompt_warn">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_device" example="USB Headphones">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device.</string>
+ <!-- USB audio device permission dialog title. [CHAR LIMIT=200]-->
+ <string name="usb_audio_device_permission_prompt_title">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_device" example="USB Headphones">%2$s</xliff:g>?</string>
+
+ <!-- USB audio device confirm dialog title. [CHAR LIMIT=200]-->
+ <string name="usb_audio_device_confirm_prompt_title">Open <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to handle <xliff:g id="usb_device" example="USB Headphones">%2$s</xliff:g>?</string>
+
+ <!-- Checkbox label for USB audio device dialogs with warning text for USB audio device dialogs. [CHAR LIMIT=NONE]-->
+ <string name="usb_audio_device_prompt_warn">This app has not been granted record permission but could capture audio through this USB device. Using <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms.</string>
+
+ <!-- Prompt for the USB audio device permission dialog [CHAR LIMIT=NONE] -->
+ <string name="usb_audio_device_prompt">Using <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> with this device might prevent hearing calls, notifications and alarms.</string>
+
<!-- Prompt for the USB accessory permission dialog [CHAR LIMIT=80] -->
<string name="usb_accessory_permission_prompt">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_accessory" example="USB Dock">%2$s</xliff:g>?</string>
@@ -2093,6 +2105,19 @@
<!-- Controls tile secondary label when device is locked and user does not want access to controls from lockscreen [CHAR LIMIT=20] -->
<string name="controls_tile_locked">Device locked</string>
+ <!-- Title of the dialog to show and control devices from lock screen [CHAR LIMIT=NONE] -->
+ <string name="controls_settings_show_controls_dialog_title">Show and control devices from lock screen?</string>
+ <!-- Message of the dialog to show and control devices from lock screen [CHAR LIMIT=NONE] -->
+ <string name="controls_settings_show_controls_dialog_message">You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes any time in Settings.</string>
+ <!-- Title of the dialog to control certain devices from lock screen without auth [CHAR LIMIT=NONE] -->
+ <string name="controls_settings_trivial_controls_dialog_title">Control devices from lock screen?</string>
+ <!-- Message of the dialog to control certain devices from lock screen without auth [CHAR LIMIT=NONE] -->
+ <string name="controls_settings_trivial_controls_dialog_message">You can control some devices without unlocking your phone or tablet.\n\nYour device app determines which devices can be controlled in this way.</string>
+ <!-- Neutral button title of the controls dialog [CHAR LIMIT=NONE] -->
+ <string name="controls_settings_dialog_neutral_button">No thanks</string>
+ <!-- Positive button title of the controls dialog [CHAR LIMIT=NONE] -->
+ <string name="controls_settings_dialog_positive_button">Yes</string>
+
<!-- Controls PIN entry dialog, switch to alphanumeric keyboard [CHAR LIMIT=100] -->
<string name="controls_pin_use_alphanumeric">PIN contains letters or symbols</string>
<!-- Controls PIN entry dialog, title [CHAR LIMIT=30] -->
@@ -2372,8 +2397,8 @@
<!-- Label of the button to stop an app from running but the app is already stopped and the button is disabled [CHAR LIMIT=12]-->
<string name="fgs_manager_app_item_stop_button_stopped_label">Stopped</string>
- <!-- Label for button to copy edited text back to the clipboard [CHAR LIMIT=20] -->
- <string name="clipboard_edit_text_copy">Copy</string>
+ <!-- Label for button to finish and copy edited text back to the clipboard [CHAR LIMIT=20] -->
+ <string name="clipboard_edit_text_done">Done</string>
<!-- Text informing user that content has been copied to the system clipboard [CHAR LIMIT=NONE] -->
<string name="clipboard_overlay_text_copied">Copied</string>
<!-- Text informing user where text being edited was copied from [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index a61eda8..7de0f65 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -616,7 +616,6 @@
parent="@android:style/Widget.Material.Button.Borderless.Small">
<item name="android:background">@drawable/qs_media_light_source</item>
<item name="android:tint">?android:attr/textColorPrimary</item>
- <item name="android:stateListAnimator">@anim/media_button_state_list_animator</item>
<item name="android:paddingTop">12dp</item>
<item name="android:paddingStart">12dp</item>
<item name="android:paddingEnd">12dp</item>
@@ -629,6 +628,10 @@
<item name="android:backgroundTint">@color/media_player_solid_button_bg</item>
</style>
+ <style name="MediaPlayer.SessionAction.Secondary" parent="MediaPlayer.SessionAction">
+ <item name="android:stateListAnimator">@anim/media_button_state_list_animator</item>
+ </style>
+
<style name="MediaPlayer.OutlineButton">
<item name="android:background">@drawable/qs_media_outline_button</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
@@ -699,6 +702,10 @@
<item name="overlayButtonTextColor">?android:attr/textColorPrimary</item>
</style>
+ <style name="EditTextActivityButton" parent="@android:style/Widget.DeviceDefault.Button.Colored">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+
<!-- Clipboard overlay's edit text activity. -->
<style name="EditTextActivity" parent="@android:style/Theme.DeviceDefault.DayNight">
<item name="android:windowNoTitle">true</item>
diff --git a/packages/SystemUI/res/xml/media_session_expanded.xml b/packages/SystemUI/res/xml/media_session_expanded.xml
index 10da704..bec4e7a 100644
--- a/packages/SystemUI/res/xml/media_session_expanded.xml
+++ b/packages/SystemUI/res/xml/media_session_expanded.xml
@@ -31,25 +31,24 @@
android:id="@+id/header_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
android:layout_marginStart="@dimen/qs_media_padding"
android:layout_marginEnd="@dimen/qs_media_padding"
app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
app:layout_constrainedWidth="true"
- app:layout_constraintTop_toBottomOf="@id/icon"
app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/header_artist"
app:layout_constraintHorizontal_bias="0" />
<Constraint
android:id="@+id/header_artist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/qs_media_padding"
+ android:layout_marginBottom="@dimen/qs_media_padding"
android:layout_marginTop="0dp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
- app:layout_constraintBottom_toTopOf="@id/media_action_barrier"
- app:layout_constraintTop_toBottomOf="@id/header_title"
app:layout_constraintStart_toStartOf="@id/header_title"
+ app:layout_constraintBottom_toTopOf="@id/media_action_barrier_top"
app:layout_constraintVertical_bias="0"
app:layout_constraintHorizontal_bias="0" />
@@ -59,10 +58,9 @@
android:layout_height="48dp"
android:layout_marginStart="@dimen/qs_media_padding"
android:layout_marginEnd="@dimen/qs_media_padding"
- android:layout_marginBottom="0dp"
+ android:layout_marginBottom="@dimen/qs_media_padding"
app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/media_seamless"
- app:layout_constraintBottom_toBottomOf="@id/header_artist" />
+ app:layout_constraintBottom_toTopOf="@id/media_action_barrier_top" />
<!--
The bottom row of action buttons should remain in the same order when RTL, so their constraints
@@ -76,7 +74,6 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/media_progress_bar"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toBottomOf="@id/header_artist"
app:layout_constraintHorizontal_chainStyle="spread" />
<Constraint
@@ -86,7 +83,6 @@
app:layout_constraintLeft_toRightOf="@id/actionPrev"
app:layout_constraintRight_toLeftOf="@id/actionNext"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toBottomOf="@id/header_artist"
app:layout_constraintHorizontal_weight="1" />
<Constraint
@@ -95,8 +91,7 @@
android:layout_height="48dp"
app:layout_constraintLeft_toRightOf="@id/media_progress_bar"
app:layout_constraintRight_toLeftOf="@id/action0"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toBottomOf="@id/header_artist" />
+ app:layout_constraintBottom_toBottomOf="parent" />
<Constraint
android:id="@+id/action0"
@@ -104,8 +99,7 @@
android:layout_height="48dp"
app:layout_constraintLeft_toRightOf="@id/actionNext"
app:layout_constraintRight_toLeftOf="@id/action1"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toBottomOf="@id/header_artist" />
+ app:layout_constraintBottom_toBottomOf="parent" />
<Constraint
android:id="@+id/action1"
@@ -113,8 +107,7 @@
android:layout_height="48dp"
app:layout_constraintLeft_toRightOf="@id/action0"
app:layout_constraintRight_toLeftOf="@id/action2"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toBottomOf="@id/header_artist" />
+ app:layout_constraintBottom_toBottomOf="parent" />
<Constraint
android:id="@+id/action2"
@@ -122,8 +115,7 @@
android:layout_height="48dp"
app:layout_constraintLeft_toRightOf="@id/action1"
app:layout_constraintRight_toLeftOf="@id/action3"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toBottomOf="@id/header_artist" />
+ app:layout_constraintBottom_toBottomOf="parent"/>
<Constraint
android:id="@+id/action3"
@@ -131,8 +123,7 @@
android:layout_height="48dp"
app:layout_constraintLeft_toRightOf="@id/action2"
app:layout_constraintRight_toLeftOf="@id/action4"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toBottomOf="@id/header_artist" />
+ app:layout_constraintBottom_toBottomOf="parent"/>
<Constraint
android:id="@+id/action4"
@@ -140,6 +131,5 @@
android:layout_height="48dp"
app:layout_constraintLeft_toRightOf="@id/action3"
app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toBottomOf="@id/header_artist" />
+ app:layout_constraintBottom_toBottomOf="parent" />
</ConstraintSet>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java
index 48f1b76..5cca4a6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java
@@ -40,4 +40,14 @@
* was running becomes ready for control.
*/
void onTasksAppeared(RemoteAnimationTargetCompat[] app);
+
+ /**
+ * Called to request that the current task tile be switched out for a screenshot (if not
+ * already). Once complete, onFinished should be called.
+ * @return true if this impl will call onFinished. No other onSwitchToScreenshot impls will
+ * be called afterwards (to avoid multiple calls to onFinished).
+ */
+ default boolean onSwitchToScreenshot(Runnable onFinished) {
+ return false;
+ }
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
index b61827a..4894c49 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
@@ -18,6 +18,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_OPEN;
@@ -244,6 +245,8 @@
RecentsAnimationListener recents) {
ArrayList<TransitionInfo.Change> openingTasks = null;
boolean cancelRecents = false;
+ boolean homeGoingAway = false;
+ boolean hasChangingApp = false;
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) {
@@ -257,8 +260,28 @@
}
openingTasks.add(change);
}
+ } else if (change.getMode() == TRANSIT_CLOSE
+ || change.getMode() == TRANSIT_TO_BACK) {
+ if (mRecentsTask.equals(change.getContainer())) {
+ homeGoingAway = true;
+ }
+ } else if (change.getMode() == TRANSIT_CHANGE) {
+ hasChangingApp = true;
}
}
+ if (hasChangingApp && homeGoingAway) {
+ // This happens when a visible app is expanding (usually PiP). In this case,
+ // The transition probably has a special-purpose animation, so finish recents
+ // now and let it do its animation (since recents is going to be occluded).
+ if (!recents.onSwitchToScreenshot(() -> {
+ finish(true /* toHome */, false /* userLeaveHint */);
+ })) {
+ Log.w(TAG, "Recents callback doesn't support support switching to screenshot"
+ + ", there might be a flicker.");
+ finish(true /* toHome */, false /* userLeaveHint */);
+ }
+ return false;
+ }
if (openingTasks == null) return false;
int pauseMatches = 0;
if (!cancelRecents) {
@@ -331,13 +354,12 @@
}
if (mWrapped != null) mWrapped.finish(toHome, sendUserLeaveHint);
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
- final WindowContainerTransaction wct;
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
if (!toHome && mPausingTasks != null && mOpeningLeashes == null) {
// The gesture went back to opening the app rather than continuing with
// recents, so end the transition by moving the app back to the top (and also
// re-showing it's task).
- wct = new WindowContainerTransaction();
for (int i = mPausingTasks.size() - 1; i >= 0; --i) {
// reverse order so that index 0 ends up on top
wct.reorder(mPausingTasks.get(i), true /* onTop */);
@@ -347,8 +369,14 @@
wct.restoreTransientOrder(mRecentsTask);
}
} else {
- wct = null;
- if (mPipTask != null && mPipTransaction != null) {
+ if (!sendUserLeaveHint) {
+ for (int i = 0; i < mPausingTasks.size(); ++i) {
+ // This means recents is not *actually* finishing, so of course we gotta
+ // do special stuff in WMCore to accommodate.
+ wct.setDoNotPip(mPausingTasks.get(i));
+ }
+ }
+ if (mPipTask != null && mPipTransaction != null && sendUserLeaveHint) {
t.show(mInfo.getChange(mPipTask).getLeash());
PictureInPictureSurfaceTransaction.apply(mPipTransaction,
mInfo.getChange(mPipTask).getLeash(), t);
@@ -363,7 +391,7 @@
t.remove(mLeashMap.valueAt(i));
}
try {
- mFinishCB.onTransitionFinished(wct, t);
+ mFinishCB.onTransitionFinished(wct.isEmpty() ? null : wct, t);
} catch (RemoteException e) {
Log.e("RemoteTransitionCompat", "Failed to call animation finish callback", e);
t.apply();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
index 15593ea..9e5aeb8 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
@@ -16,6 +16,7 @@
package com.android.systemui.unfold
+import android.app.ActivityManager
import android.content.ContentResolver
import android.content.Context
import android.hardware.SensorManager
@@ -51,6 +52,7 @@
@BindsInstance config: UnfoldTransitionConfig,
@BindsInstance screenStatusProvider: ScreenStatusProvider,
@BindsInstance deviceStateManager: DeviceStateManager,
+ @BindsInstance activityManager: ActivityManager,
@BindsInstance sensorManager: SensorManager,
@BindsInstance @Main handler: Handler,
@BindsInstance @Main executor: Executor,
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
index 8e4ff9b..cc56007c 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
@@ -17,6 +17,7 @@
package com.android.systemui.unfold
+import android.app.ActivityManager
import android.content.Context
import android.hardware.SensorManager
import android.hardware.devicestate.DeviceStateManager
@@ -39,6 +40,7 @@
config: UnfoldTransitionConfig,
screenStatusProvider: ScreenStatusProvider,
deviceStateManager: DeviceStateManager,
+ activityManager: ActivityManager,
sensorManager: SensorManager,
mainHandler: Handler,
mainExecutor: Executor,
@@ -51,6 +53,7 @@
config,
screenStatusProvider,
deviceStateManager,
+ activityManager,
sensorManager,
mainHandler,
mainExecutor,
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
index 5266f09..3daae75 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
@@ -33,7 +33,7 @@
import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
/** Maps fold updates to unfold transition progress using DynamicAnimation. */
-internal class PhysicsBasedUnfoldTransitionProgressProvider(
+class PhysicsBasedUnfoldTransitionProgressProvider(
private val foldStateProvider: FoldStateProvider
) : UnfoldTransitionProgressProvider, FoldUpdatesListener, DynamicAnimation.OnAnimationEndListener {
@@ -97,7 +97,17 @@
FOLD_UPDATE_START_CLOSING -> {
// The transition might be already running as the device might start closing several
// times before reaching an end state.
- if (!isTransitionRunning) {
+ if (isTransitionRunning) {
+ // If we are cancelling the animation, reset that so we can resume it normally.
+ // The animation could be 'cancelled' when the user stops folding/unfolding
+ // for some period of time or fully unfolds the device. In this case,
+ // it is forced to run to the end ignoring all further hinge angle events.
+ // By resetting this flag we allow reacting to hinge angle events again, so
+ // the transition continues running.
+ if (isAnimatedCancelRunning) {
+ isAnimatedCancelRunning = false
+ }
+ } else {
startTransition(startValue = 1f)
}
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
index 24ecf87..ed973d6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
@@ -16,6 +16,8 @@
package com.android.systemui.unfold.updates
import android.annotation.FloatRange
+import android.app.ActivityManager
+import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
import android.content.Context
import android.hardware.devicestate.DeviceStateManager
import android.os.Handler
@@ -39,6 +41,7 @@
private val hingeAngleProvider: HingeAngleProvider,
private val screenStatusProvider: ScreenStatusProvider,
private val deviceStateManager: DeviceStateManager,
+ private val activityManager: ActivityManager,
@Main private val mainExecutor: Executor,
@Main private val handler: Handler
) : FoldStateProvider {
@@ -92,10 +95,12 @@
}
val isClosing = angle < lastHingeAngle
+ val closingThreshold = getClosingThreshold()
+ val closingThresholdMet = closingThreshold == null || angle < closingThreshold
val isFullyOpened = FULLY_OPEN_DEGREES - angle < FULLY_OPEN_THRESHOLD_DEGREES
val closingEventDispatched = lastFoldUpdate == FOLD_UPDATE_START_CLOSING
- if (isClosing && !closingEventDispatched && !isFullyOpened) {
+ if (isClosing && closingThresholdMet && !closingEventDispatched && !isFullyOpened) {
notifyFoldUpdate(FOLD_UPDATE_START_CLOSING)
}
@@ -113,6 +118,28 @@
outputListeners.forEach { it.onHingeAngleUpdate(angle) }
}
+ /**
+ * Fold animation should be started only after the threshold returned here.
+ *
+ * This has been introduced because the fold animation might be distracting/unwanted on top of
+ * apps that support table-top/HALF_FOLDED mode. Only for launcher, there is no threshold.
+ */
+ private fun getClosingThreshold(): Int? {
+ val activityType =
+ activityManager.getRunningTasks(/* maxNum= */ 1)?.getOrNull(0)?.topActivityType
+ ?: return null
+
+ if (DEBUG) {
+ Log.d(TAG, "activityType=" + activityType)
+ }
+
+ return if (activityType == ACTIVITY_TYPE_HOME) {
+ null
+ } else {
+ START_CLOSING_ON_APPS_THRESHOLD_DEGREES
+ }
+ }
+
private inner class FoldStateListener(context: Context) :
DeviceStateManager.FoldStateListener(
context,
@@ -199,7 +226,10 @@
* Time after which [FOLD_UPDATE_FINISH_HALF_OPEN] is emitted following a
* [FOLD_UPDATE_START_CLOSING] or [FOLD_UPDATE_START_OPENING] event, if an end state is not reached.
*/
-@VisibleForTesting const val HALF_OPENED_TIMEOUT_MILLIS = 1000L
+@VisibleForTesting const val HALF_OPENED_TIMEOUT_MILLIS = 600L
/** Threshold after which we consider the device fully unfolded. */
@VisibleForTesting const val FULLY_OPEN_THRESHOLD_DEGREES = 15f
+
+/** Fold animation on top of apps only when the angle exceeds this threshold. */
+@VisibleForTesting const val START_CLOSING_ON_APPS_THRESHOLD_DEGREES = 60
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index d02b875..b18abf3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -76,8 +76,7 @@
// Cause a VIRTUAL_KEY vibration
public void doHapticKeyClick() {
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
- HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
- | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
}
public void setKeyDownListener(KeyDownListener keyDownListener) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 46a88319..3103219 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -307,8 +307,6 @@
void onResume(SecurityMode securityMode, boolean faceAuthEnabled) {
mSecurityViewFlipper.setWindowInsetsAnimationCallback(mWindowInsetsAnimationCallback);
updateBiometricRetry(securityMode, faceAuthEnabled);
-
- setupViewMode();
}
void initMode(@Mode int mode, GlobalSettings globalSettings, FalsingManager falsingManager,
@@ -1044,11 +1042,13 @@
/**
* Moves the bouncer to align with a tap (most likely in the shade), so the bouncer
- * appears on the same side as a touch. Will not update the user-preference.
+ * appears on the same side as a touch.
*/
@Override
public void updatePositionByTouchX(float x) {
- updateSecurityViewLocation(x <= mView.getWidth() / 2f, /* animate= */false);
+ boolean isTouchOnLeft = x <= mView.getWidth() / 2f;
+ updateSideSetting(isTouchOnLeft);
+ updateSecurityViewLocation(isTouchOnLeft, /* animate= */false);
}
boolean isLeftAligned() {
@@ -1057,6 +1057,13 @@
== Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT;
}
+ private void updateSideSetting(boolean leftAligned) {
+ mGlobalSettings.putInt(
+ Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
+ leftAligned ? Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT
+ : Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT);
+ }
+
/**
* Determine if a tap on this view is on the other side. If so, will animate positions
* and record the preference to always show on this side.
@@ -1070,10 +1077,7 @@
|| (!currentlyLeftAligned && (x < mView.getWidth() / 2f))) {
boolean willBeLeftAligned = !currentlyLeftAligned;
- mGlobalSettings.putInt(
- Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
- willBeLeftAligned ? Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT
- : Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT);
+ updateSideSetting(willBeLeftAligned);
int keyguardState = willBeLeftAligned
? SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SWITCH_LEFT
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 57997d8..1a325d3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -233,6 +233,13 @@
mSecurityViewFlipperController.reloadColors();
}
};
+ private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onDevicePolicyManagerStateChanged() {
+ showPrimarySecurityScreen(false);
+ }
+ };
private KeyguardSecurityContainerController(KeyguardSecurityContainer view,
AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory,
@@ -279,6 +286,7 @@
@Override
protected void onViewAttached() {
+ mUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
mView.setSwipeListener(mSwipeListener);
mView.addMotionEventListener(mGlobalTouchListener);
mConfigurationController.addCallback(mConfigurationListener);
@@ -286,6 +294,7 @@
@Override
protected void onViewDetached() {
+ mUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
mConfigurationController.removeCallback(mConfigurationListener);
mView.removeMotionEventListener(mGlobalTouchListener);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 5602f3d..fcabbbc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2723,12 +2723,20 @@
}
/**
- * Handle {@link #MSG_DPM_STATE_CHANGED}
+ * Handle {@link #MSG_DPM_STATE_CHANGED} which can change primary authentication methods to
+ * pin/pattern/password/none.
*/
private void handleDevicePolicyManagerStateChanged(int userId) {
Assert.isMainThread();
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
updateSecondaryLockscreenRequirement(userId);
+
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onDevicePolicyManagerStateChanged();
+ }
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index ad2053c..9373ea8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -300,6 +300,11 @@
public void onSecondaryLockscreenRequirementChanged(int userId) { }
/**
+ * Called when device policy manager state changes.
+ */
+ public void onDevicePolicyManagerStateChanged() { }
+
+ /**
* Called when notifying user to unlock in order to use NFC.
*/
public void onRequireUnlockForNfc() { }
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index a4a0105f..6f0cd47 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -212,13 +212,13 @@
updateBurnInOffsets();
updateVisibility();
- mAccessibilityManager.addTouchExplorationStateChangeListener(
- mTouchExplorationStateChangeListener);
+ mAccessibilityManager.addAccessibilityStateChangeListener(
+ mAccessibilityStateChangeListener);
updateAccessibility();
}
private void updateAccessibility() {
- if (mAccessibilityManager.isTouchExplorationEnabled()) {
+ if (mAccessibilityManager.isEnabled()) {
mView.setOnClickListener(mA11yClickListener);
} else {
mView.setOnClickListener(null);
@@ -238,8 +238,8 @@
mCancelDelayedUpdateVisibilityRunnable = null;
}
- mAccessibilityManager.removeTouchExplorationStateChangeListener(
- mTouchExplorationStateChangeListener);
+ mAccessibilityManager.removeAccessibilityStateChangeListener(
+ mAccessibilityStateChangeListener);
}
public float getTop() {
@@ -721,6 +721,6 @@
private final View.OnClickListener mA11yClickListener = v -> onLongPress();
- private final AccessibilityManager.TouchExplorationStateChangeListener
- mTouchExplorationStateChangeListener = enabled -> updateAccessibility();
+ private final AccessibilityManager.AccessibilityStateChangeListener
+ mAccessibilityStateChangeListener = enabled -> updateAccessibility();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 5cab547..f771c97 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -219,7 +219,6 @@
// Cause a VIRTUAL_KEY vibration
public void doHapticKeyClick() {
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
- HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
- | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
index 0118813..22c6937 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
@@ -369,15 +369,10 @@
* Update the rounded corner size.
*/
fun updateRoundedCornerSize(top: Int, bottom: Int) {
- if (roundedCornerTopSize == top && roundedCornerBottomSize == bottom) {
- return
- }
roundedCornerTopSize = top
roundedCornerBottomSize = bottom
updateRoundedCornerDrawableBounds()
-
- // Use requestLayout() to trigger transparent region recalculated
- requestLayout()
+ invalidate()
}
private fun updateRoundedCornerDrawableBounds() {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 5de09b1..2ec9174 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -77,7 +77,6 @@
import com.android.systemui.decor.DecorProviderKt;
import com.android.systemui.decor.OverlayWindow;
import com.android.systemui.decor.PrivacyDotDecorProviderFactory;
-import com.android.systemui.decor.RoundedCornerDecorProviderFactory;
import com.android.systemui.decor.RoundedCornerResDelegate;
import com.android.systemui.qs.SettingObserver;
import com.android.systemui.settings.UserTracker;
@@ -139,12 +138,10 @@
@VisibleForTesting
protected RoundedCornerResDelegate mRoundedCornerResDelegate;
@VisibleForTesting
- protected DecorProviderFactory mRoundedCornerFactory;
- private int mProviderRefreshToken = 0;
- @VisibleForTesting
protected OverlayWindow[] mOverlays = null;
+ @VisibleForTesting
@Nullable
- private DisplayCutoutView[] mCutoutViews;
+ DisplayCutoutView[] mCutoutViews;
@VisibleForTesting
ViewGroup mScreenDecorHwcWindow;
@VisibleForTesting
@@ -296,11 +293,11 @@
mDisplayUniqueId = mContext.getDisplay().getUniqueId();
mRoundedCornerResDelegate = new RoundedCornerResDelegate(mContext.getResources(),
mDisplayUniqueId);
- mRoundedCornerFactory = new RoundedCornerDecorProviderFactory(mRoundedCornerResDelegate);
mWindowManager = mContext.getSystemService(WindowManager.class);
mDisplayManager = mContext.getSystemService(DisplayManager.class);
mHwcScreenDecorationSupport = mContext.getDisplay().getDisplayDecorationSupport();
- updateHwLayerRoundedCornerDrawable();
+ updateRoundedCornerDrawable();
+ updateRoundedCornerRadii();
setupDecorations();
setupCameraListener();
@@ -352,7 +349,7 @@
final String newUniqueId = mContext.getDisplay().getUniqueId();
if (!Objects.equals(newUniqueId, mDisplayUniqueId)) {
mDisplayUniqueId = newUniqueId;
- mRoundedCornerResDelegate.updateDisplayUniqueId(newUniqueId, null);
+ mRoundedCornerResDelegate.reloadAll(newUniqueId);
final DisplayDecorationSupport newScreenDecorationSupport =
mContext.getDisplay().getDisplayDecorationSupport();
// When the value of mSupportHwcScreenDecoration is changed, re-setup the whole
@@ -363,12 +360,22 @@
setupDecorations();
return;
}
- updateHwLayerRoundedCornerDrawable();
+ updateRoundedCornerDrawable();
+ }
+ if (mCutoutViews != null) {
+ final int size = mCutoutViews.length;
+ for (int i = 0; i < size; i++) {
+ final DisplayCutoutView cutoutView = mCutoutViews[i];
+ if (cutoutView == null) {
+ continue;
+ }
+ cutoutView.onDisplayChanged(displayId);
+ }
}
if (mScreenDecorHwcLayer != null) {
mScreenDecorHwcLayer.onDisplayChanged(displayId);
}
- updateView();
+ updateOrientation();
}
};
@@ -410,22 +417,22 @@
}
private void setupDecorations() {
- if (hasRoundedCorners() || shouldDrawCutout() || isPrivacyDotEnabled()) {
- List<DecorProvider> decorProviders = new ArrayList<>(mDotFactory.getProviders());
+ List<DecorProvider> decorProviders = mDotFactory.getProviders();
+
+ if (hasRoundedCorners() || shouldDrawCutout() || !decorProviders.isEmpty()) {
if (mHwcScreenDecorationSupport != null) {
createHwcOverlay();
} else {
removeHwcOverlay();
- decorProviders.addAll(mRoundedCornerFactory.getProviders());
}
final DisplayCutout cutout = getCutout();
for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
- if (shouldShowSwLayerCutout(i, cutout) || shouldShowSwLayerRoundedCorner(i, cutout)
- || shouldShowSwLayerPrivacyDot(i, cutout)) {
+ if (shouldShowCutout(i, cutout) || shouldShowRoundedCorner(i, cutout)
+ || shouldShowPrivacyDot(i, cutout)) {
Pair<List<DecorProvider>, List<DecorProvider>> pair =
DecorProviderKt.partitionAlignedBound(decorProviders, i);
decorProviders = pair.getSecond();
- createOverlay(i, pair.getFirst());
+ createOverlay(i, cutout, pair.getFirst());
} else {
removeOverlay(i);
}
@@ -526,6 +533,7 @@
private void createOverlay(
@BoundsPosition int pos,
+ @Nullable DisplayCutout cutout,
@NonNull List<DecorProvider> decorProviders) {
if (mOverlays == null) {
mOverlays = new OverlayWindow[BOUNDS_POSITION_LENGTH];
@@ -550,7 +558,7 @@
mCutoutViews[pos] = new DisplayCutoutView(mContext, pos);
mCutoutViews[pos].setColor(mTintColor);
overlayView.addView(mCutoutViews[pos]);
- mCutoutViews[pos].updateRotation(mRotation);
+ updateView(pos, cutout);
}
mWindowManager.addView(overlayView, getWindowLayoutParams(pos));
@@ -606,7 +614,7 @@
private OverlayWindow overlayForPosition(
@BoundsPosition int pos,
@NonNull List<DecorProvider> decorProviders) {
- final OverlayWindow currentOverlay = new OverlayWindow(mContext);
+ final OverlayWindow currentOverlay = new OverlayWindow(LayoutInflater.from(mContext), pos);
decorProviders.forEach(provider -> {
removeOverlayView(provider.getViewId());
currentOverlay.addDecorProvider(provider, mRotation);
@@ -620,16 +628,22 @@
return currentOverlay;
}
- private void updateView() {
- if (mOverlays == null) {
+ private void updateView(@BoundsPosition int pos, @Nullable DisplayCutout cutout) {
+ if (mOverlays == null || mOverlays[pos] == null || mHwcScreenDecorationSupport != null) {
return;
}
- ++mProviderRefreshToken;
- for (final OverlayWindow overlay: mOverlays) {
- if (overlay == null) {
- continue;
- }
- overlay.onReloadResAndMeasure(null, mProviderRefreshToken, mRotation, mDisplayUniqueId);
+
+ // update rounded corner view rotation
+ updateRoundedCornerView(pos, R.id.left, cutout);
+ updateRoundedCornerView(pos, R.id.right, cutout);
+ updateRoundedCornerSize(
+ mRoundedCornerResDelegate.getTopRoundedSize(),
+ mRoundedCornerResDelegate.getBottomRoundedSize());
+ updateRoundedCornerImageView();
+
+ // update cutout view rotation
+ if (mCutoutViews != null && mCutoutViews[pos] != null) {
+ mCutoutViews[pos].updateRotation(mRotation);
}
}
@@ -803,6 +817,7 @@
int oldRotation = mRotation;
mPendingRotationChange = false;
updateOrientation();
+ updateRoundedCornerRadii();
if (DEBUG) Log.i(TAG, "onConfigChanged from rot " + oldRotation + " to " + mRotation);
setupDecorations();
if (mOverlays != null) {
@@ -862,32 +877,109 @@
mDotViewController.setNewRotation(newRotation);
}
- if (!mPendingRotationChange && newRotation != mRotation) {
+ if (mPendingRotationChange) {
+ return;
+ }
+ if (newRotation != mRotation) {
mRotation = newRotation;
if (mScreenDecorHwcLayer != null) {
mScreenDecorHwcLayer.pendingRotationChange = false;
mScreenDecorHwcLayer.updateRotation(mRotation);
- updateHwLayerRoundedCornerSize();
- updateHwLayerRoundedCornerDrawable();
}
- updateLayoutParams();
- // update cutout view rotation
- if (mCutoutViews != null) {
- for (final DisplayCutoutView cutoutView: mCutoutViews) {
- if (cutoutView == null) {
+ if (mOverlays != null) {
+ updateLayoutParams();
+ final DisplayCutout cutout = getCutout();
+ for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
+ if (mOverlays[i] == null) {
continue;
}
- cutoutView.updateRotation(mRotation);
+ updateView(i, cutout);
}
}
}
-
- // update views
- updateView();
}
+ private void updateRoundedCornerRadii() {
+ // We should eventually move to just using the intrinsic size of the drawables since
+ // they should be sized to the exact pixels they want to cover. Therefore I'm purposely not
+ // upgrading all of the configs to contain (width, height) pairs. Instead assume that a
+ // device configured using the single integer config value is okay with drawing the corners
+ // as a square
+ final Size oldRoundedDefaultTop = mRoundedCornerResDelegate.getTopRoundedSize();
+ final Size oldRoundedDefaultBottom = mRoundedCornerResDelegate.getBottomRoundedSize();
+ mRoundedCornerResDelegate.reloadAll(mDisplayUniqueId);
+ final Size newRoundedDefaultTop = mRoundedCornerResDelegate.getTopRoundedSize();
+ final Size newRoundedDefaultBottom = mRoundedCornerResDelegate.getBottomRoundedSize();
+
+ if (oldRoundedDefaultTop.getWidth() != newRoundedDefaultTop.getWidth()
+ || oldRoundedDefaultBottom.getWidth() != newRoundedDefaultBottom.getWidth()) {
+ onTuningChanged(SIZE, null);
+ }
+ }
+
+ private void updateRoundedCornerView(@BoundsPosition int pos, int id,
+ @Nullable DisplayCutout cutout) {
+ final View rounded = mOverlays[pos].getRootView().findViewById(id);
+ if (rounded == null) {
+ return;
+ }
+ rounded.setVisibility(View.GONE);
+ if (shouldShowRoundedCorner(pos, cutout)) {
+ final int gravity = getRoundedCornerGravity(pos, id == R.id.left);
+ ((FrameLayout.LayoutParams) rounded.getLayoutParams()).gravity = gravity;
+ setRoundedCornerOrientation(rounded, gravity);
+ rounded.setVisibility(View.VISIBLE);
+ }
+ }
+
+ private int getRoundedCornerGravity(@BoundsPosition int pos, boolean isStart) {
+ final int rotatedPos = getBoundPositionFromRotation(pos, mRotation);
+ switch (rotatedPos) {
+ case BOUNDS_POSITION_LEFT:
+ return isStart ? Gravity.TOP | Gravity.LEFT : Gravity.BOTTOM | Gravity.LEFT;
+ case BOUNDS_POSITION_TOP:
+ return isStart ? Gravity.TOP | Gravity.LEFT : Gravity.TOP | Gravity.RIGHT;
+ case BOUNDS_POSITION_RIGHT:
+ return isStart ? Gravity.TOP | Gravity.RIGHT : Gravity.BOTTOM | Gravity.RIGHT;
+ case BOUNDS_POSITION_BOTTOM:
+ return isStart ? Gravity.BOTTOM | Gravity.LEFT : Gravity.BOTTOM | Gravity.RIGHT;
+ default:
+ throw new IllegalArgumentException("Incorrect position: " + rotatedPos);
+ }
+ }
+
+ /**
+ * Configures the rounded corner drawable's view matrix based on the gravity.
+ *
+ * The gravity describes which corner to configure for, and the drawable we are rotating is
+ * assumed to be oriented for the top-left corner of the device regardless of the target corner.
+ * Therefore we need to rotate 180 degrees to get a bottom-left corner, and mirror in the x- or
+ * y-axis for the top-right and bottom-left corners.
+ */
+ private void setRoundedCornerOrientation(View corner, int gravity) {
+ corner.setRotation(0);
+ corner.setScaleX(1);
+ corner.setScaleY(1);
+ switch (gravity) {
+ case Gravity.TOP | Gravity.LEFT:
+ return;
+ case Gravity.TOP | Gravity.RIGHT:
+ corner.setScaleX(-1); // flip X axis
+ return;
+ case Gravity.BOTTOM | Gravity.LEFT:
+ corner.setScaleY(-1); // flip Y axis
+ return;
+ case Gravity.BOTTOM | Gravity.RIGHT:
+ corner.setRotation(180);
+ return;
+ default:
+ throw new IllegalArgumentException("Unsupported gravity: " + gravity);
+ }
+ }
private boolean hasRoundedCorners() {
- return mRoundedCornerFactory.getHasProviders();
+ return mRoundedCornerResDelegate.getBottomRoundedSize().getWidth() > 0
+ || mRoundedCornerResDelegate.getTopRoundedSize().getWidth() > 0
+ || mRoundedCornerResDelegate.isMultipleRadius();
}
private boolean isDefaultShownOverlayPos(@BoundsPosition int pos,
@@ -906,19 +998,17 @@
}
}
- private boolean shouldShowSwLayerRoundedCorner(@BoundsPosition int pos,
+ private boolean shouldShowRoundedCorner(@BoundsPosition int pos,
@Nullable DisplayCutout cutout) {
return hasRoundedCorners() && isDefaultShownOverlayPos(pos, cutout)
&& mHwcScreenDecorationSupport == null;
}
- private boolean shouldShowSwLayerPrivacyDot(@BoundsPosition int pos,
- @Nullable DisplayCutout cutout) {
+ private boolean shouldShowPrivacyDot(@BoundsPosition int pos, @Nullable DisplayCutout cutout) {
return isPrivacyDotEnabled() && isDefaultShownOverlayPos(pos, cutout);
}
- private boolean shouldShowSwLayerCutout(@BoundsPosition int pos,
- @Nullable DisplayCutout cutout) {
+ private boolean shouldShowCutout(@BoundsPosition int pos, @Nullable DisplayCutout cutout) {
final Rect[] bounds = cutout == null ? null : cutout.getBoundingRectsAll();
final int rotatedPos = getBoundPositionFromRotation(pos, mRotation);
return (bounds != null && !bounds[rotatedPos].isEmpty()
@@ -953,33 +1043,54 @@
return;
}
mExecutor.execute(() -> {
- if (mOverlays == null || !SIZE.equals(key)) {
- return;
- }
- ++mProviderRefreshToken;
- try {
- final int sizeFactor = Integer.parseInt(newValue);
- mRoundedCornerResDelegate.updateTuningSizeFactor(sizeFactor, mProviderRefreshToken);
- } catch (NumberFormatException e) {
- mRoundedCornerResDelegate.updateTuningSizeFactor(null, mProviderRefreshToken);
- }
- Integer[] filterIds = {
- R.id.rounded_corner_top_left,
- R.id.rounded_corner_top_right,
- R.id.rounded_corner_bottom_left,
- R.id.rounded_corner_bottom_right
- };
- for (final OverlayWindow overlay: mOverlays) {
- if (overlay == null) {
- continue;
+ if (mOverlays == null) return;
+ if (SIZE.equals(key)) {
+ if (newValue != null) {
+ try {
+ mRoundedCornerResDelegate.updateTuningSizeFactor(
+ Integer.parseInt(newValue));
+ } catch (Exception e) {
+ }
}
- overlay.onReloadResAndMeasure(filterIds, mProviderRefreshToken, mRotation,
- mDisplayUniqueId);
+ updateRoundedCornerSize(
+ mRoundedCornerResDelegate.getTopRoundedSize(),
+ mRoundedCornerResDelegate.getBottomRoundedSize());
}
- updateHwLayerRoundedCornerSize();
});
}
+ private void updateRoundedCornerDrawable() {
+ mRoundedCornerResDelegate.reloadAll(mDisplayUniqueId);
+ updateRoundedCornerImageView();
+ }
+
+ private void updateRoundedCornerImageView() {
+ final Drawable top = mRoundedCornerResDelegate.getTopRoundedDrawable();
+ final Drawable bottom = mRoundedCornerResDelegate.getBottomRoundedDrawable();
+
+ if (mScreenDecorHwcLayer != null) {
+ mScreenDecorHwcLayer.updateRoundedCornerDrawable(top, bottom);
+ return;
+ }
+
+ if (mOverlays == null) {
+ return;
+ }
+ final ColorStateList colorStateList = ColorStateList.valueOf(mTintColor);
+ for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
+ if (mOverlays[i] == null) {
+ continue;
+ }
+ final ViewGroup overlayView = mOverlays[i].getRootView();
+ ((ImageView) overlayView.findViewById(R.id.left)).setImageTintList(colorStateList);
+ ((ImageView) overlayView.findViewById(R.id.right)).setImageTintList(colorStateList);
+ ((ImageView) overlayView.findViewById(R.id.left)).setImageDrawable(
+ isTopRoundedCorner(i, R.id.left) ? top : bottom);
+ ((ImageView) overlayView.findViewById(R.id.right)).setImageDrawable(
+ isTopRoundedCorner(i, R.id.right) ? top : bottom);
+ }
+ }
+
private void updateHwLayerRoundedCornerDrawable() {
if (mScreenDecorHwcLayer == null) {
return;
@@ -994,6 +1105,25 @@
mScreenDecorHwcLayer.updateRoundedCornerDrawable(topDrawable, bottomDrawable);
}
+ @VisibleForTesting
+ boolean isTopRoundedCorner(@BoundsPosition int pos, int id) {
+ switch (pos) {
+ case BOUNDS_POSITION_LEFT:
+ case BOUNDS_POSITION_RIGHT:
+ if (mRotation == ROTATION_270) {
+ return id == R.id.left ? false : true;
+ } else {
+ return id == R.id.left ? true : false;
+ }
+ case BOUNDS_POSITION_TOP:
+ return true;
+ case BOUNDS_POSITION_BOTTOM:
+ return false;
+ default:
+ throw new IllegalArgumentException("Unknown bounds position");
+ }
+ }
+
private void updateHwLayerRoundedCornerSize() {
if (mScreenDecorHwcLayer == null) {
return;
@@ -1005,6 +1135,28 @@
mScreenDecorHwcLayer.updateRoundedCornerSize(topWidth, bottomWidth);
}
+ private void updateRoundedCornerSize(Size sizeTop, Size sizeBottom) {
+
+ if (mScreenDecorHwcLayer != null) {
+ mScreenDecorHwcLayer.updateRoundedCornerSize(sizeTop.getWidth(), sizeBottom.getWidth());
+ return;
+ }
+
+ if (mOverlays == null) {
+ return;
+ }
+ for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
+ if (mOverlays[i] == null) {
+ continue;
+ }
+ final ViewGroup overlayView = mOverlays[i].getRootView();
+ setSize(overlayView.findViewById(R.id.left),
+ isTopRoundedCorner(i, R.id.left) ? sizeTop : sizeBottom);
+ setSize(overlayView.findViewById(R.id.right),
+ isTopRoundedCorner(i, R.id.right) ? sizeTop : sizeBottom);
+ }
+ }
+
@VisibleForTesting
protected void setSize(View view, Size pixelSize) {
LayoutParams params = view.getLayoutParams();
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
index 4c00735..085bcfa 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
@@ -33,6 +33,8 @@
import android.hardware.fingerprint.ISidefpsController
import android.os.Handler
import android.util.Log
+import android.view.View.AccessibilityDelegate
+import android.view.accessibility.AccessibilityEvent
import android.view.Display
import android.view.Gravity
import android.view.LayoutInflater
@@ -181,6 +183,23 @@
}
lottie.addOverlayDynamicColor(context)
+ /**
+ * Intercepts TYPE_WINDOW_STATE_CHANGED accessibility event, preventing Talkback from
+ * speaking @string/accessibility_fingerprint_label twice when sensor location indicator
+ * is in focus
+ */
+ view.setAccessibilityDelegate(object : AccessibilityDelegate() {
+ override fun dispatchPopulateAccessibilityEvent(
+ host: View,
+ event: AccessibilityEvent
+ ): Boolean {
+ return if (event.getEventType() === AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+ true
+ } else {
+ super.dispatchPopulateAccessibilityEvent(host, event)
+ }
+ }
+ })
return view
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
index 631a461..f3a603f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
@@ -22,6 +22,7 @@
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
+import android.view.accessibility.AccessibilityManager;
import android.view.animation.Interpolator;
import android.view.animation.OvershootInterpolator;
@@ -71,7 +72,13 @@
public UdfpsEnrollProgressBarDrawable(@NonNull Context context) {
mStrokeWidthPx = Utils.dpToPixels(context, STROKE_WIDTH_DP);
mProgressColor = context.getColor(R.color.udfps_enroll_progress);
- mHelpColor = context.getColor(R.color.udfps_enroll_progress_help);
+ final AccessibilityManager am = context.getSystemService(AccessibilityManager.class);
+ final boolean isAccessbilityEnabled = am.isTouchExplorationEnabled();
+ if (!isAccessbilityEnabled) {
+ mHelpColor = context.getColor(R.color.udfps_enroll_progress_help);
+ } else {
+ mHelpColor = context.getColor(R.color.udfps_enroll_progress_help_with_talkback);
+ }
mCheckmarkDrawable = context.getDrawable(R.drawable.udfps_enroll_checkmark);
mCheckmarkDrawable.mutate();
mCheckmarkInterpolator = new OvershootInterpolator();
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
index bbb75c3..0ff5805 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
@@ -60,6 +60,8 @@
* Use only for IntentFilters with actions and optionally categories. It does not support,
* permissions, schemes, data types, data authorities or priority different than 0.
* Cannot be used for getting sticky broadcasts (either as return of registering or as re-delivery).
+ * Broadcast handling may be asynchronous *without* calling goAsync(), as it's running within sysui
+ * and doesn't need to worry about being killed.
*/
open class BroadcastDispatcher constructor (
private val context: Context,
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index 0f937d1..be2397d 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -190,6 +190,13 @@
}
});
+ mTextPreview.getViewTreeObserver().addOnPreDrawListener(() -> {
+ int availableHeight = mTextPreview.getHeight()
+ - (mTextPreview.getPaddingTop() + mTextPreview.getPaddingBottom());
+ mTextPreview.setMaxLines(availableHeight / mTextPreview.getLineHeight());
+ return true;
+ });
+
mDismissButton.setOnClickListener(view -> animateOut());
mEditChip.setIcon(Icon.createWithResource(mContext, R.drawable.ic_screenshot_edit), true);
@@ -240,7 +247,10 @@
SELF_PERMISSION, null);
monitorOutsideTouches();
- mContext.sendBroadcast(new Intent(COPY_OVERLAY_ACTION), SELF_PERMISSION);
+ Intent copyIntent = new Intent(COPY_OVERLAY_ACTION);
+ // Set package name so the system knows it's safe
+ copyIntent.setPackage(mContext.getPackageName());
+ mContext.sendBroadcast(copyIntent, SELF_PERMISSION);
}
void setClipData(ClipData clipData, String clipSource) {
@@ -284,6 +294,7 @@
OverlayActionChip chip = constructActionChip(action);
mActionContainer.addView(chip);
mActionChips.add(chip);
+ break; // only show at most one action chip
}
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
index a57a135..1621cbc 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
@@ -45,7 +45,7 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.clipboard_edit_text_activity);
- findViewById(R.id.copy_button).setOnClickListener((v) -> saveToClipboard());
+ findViewById(R.id.done_button).setOnClickListener((v) -> saveToClipboard());
findViewById(R.id.share).setOnClickListener((v) -> share());
mEditText = findViewById(R.id.edit_text);
mAttribution = findViewById(R.id.attribution);
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
index e53f267..73faa34 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
@@ -18,6 +18,7 @@
import android.annotation.AnyThread
import android.annotation.MainThread
+import android.app.AlertDialog
import android.app.Dialog
import android.app.PendingIntent
import android.content.Context
@@ -27,7 +28,7 @@
import android.net.Uri
import android.os.Handler
import android.os.VibrationEffect
-import android.provider.Settings
+import android.provider.Settings.Secure
import android.service.controls.Control
import android.service.controls.actions.BooleanAction
import android.service.controls.actions.CommandAction
@@ -35,12 +36,17 @@
import android.util.Log
import android.view.HapticFeedbackConstants
import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.R
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.controls.ControlsMetricsLogger
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.settings.UserContextProvider
import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_CONTROLS_FILE
+import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_SETTINGS_DIALOG_ATTEMPTS
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.settings.SecureSettings
@@ -60,6 +66,7 @@
private val controlsMetricsLogger: ControlsMetricsLogger,
private val vibrator: VibratorHelper,
private val secureSettings: SecureSettings,
+ private val userContextProvider: UserContextProvider,
@Main mainHandler: Handler
) : ControlActionCoordinator {
private var dialog: Dialog? = null
@@ -68,22 +75,33 @@
private val isLocked: Boolean
get() = !keyguardStateController.isUnlocked()
private var mAllowTrivialControls: Boolean = secureSettings.getInt(
- Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
+ Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
+ private var mShowDeviceControlsInLockscreen: Boolean = secureSettings.getInt(
+ Secure.LOCKSCREEN_SHOW_CONTROLS, 0) != 0
override lateinit var activityContext: Context
companion object {
private const val RESPONSE_TIMEOUT_IN_MILLIS = 3000L
+ private const val MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG = 2
}
init {
val lockScreenShowControlsUri =
- secureSettings.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS)
+ secureSettings.getUriFor(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS)
+ val showControlsUri =
+ secureSettings.getUriFor(Secure.LOCKSCREEN_SHOW_CONTROLS)
val controlsContentObserver = object : ContentObserver(mainHandler) {
override fun onChange(selfChange: Boolean, uri: Uri?) {
super.onChange(selfChange, uri)
- if (uri == lockScreenShowControlsUri) {
- mAllowTrivialControls = secureSettings.getInt(
- Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
+ when (uri) {
+ lockScreenShowControlsUri -> {
+ mAllowTrivialControls = secureSettings.getInt(
+ Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
+ }
+ showControlsUri -> {
+ mShowDeviceControlsInLockscreen = secureSettings
+ .getInt(Secure.LOCKSCREEN_SHOW_CONTROLS, 0) != 0
+ }
}
}
}
@@ -91,6 +109,10 @@
lockScreenShowControlsUri,
false /* notifyForDescendants */, controlsContentObserver
)
+ secureSettings.registerContentObserver(
+ showControlsUri,
+ false /* notifyForDescendants */, controlsContentObserver
+ )
}
override fun closeDialogs() {
@@ -107,9 +129,9 @@
cvh.layout.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)
cvh.action(BooleanAction(templateId, !isChecked))
},
- true /* blockable */
- ),
- isAuthRequired(cvh, mAllowTrivialControls)
+ true /* blockable */,
+ cvh.cws.control?.isAuthRequired ?: true /* authIsRequired */
+ )
)
}
@@ -127,9 +149,9 @@
cvh.action(CommandAction(templateId))
}
},
- blockable
- ),
- isAuthRequired(cvh, mAllowTrivialControls)
+ blockable /* blockable */,
+ cvh.cws.control?.isAuthRequired ?: true /* authIsRequired */
+ )
)
}
@@ -147,9 +169,9 @@
createAction(
cvh.cws.ci.controlId,
{ cvh.action(FloatAction(templateId, newValue)) },
- false /* blockable */
- ),
- isAuthRequired(cvh, mAllowTrivialControls)
+ false /* blockable */,
+ cvh.cws.control?.isAuthRequired ?: true /* authIsRequired */
+ )
)
}
@@ -166,15 +188,16 @@
showDetail(cvh, it.getAppIntent())
}
},
- false /* blockable */
- ),
- isAuthRequired(cvh, mAllowTrivialControls)
+ false /* blockable */,
+ cvh.cws.control?.isAuthRequired ?: true /* authIsRequired */
+ )
)
}
override fun runPendingAction(controlId: String) {
if (isLocked) return
if (pendingAction?.controlId == controlId) {
+ showSettingsDialogIfNeeded(pendingAction!!)
pendingAction?.invoke()
pendingAction = null
}
@@ -185,12 +208,6 @@
actionsInProgress.remove(controlId)
}
- @VisibleForTesting()
- fun isAuthRequired(cvh: ControlViewHolder, allowTrivialControls: Boolean): Boolean {
- val isAuthRequired = cvh.cws.control?.isAuthRequired ?: true
- return isAuthRequired || !allowTrivialControls
- }
-
private fun shouldRunAction(controlId: String) =
if (actionsInProgress.add(controlId)) {
uiExecutor.executeDelayed({
@@ -203,7 +220,9 @@
@AnyThread
@VisibleForTesting
- fun bouncerOrRun(action: Action, authRequired: Boolean) {
+ fun bouncerOrRun(action: Action) {
+ val authRequired = action.authIsRequired || !mAllowTrivialControls
+
if (keyguardStateController.isShowing() && authRequired) {
if (isLocked) {
broadcastSender.closeSystemDialogs()
@@ -217,6 +236,7 @@
true
}, { pendingAction = null }, true /* afterKeyguardGone */)
} else {
+ showSettingsDialogIfNeeded(action)
action.invoke()
}
}
@@ -251,11 +271,88 @@
}
}
- @VisibleForTesting
- fun createAction(controlId: String, f: () -> Unit, blockable: Boolean) =
- Action(controlId, f, blockable)
+ private fun showSettingsDialogIfNeeded(action: Action) {
+ if (action.authIsRequired) {
+ return
+ }
+ val prefs = userContextProvider.userContext.getSharedPreferences(
+ PREFS_CONTROLS_FILE, Context.MODE_PRIVATE)
+ val attempts = prefs.getInt(PREFS_SETTINGS_DIALOG_ATTEMPTS, 0)
+ if (attempts >= MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG ||
+ (mShowDeviceControlsInLockscreen && mAllowTrivialControls)) {
+ return
+ }
+ val builder = AlertDialog
+ .Builder(activityContext, R.style.Theme_SystemUI_Dialog)
+ .setIcon(R.drawable.ic_warning)
+ .setOnCancelListener {
+ if (attempts < MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG) {
+ prefs.edit().putInt(PREFS_SETTINGS_DIALOG_ATTEMPTS, attempts + 1)
+ .commit()
+ }
+ true
+ }
+ .setNeutralButton(R.string.controls_settings_dialog_neutral_button) { _, _ ->
+ if (attempts != MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG) {
+ prefs.edit().putInt(PREFS_SETTINGS_DIALOG_ATTEMPTS,
+ MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG)
+ .commit()
+ }
+ true
+ }
- inner class Action(val controlId: String, val f: () -> Unit, val blockable: Boolean) {
+ if (mShowDeviceControlsInLockscreen) {
+ dialog = builder
+ .setTitle(R.string.controls_settings_trivial_controls_dialog_title)
+ .setMessage(R.string.controls_settings_trivial_controls_dialog_message)
+ .setPositiveButton(R.string.controls_settings_dialog_positive_button) { _, _ ->
+ if (attempts != MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG) {
+ prefs.edit().putInt(PREFS_SETTINGS_DIALOG_ATTEMPTS,
+ MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG)
+ .commit()
+ }
+ secureSettings.putInt(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 1)
+ true
+ }
+ .create()
+ } else {
+ dialog = builder
+ .setTitle(R.string.controls_settings_show_controls_dialog_title)
+ .setMessage(R.string.controls_settings_show_controls_dialog_message)
+ .setPositiveButton(R.string.controls_settings_dialog_positive_button) { _, _ ->
+ if (attempts != MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG) {
+ prefs.edit().putInt(PREFS_SETTINGS_DIALOG_ATTEMPTS,
+ MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG)
+ .commit()
+ }
+ secureSettings.putInt(Secure.LOCKSCREEN_SHOW_CONTROLS, 1)
+ secureSettings.putInt(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 1)
+ true
+ }
+ .create()
+ }
+
+ SystemUIDialog.registerDismissListener(dialog)
+ SystemUIDialog.setDialogSize(dialog)
+
+ dialog?.create()
+ dialog?.show()
+ }
+
+ @VisibleForTesting
+ fun createAction(
+ controlId: String,
+ f: () -> Unit,
+ blockable: Boolean,
+ authIsRequired: Boolean
+ ) = Action(controlId, f, blockable, authIsRequired)
+
+ inner class Action(
+ val controlId: String,
+ val f: () -> Unit,
+ val blockable: Boolean,
+ val authIsRequired: Boolean
+ ) {
fun invoke() {
if (!blockable || shouldRunAction(controlId)) {
f.invoke()
diff --git a/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt b/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
index 03ee8b1..3543bb4 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
@@ -15,8 +15,8 @@
*/
package com.android.systemui.decor
-import android.content.Context
import android.view.DisplayCutout
+import android.view.LayoutInflater
import android.view.Surface
import android.view.View
import android.view.ViewGroup
@@ -38,20 +38,9 @@
/** The aligned bounds for the view which is created through inflateView() */
abstract val alignedBounds: List<Int>
- /**
- * Called when res info changed.
- * Child provider needs to implement it if its view needs to be updated.
- */
- abstract fun onReloadResAndMeasure(
- view: View,
- reloadToken: Int,
- @Surface.Rotation rotation: Int,
- displayUniqueId: String? = null
- )
-
/** Inflate view into parent as current rotation */
abstract fun inflateView(
- context: Context,
+ inflater: LayoutInflater,
parent: ViewGroup,
@Surface.Rotation rotation: Int
): View
diff --git a/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt b/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
index f38ff14..9f8679c 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
@@ -16,22 +16,31 @@
package com.android.systemui.decor
import android.annotation.IdRes
-import android.content.Context
+import android.view.DisplayCutout
+import android.view.LayoutInflater
import android.view.Surface
import android.view.View
import android.view.ViewGroup
-import com.android.systemui.RegionInterceptingFrameLayout
+import com.android.systemui.R
+import java.util.HashMap
-class OverlayWindow(private val context: Context) {
+class OverlayWindow(private val layoutInflater: LayoutInflater, private val pos: Int) {
- val rootView = RegionInterceptingFrameLayout(context) as ViewGroup
- private val viewProviderMap = mutableMapOf<Int, Pair<View, DecorProvider>>()
+ private val layoutId: Int
+ get() {
+ return if (pos == DisplayCutout.BOUNDS_POSITION_LEFT ||
+ pos == DisplayCutout.BOUNDS_POSITION_TOP) {
+ R.layout.rounded_corners_top
+ } else {
+ R.layout.rounded_corners_bottom
+ }
+ }
- fun addDecorProvider(
- decorProvider: DecorProvider,
- @Surface.Rotation rotation: Int
- ) {
- val view = decorProvider.inflateView(context, rootView, rotation)
+ val rootView = layoutInflater.inflate(layoutId, null) as ViewGroup
+ private val viewProviderMap: MutableMap<Int, Pair<View, DecorProvider>> = HashMap()
+
+ fun addDecorProvider(decorProvider: DecorProvider, @Surface.Rotation rotation: Int) {
+ val view = decorProvider.inflateView(layoutInflater, rootView, rotation)
viewProviderMap[decorProvider.viewId] = Pair(view, decorProvider)
}
@@ -47,35 +56,4 @@
viewProviderMap.remove(id)
}
}
-
- /**
- * Apply new configuration info into views.
- * @param filterIds target view ids. Apply to all if null.
- * @param rotation current or new rotation direction.
- * @param displayUniqueId new displayUniqueId if any.
- */
- fun onReloadResAndMeasure(
- filterIds: Array<Int>? = null,
- reloadToken: Int,
- @Surface.Rotation rotation: Int,
- displayUniqueId: String? = null
- ) {
- filterIds?.forEach { id ->
- viewProviderMap[id]?.let {
- it.second.onReloadResAndMeasure(
- view = it.first,
- reloadToken = reloadToken,
- displayUniqueId = displayUniqueId,
- rotation = rotation)
- }
- } ?: run {
- viewProviderMap.values.forEach {
- it.second.onReloadResAndMeasure(
- view = it.first,
- reloadToken = reloadToken,
- displayUniqueId = displayUniqueId,
- rotation = rotation)
- }
- }
- }
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
index 136f135..7afd7e0e 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
@@ -16,7 +16,6 @@
package com.android.systemui.decor
-import android.content.Context
import android.content.res.Resources
import android.view.DisplayCutout
import android.view.LayoutInflater
@@ -77,21 +76,12 @@
private val layoutId: Int
) : CornerDecorProvider() {
- override fun onReloadResAndMeasure(
- view: View,
- reloadToken: Int,
- rotation: Int,
- displayUniqueId: String?
- ) {
- // Do nothing here because it is handled inside PrivacyDotViewController
- }
-
override fun inflateView(
- context: Context,
+ inflater: LayoutInflater,
parent: ViewGroup,
@Surface.Rotation rotation: Int
): View {
- LayoutInflater.from(context).inflate(layoutId, parent, true)
+ inflater.inflate(layoutId, parent, true)
return parent.getChildAt(parent.childCount - 1 /* latest new added child */)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt
deleted file mode 100644
index 4388b8b..0000000
--- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.decor
-
-import android.view.DisplayCutout
-import com.android.systemui.R
-
-class RoundedCornerDecorProviderFactory(
- private val roundedCornerResDelegate: RoundedCornerResDelegate
-) : DecorProviderFactory() {
-
- override val hasProviders: Boolean
- get() = roundedCornerResDelegate.run {
- // We don't consider isMultipleRadius here because it makes no sense if size is zero.
- topRoundedSize.width > 0 || bottomRoundedSize.width > 0
- }
-
- override val providers: List<DecorProvider>
- get() {
- val hasTop = roundedCornerResDelegate.topRoundedSize.width > 0
- val hasBottom = roundedCornerResDelegate.bottomRoundedSize.width > 0
- return when {
- hasTop && hasBottom -> listOf(
- RoundedCornerDecorProviderImpl(
- viewId = R.id.rounded_corner_top_left,
- alignedBound1 = DisplayCutout.BOUNDS_POSITION_TOP,
- alignedBound2 = DisplayCutout.BOUNDS_POSITION_LEFT,
- roundedCornerResDelegate = roundedCornerResDelegate),
- RoundedCornerDecorProviderImpl(
- viewId = R.id.rounded_corner_top_right,
- alignedBound1 = DisplayCutout.BOUNDS_POSITION_TOP,
- alignedBound2 = DisplayCutout.BOUNDS_POSITION_RIGHT,
- roundedCornerResDelegate = roundedCornerResDelegate),
- RoundedCornerDecorProviderImpl(
- viewId = R.id.rounded_corner_bottom_left,
- alignedBound1 = DisplayCutout.BOUNDS_POSITION_BOTTOM,
- alignedBound2 = DisplayCutout.BOUNDS_POSITION_LEFT,
- roundedCornerResDelegate = roundedCornerResDelegate),
- RoundedCornerDecorProviderImpl(
- viewId = R.id.rounded_corner_bottom_right,
- alignedBound1 = DisplayCutout.BOUNDS_POSITION_BOTTOM,
- alignedBound2 = DisplayCutout.BOUNDS_POSITION_RIGHT,
- roundedCornerResDelegate = roundedCornerResDelegate)
- )
- hasTop -> listOf(
- RoundedCornerDecorProviderImpl(
- viewId = R.id.rounded_corner_top_left,
- alignedBound1 = DisplayCutout.BOUNDS_POSITION_TOP,
- alignedBound2 = DisplayCutout.BOUNDS_POSITION_LEFT,
- roundedCornerResDelegate = roundedCornerResDelegate),
- RoundedCornerDecorProviderImpl(
- viewId = R.id.rounded_corner_top_right,
- alignedBound1 = DisplayCutout.BOUNDS_POSITION_TOP,
- alignedBound2 = DisplayCutout.BOUNDS_POSITION_RIGHT,
- roundedCornerResDelegate = roundedCornerResDelegate)
- )
- hasBottom -> listOf(
- RoundedCornerDecorProviderImpl(
- viewId = R.id.rounded_corner_bottom_left,
- alignedBound1 = DisplayCutout.BOUNDS_POSITION_BOTTOM,
- alignedBound2 = DisplayCutout.BOUNDS_POSITION_LEFT,
- roundedCornerResDelegate = roundedCornerResDelegate),
- RoundedCornerDecorProviderImpl(
- viewId = R.id.rounded_corner_bottom_right,
- alignedBound1 = DisplayCutout.BOUNDS_POSITION_BOTTOM,
- alignedBound2 = DisplayCutout.BOUNDS_POSITION_RIGHT,
- roundedCornerResDelegate = roundedCornerResDelegate)
- )
- else -> emptyList()
- }
- }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
deleted file mode 100644
index 90ff950..0000000
--- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.decor
-
-import android.content.Context
-import android.view.DisplayCutout
-import android.view.Gravity
-import android.view.Surface
-import android.view.View
-import android.view.ViewGroup
-import android.widget.FrameLayout
-import android.widget.ImageView
-import com.android.systemui.R
-
-class RoundedCornerDecorProviderImpl(
- override val viewId: Int,
- @DisplayCutout.BoundsPosition override val alignedBound1: Int,
- @DisplayCutout.BoundsPosition override val alignedBound2: Int,
- private val roundedCornerResDelegate: RoundedCornerResDelegate
-) : CornerDecorProvider() {
-
- private val isTop = alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_TOP)
-
- override fun inflateView(
- context: Context,
- parent: ViewGroup,
- @Surface.Rotation rotation: Int
- ): View {
- return ImageView(context).also { view ->
- // View
- view.id = viewId
- initView(view, rotation)
-
- // LayoutParams
- val layoutSize = if (isTop) {
- roundedCornerResDelegate.topRoundedSize
- } else {
- roundedCornerResDelegate.bottomRoundedSize
- }
- val params = FrameLayout.LayoutParams(
- layoutSize.width,
- layoutSize.height,
- alignedBound1.toLayoutGravity(rotation) or
- alignedBound2.toLayoutGravity(rotation))
-
- // AddView
- parent.addView(view, params)
- }
- }
-
- private fun initView(view: ImageView, @Surface.Rotation rotation: Int) {
- view.setRoundedCornerImage(roundedCornerResDelegate, isTop)
- view.adjustRotation(alignedBounds, rotation)
- view.setColorFilter(IMAGE_TINT_COLOR)
- }
-
- override fun onReloadResAndMeasure(
- view: View,
- reloadToken: Int,
- @Surface.Rotation rotation: Int,
- displayUniqueId: String?
- ) {
- roundedCornerResDelegate.updateDisplayUniqueId(displayUniqueId, reloadToken)
-
- initView((view as ImageView), rotation)
-
- val layoutSize = if (isTop) {
- roundedCornerResDelegate.topRoundedSize
- } else {
- roundedCornerResDelegate.bottomRoundedSize
- }
- (view.layoutParams as FrameLayout.LayoutParams).let {
- it.width = layoutSize.width
- it.height = layoutSize.height
- it.gravity = alignedBound1.toLayoutGravity(rotation) or
- alignedBound2.toLayoutGravity(rotation)
- view.setLayoutParams(it)
- }
- }
-}
-
-private const val IMAGE_TINT_COLOR: Int = 0xFF000000.toInt()
-
-@DisplayCutout.BoundsPosition
-private fun Int.toLayoutGravity(@Surface.Rotation rotation: Int): Int = when (rotation) {
- Surface.ROTATION_0 -> when (this) {
- DisplayCutout.BOUNDS_POSITION_LEFT -> Gravity.LEFT
- DisplayCutout.BOUNDS_POSITION_TOP -> Gravity.TOP
- DisplayCutout.BOUNDS_POSITION_RIGHT -> Gravity.RIGHT
- else /* DisplayCutout.BOUNDS_POSITION_BOTTOM */ -> Gravity.BOTTOM
- }
- Surface.ROTATION_90 -> when (this) {
- DisplayCutout.BOUNDS_POSITION_LEFT -> Gravity.BOTTOM
- DisplayCutout.BOUNDS_POSITION_TOP -> Gravity.LEFT
- DisplayCutout.BOUNDS_POSITION_RIGHT -> Gravity.TOP
- else /* DisplayCutout.BOUNDS_POSITION_BOTTOM */ -> Gravity.LEFT
- }
- Surface.ROTATION_270 -> when (this) {
- DisplayCutout.BOUNDS_POSITION_LEFT -> Gravity.TOP
- DisplayCutout.BOUNDS_POSITION_TOP -> Gravity.RIGHT
- DisplayCutout.BOUNDS_POSITION_RIGHT -> Gravity.BOTTOM
- else /* DisplayCutout.BOUNDS_POSITION_BOTTOM */ -> Gravity.LEFT
- }
- else /* Surface.ROTATION_180 */ -> when (this) {
- DisplayCutout.BOUNDS_POSITION_LEFT -> Gravity.RIGHT
- DisplayCutout.BOUNDS_POSITION_TOP -> Gravity.BOTTOM
- DisplayCutout.BOUNDS_POSITION_RIGHT -> Gravity.LEFT
- else /* DisplayCutout.BOUNDS_POSITION_BOTTOM */ -> Gravity.TOP
- }
-}
-
-private fun ImageView.setRoundedCornerImage(
- resDelegate: RoundedCornerResDelegate,
- isTop: Boolean
-) {
- val drawable = if (isTop)
- resDelegate.topRoundedDrawable
- else
- resDelegate.bottomRoundedDrawable
-
- if (drawable != null) {
- setImageDrawable(drawable)
- } else {
- setImageResource(
- if (isTop)
- R.drawable.rounded_corner_top
- else
- R.drawable.rounded_corner_bottom
- )
- }
-}
-
-/**
- * Configures the rounded corner drawable's view matrix based on the gravity.
- *
- * The gravity describes which corner to configure for, and the drawable we are rotating is assumed
- * to be oriented for the top-left corner of the device regardless of the target corner.
- * Therefore we need to rotate 180 degrees to get a bottom-left corner, and mirror in the x- or
- * y-axis for the top-right and bottom-left corners.
- */
-private fun ImageView.adjustRotation(alignedBounds: List<Int>, @Surface.Rotation rotation: Int) {
- var newRotation = 0F
- var newScaleX = 1F
- var newScaleY = 1F
-
- val isTop = alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_TOP)
- val isLeft = alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_LEFT)
- when (rotation) {
- Surface.ROTATION_0 -> when {
- isTop && isLeft -> {}
- isTop && !isLeft -> { newScaleX = -1F }
- !isTop && isLeft -> { newScaleY = -1F }
- else /* !isTop && !isLeft */ -> { newRotation = 180F }
- }
- Surface.ROTATION_90 -> when {
- isTop && isLeft -> { newScaleY = -1F }
- isTop && !isLeft -> {}
- !isTop && isLeft -> { newRotation = 180F }
- else /* !isTop && !isLeft */ -> { newScaleX = -1F }
- }
- Surface.ROTATION_270 -> when {
- isTop && isLeft -> { newScaleX = -1F }
- isTop && !isLeft -> { newRotation = 180F }
- !isTop && isLeft -> {}
- else /* !isTop && !isLeft */ -> { newScaleY = -1F }
- }
- else /* Surface.ROTATION_180 */ -> when {
- isTop && isLeft -> { newRotation = 180F }
- isTop && !isLeft -> { newScaleY = -1F }
- !isTop && isLeft -> { newScaleX = -1F }
- else /* !isTop && !isLeft */ -> {}
- }
- }
-
- this.rotation = newRotation
- this.scaleX = newScaleX
- this.scaleY = newScaleY
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
index 1d38e58..c817f89 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
@@ -36,8 +36,6 @@
private val density: Float
get() = res.displayMetrics.density
- private var reloadToken: Int = 0
-
var isMultipleRadius: Boolean = false
private set
@@ -62,26 +60,12 @@
reloadMeasures()
}
- private fun reloadAll(newReloadToken: Int) {
- if (reloadToken == newReloadToken) {
- return
- }
- reloadToken = newReloadToken
+ fun reloadAll(newDisplayUniqueId: String?) {
+ displayUniqueId = newDisplayUniqueId
reloadDrawables()
reloadMeasures()
}
- fun updateDisplayUniqueId(newDisplayUniqueId: String?, newReloadToken: Int?) {
- if (displayUniqueId != newDisplayUniqueId) {
- displayUniqueId = newDisplayUniqueId
- newReloadToken ?.let { reloadToken = it }
- reloadDrawables()
- reloadMeasures()
- } else {
- newReloadToken?.let { reloadAll(it) }
- }
- }
-
private fun reloadDrawables() {
val configIdx = DisplayUtils.getDisplayUniqueIdConfigIndex(res, displayUniqueId)
isMultipleRadius = getIsMultipleRadius(configIdx)
@@ -101,9 +85,7 @@
arrayResId = R.array.config_roundedCornerBottomDrawableArray,
backupDrawableId = R.drawable.rounded_corner_bottom
) ?: roundedDrawable
- }
- private fun reloadMeasures(roundedSizeFactor: Int? = null) {
// If config_roundedCornerMultipleRadius set as true, ScreenDecorations respect the
// (width, height) size of drawable/rounded.xml instead of rounded_corner_radius
if (isMultipleRadius) {
@@ -131,19 +113,44 @@
if (bottomRoundedSize.width == 0) {
bottomRoundedSize = roundedSize
}
+ }
- if (roundedSizeFactor != null && roundedSizeFactor > 0) {
- val length: Int = (roundedSizeFactor * density).toInt()
- topRoundedSize = Size(length, length)
- bottomRoundedSize = Size(length, length)
+ private fun reloadMeasures(roundedSizeFactor: Int? = null) {
+ // If config_roundedCornerMultipleRadius set as true, ScreenDecorations respect the
+ // (width, height) size of drawable/rounded.xml instead of rounded_corner_radius
+ if (isMultipleRadius) {
+ roundedSize = Size(
+ roundedDrawable?.intrinsicWidth ?: 0,
+ roundedDrawable?.intrinsicHeight ?: 0)
+ topRoundedDrawable?.let {
+ topRoundedSize = Size(it.intrinsicWidth, it.intrinsicHeight)
+ }
+ bottomRoundedDrawable?.let {
+ bottomRoundedSize = Size(it.intrinsicWidth, it.intrinsicHeight)
+ }
+ } else {
+ val defaultRadius = RoundedCorners.getRoundedCornerRadius(res, displayUniqueId)
+ val topRadius = RoundedCorners.getRoundedCornerTopRadius(res, displayUniqueId)
+ val bottomRadius = RoundedCorners.getRoundedCornerBottomRadius(res, displayUniqueId)
+ roundedSize = Size(defaultRadius, defaultRadius)
+ topRoundedSize = Size(topRadius, topRadius)
+ bottomRoundedSize = Size(bottomRadius, bottomRadius)
+ }
+
+ roundedSizeFactor ?.let {
+ val length: Int = (it * density).toInt()
+ roundedSize = Size(length, length)
+ }
+
+ if (topRoundedSize.width == 0) {
+ topRoundedSize = roundedSize
+ }
+ if (bottomRoundedSize.width == 0) {
+ bottomRoundedSize = roundedSize
}
}
- fun updateTuningSizeFactor(factor: Int?, newReloadToken: Int) {
- if (reloadToken == newReloadToken) {
- return
- }
- reloadToken = newReloadToken
+ fun updateTuningSizeFactor(factor: Int) {
reloadMeasures(factor)
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index 330bd6c..4561190 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -23,6 +23,7 @@
import android.view.View;
import android.view.ViewGroup;
+import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.complication.ComplicationHostViewController;
import com.android.systemui.dreams.dagger.DreamOverlayComponent;
@@ -93,9 +94,12 @@
@Override
public void onExpansionChanged(float bouncerHideAmount) {
if (!mBouncerAnimating) return;
+ final float scaledFraction =
+ BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(
+ bouncerHideAmount);
final int blurRadius =
- (int) mBlurUtils.blurRadiusOfRatio(1 - bouncerHideAmount);
- updateTransitionState(blurRadius, bouncerHideAmount);
+ (int) mBlurUtils.blurRadiusOfRatio(1 - scaledFraction);
+ updateTransitionState(blurRadius, scaledFraction);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayNotificationCountProvider.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayNotificationCountProvider.java
new file mode 100644
index 0000000..aaa34ed
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayNotificationCountProvider.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams;
+
+import android.annotation.NonNull;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
+import com.android.systemui.statusbar.policy.CallbackController;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+/***
+ * {@link DreamOverlayNotificationCountProvider} provides the current notification count to
+ * registered callbacks.
+ */
+@SysUISingleton
+public class DreamOverlayNotificationCountProvider
+ implements CallbackController<DreamOverlayNotificationCountProvider.Callback> {
+ private final Set<String> mNotificationKeys = new HashSet<>();
+ private final List<Callback> mCallbacks = new ArrayList<>();
+
+ private final NotificationHandler mNotificationHandler = new NotificationHandler() {
+ @Override
+ public void onNotificationPosted(
+ StatusBarNotification sbn, NotificationListenerService.RankingMap rankingMap) {
+ mNotificationKeys.add(sbn.getKey());
+ reportNotificationCountChanged();
+ }
+
+ @Override
+ public void onNotificationRemoved(
+ StatusBarNotification sbn, NotificationListenerService.RankingMap rankingMap) {
+ mNotificationKeys.remove(sbn.getKey());
+ reportNotificationCountChanged();
+ }
+
+ @Override
+ public void onNotificationRemoved(
+ StatusBarNotification sbn,
+ NotificationListenerService.RankingMap rankingMap,
+ int reason) {
+ mNotificationKeys.remove(sbn.getKey());
+ reportNotificationCountChanged();
+ }
+
+ @Override
+ public void onNotificationRankingUpdate(NotificationListenerService.RankingMap rankingMap) {
+ }
+
+ @Override
+ public void onNotificationsInitialized() {
+ }
+ };
+
+ @Inject
+ public DreamOverlayNotificationCountProvider(
+ NotificationListener notificationListener) {
+ notificationListener.addNotificationHandler(mNotificationHandler);
+ Arrays.stream(notificationListener.getActiveNotifications())
+ .forEach(sbn -> mNotificationKeys.add(sbn.getKey()));
+ }
+
+ @Override
+ public void addCallback(@NonNull Callback callback) {
+ if (!mCallbacks.contains(callback)) {
+ mCallbacks.add(callback);
+ callback.onNotificationCountChanged(mNotificationKeys.size());
+ }
+ }
+
+ @Override
+ public void removeCallback(@NonNull Callback callback) {
+ mCallbacks.remove(callback);
+ }
+
+ private void reportNotificationCountChanged() {
+ final int notificationCount = mNotificationKeys.size();
+ mCallbacks.forEach(callback -> callback.onNotificationCountChanged(notificationCount));
+ }
+
+ /**
+ * A callback to be registered with {@link DreamOverlayNotificationCountProvider} to receive
+ * changes to the current notification count.
+ */
+ public interface Callback {
+ /**
+ * Called when the notification count has changed.
+ * @param count The current notification count.
+ */
+ void onNotificationCountChanged(int count);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
index 761f28c..d4909c78 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
@@ -27,16 +27,12 @@
import android.net.NetworkRequest;
import android.os.UserHandle;
import android.provider.Settings;
-import android.service.notification.NotificationListenerService.RankingMap;
-import android.service.notification.StatusBarNotification;
import android.text.format.DateFormat;
import android.util.PluralsMessageFormatter;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.dagger.DreamOverlayComponent;
-import com.android.systemui.statusbar.NotificationListener;
-import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -62,7 +58,7 @@
private final Resources mResources;
private final DateFormatUtil mDateFormatUtil;
private final IndividualSensorPrivacyController mSensorPrivacyController;
- private final NotificationListener mNotificationListener;
+ private final DreamOverlayNotificationCountProvider mDreamOverlayNotificationCountProvider;
private final ZenModeController mZenModeController;
private final Executor mMainExecutor;
@@ -96,35 +92,6 @@
private final NextAlarmController.NextAlarmChangeCallback mNextAlarmCallback =
nextAlarm -> updateAlarmStatusIcon();
- private final NotificationHandler mNotificationHandler = new NotificationHandler() {
- @Override
- public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
- updateNotificationsStatusIcon();
- }
-
- @Override
- public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
- updateNotificationsStatusIcon();
- }
-
- @Override
- public void onNotificationRemoved(
- StatusBarNotification sbn,
- RankingMap rankingMap,
- int reason) {
- updateNotificationsStatusIcon();
- }
-
- @Override
- public void onNotificationRankingUpdate(RankingMap rankingMap) {
- }
-
- @Override
- public void onNotificationsInitialized() {
- updateNotificationsStatusIcon();
- }
- };
-
private final ZenModeController.Callback mZenModeCallback = new ZenModeController.Callback() {
@Override
public void onZenChanged(int zen) {
@@ -132,6 +99,14 @@
}
};
+ private final DreamOverlayNotificationCountProvider.Callback mNotificationCountCallback =
+ notificationCount -> showIcon(
+ DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS,
+ notificationCount > 0,
+ notificationCount > 0
+ ? buildNotificationsContentDescription(notificationCount)
+ : null);
+
@Inject
public DreamOverlayStatusBarViewController(
DreamOverlayStatusBarView view,
@@ -143,7 +118,7 @@
NextAlarmController nextAlarmController,
DateFormatUtil dateFormatUtil,
IndividualSensorPrivacyController sensorPrivacyController,
- NotificationListener notificationListener,
+ DreamOverlayNotificationCountProvider dreamOverlayNotificationCountProvider,
ZenModeController zenModeController) {
super(view);
mResources = resources;
@@ -154,20 +129,14 @@
mNextAlarmController = nextAlarmController;
mDateFormatUtil = dateFormatUtil;
mSensorPrivacyController = sensorPrivacyController;
- mNotificationListener = notificationListener;
+ mDreamOverlayNotificationCountProvider = dreamOverlayNotificationCountProvider;
mZenModeController = zenModeController;
-
- // Handlers can be added to NotificationListener, but apparently they can't be removed. So
- // add the handler here in the constructor rather than in onViewAttached to avoid confusion.
- mNotificationListener.addNotificationHandler(mNotificationHandler);
}
@Override
protected void onViewAttached() {
mIsAttached = true;
- updateNotificationsStatusIcon();
-
mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback);
updateWifiUnavailableStatusIcon();
@@ -180,6 +149,7 @@
mZenModeController.addCallback(mZenModeCallback);
updatePriorityModeStatusIcon();
+ mDreamOverlayNotificationCountProvider.addCallback(mNotificationCountCallback);
mTouchInsetSession.addViewToTracking(mView);
}
@@ -189,6 +159,7 @@
mSensorPrivacyController.removeCallback(mSensorCallback);
mNextAlarmController.removeCallback(mNextAlarmCallback);
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+ mDreamOverlayNotificationCountProvider.removeCallback(mNotificationCountCallback);
mTouchInsetSession.clear();
mIsAttached = false;
@@ -231,24 +202,6 @@
micBlocked && cameraBlocked);
}
- private void updateNotificationsStatusIcon() {
- if (mView == null) {
- // It is possible for this method to be called before the view is attached, which makes
- // null-checking necessary.
- return;
- }
-
- final StatusBarNotification[] notifications =
- mNotificationListener.getActiveNotifications();
- final int notificationCount = notifications != null ? notifications.length : 0;
- showIcon(
- DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS,
- notificationCount > 0,
- notificationCount > 0
- ? buildNotificationsContentDescription(notificationCount)
- : null);
- }
-
private String buildNotificationsContentDescription(int notificationCount) {
return PluralsMessageFormatter.format(
mResources,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
index aa43383..4065a25 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
@@ -540,13 +540,15 @@
/**
* Removes a complication by {@link ComplicationId}.
*/
- public void removeComplication(ComplicationId id) {
- if (!mEntries.containsKey(id)) {
+ public boolean removeComplication(ComplicationId id) {
+ final ViewEntry entry = mEntries.remove(id);
+
+ if (entry == null) {
Log.e(TAG, "could not find id:" + id);
- return;
+ return false;
}
- final ViewEntry entry = mEntries.get(id);
entry.remove();
+ return true;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
index 1b62ec4..5c99cd1 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
@@ -30,6 +30,10 @@
import android.view.MotionEvent;
import android.view.VelocityTracker;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
@@ -90,6 +94,8 @@
private VelocityTrackerFactory mVelocityTrackerFactory;
+ private final UiEventLogger mUiEventLogger;
+
private final GestureDetector.OnGestureListener mOnGestureListener =
new GestureDetector.SimpleOnGestureListener() {
@Override
@@ -116,8 +122,10 @@
// bouncer. As that view's expansion shrinks, the bouncer appears. The bouncer
// is fully hidden at full expansion (1) and fully visible when fully collapsed
// (0).
- final float screenTravelPercentage =
- Math.abs((e1.getY() - e2.getY()) / mCentralSurfaces.getDisplayHeight());
+ final float dy = mBouncerInitiallyShowing ? e2.getY() - e1.getY()
+ : e1.getY() - e2.getY();
+ final float screenTravelPercentage = Math.max(0,
+ dy / mCentralSurfaces.getDisplayHeight());
setPanelExpansion(mBouncerInitiallyShowing
? screenTravelPercentage : 1 - screenTravelPercentage);
return true;
@@ -129,6 +137,23 @@
mStatusBarKeyguardViewManager.onPanelExpansionChanged(mCurrentExpansion, false, true);
}
+ @VisibleForTesting
+ public enum DreamEvent implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "The screensaver has been swiped up.")
+ DREAM_SWIPED(988);
+
+ private final int mId;
+
+ DreamEvent(int id) {
+ mId = id;
+ }
+
+ @Override
+ public int getId() {
+ return mId;
+ }
+ }
+
@Inject
public BouncerSwipeTouchHandler(
DisplayMetrics displayMetrics,
@@ -141,7 +166,8 @@
FlingAnimationUtils flingAnimationUtils,
@Named(SWIPE_TO_BOUNCER_FLING_ANIMATION_UTILS_CLOSING)
FlingAnimationUtils flingAnimationUtilsClosing,
- @Named(SWIPE_TO_BOUNCER_START_REGION) float swipeRegionPercentage) {
+ @Named(SWIPE_TO_BOUNCER_START_REGION) float swipeRegionPercentage,
+ UiEventLogger uiEventLogger) {
mDisplayMetrics = displayMetrics;
mCentralSurfaces = centralSurfaces;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
@@ -151,6 +177,7 @@
mFlingAnimationUtilsClosing = flingAnimationUtilsClosing;
mValueAnimatorCreator = valueAnimatorCreator;
mVelocityTrackerFactory = velocityTrackerFactory;
+ mUiEventLogger = uiEventLogger;
}
@Override
@@ -218,6 +245,12 @@
final float expansion = flingRevealsOverlay(verticalVelocity, velocityVector)
? KeyguardBouncer.EXPANSION_HIDDEN : KeyguardBouncer.EXPANSION_VISIBLE;
+
+ // Log the swiping up to show Bouncer event.
+ if (!mBouncerInitiallyShowing && expansion == KeyguardBouncer.EXPANSION_VISIBLE) {
+ mUiEventLogger.log(DreamEvent.DREAM_SWIPED);
+ }
+
flingToExpansion(verticalVelocity, expansion);
if (expansion == KeyguardBouncer.EXPANSION_HIDDEN) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index d36bb72..0486fee 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2009,7 +2009,6 @@
case KEYGUARD_TIMEOUT:
synchronized (KeyguardViewMediator.this) {
doKeyguardLocked((Bundle) msg.obj);
- notifyDefaultDisplayCallbacks(mShowing);
}
break;
case DISMISS:
@@ -2373,7 +2372,8 @@
// Hack level over 9000: To speed up wake-and-unlock sequence, force it to report
// the next draw from here, so we don't have to wait for window manager to signal
// this to our ViewRootImpl.
- mKeyguardViewControllerLazy.get().getViewRootImpl().setReportNextDraw();
+ mKeyguardViewControllerLazy.get().getViewRootImpl().setReportNextDraw(
+ false /* syncBuffer */);
mScreenOnCoordinator.setWakeAndUnlocking(false);
}
@@ -2954,14 +2954,18 @@
private void setShowingLocked(boolean showing, boolean forceCallbacks) {
final boolean aodShowing = mDozing && !mScreenOnCoordinator.getWakeAndUnlocking();
- final boolean notifyDefaultDisplayCallbacks = showing != mShowing
+ final boolean notifyDefaultDisplayCallbacks = showing != mShowing || forceCallbacks;
+ final boolean updateActivityLockScreenState = showing != mShowing
|| aodShowing != mAodShowing || forceCallbacks;
mShowing = showing;
mAodShowing = aodShowing;
if (notifyDefaultDisplayCallbacks) {
notifyDefaultDisplayCallbacks(showing);
+ }
+ if (updateActivityLockScreenState) {
updateActivityLockScreenState(showing, aodShowing);
}
+
}
private void notifyDefaultDisplayCallbacks(boolean showing) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 958c244..b815f0c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -23,18 +23,22 @@
import android.app.smartspace.SmartspaceAction;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Rect;
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Animatable2;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.os.Process;
+import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -64,6 +68,7 @@
import com.android.systemui.util.time.SystemClock;
import java.net.URISyntaxException;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
@@ -87,6 +92,7 @@
private static final int MEDIA_RECOMMENDATION_MAX_NUM = 6;
private static final String KEY_SMARTSPACE_ARTIST_NAME = "artist_name";
private static final String KEY_SMARTSPACE_OPEN_IN_FOREGROUND = "KEY_OPEN_IN_FOREGROUND";
+ private static final String KEY_SMARTSPACE_APP_NAME = "KEY_SMARTSPACE_APP_NAME";
// Event types logged by smartspace
private static final int SMARTSPACE_CARD_CLICK_EVENT = 760;
@@ -606,19 +612,61 @@
setSemanticButton(genericButtons[i], null, collapsedSet, expandedSet, false);
}
}
+ expandedSet.setVisibility(R.id.media_progress_bar, getSeekBarVisibility());
+ expandedSet.setAlpha(R.id.media_progress_bar, mSeekBarViewModel.getEnabled() ? 1.0f : 0.0f);
+ }
- // If disabled, set progress bar to INVISIBLE instead of GONE so layout weights still work
+ private int getSeekBarVisibility() {
boolean seekbarEnabled = mSeekBarViewModel.getEnabled();
- expandedSet.setVisibility(R.id.media_progress_bar,
- seekbarEnabled ? ConstraintSet.VISIBLE : ConstraintSet.INVISIBLE);
- expandedSet.setAlpha(R.id.media_progress_bar, seekbarEnabled ? 1.0f : 0.0f);
+ if (seekbarEnabled) {
+ return ConstraintSet.VISIBLE;
+ }
+ // If disabled and "neighbours" are visible, set progress bar to INVISIBLE instead of GONE
+ // so layout weights still work.
+ return areAnyExpandedBottomActionsVisible() ? ConstraintSet.INVISIBLE : ConstraintSet.GONE;
+ }
+
+ private boolean areAnyExpandedBottomActionsVisible() {
+ ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
+ int[] referencedIds = mMediaViewHolder.getActionsTopBarrier().getReferencedIds();
+ for (int id : referencedIds) {
+ if (expandedSet.getVisibility(id) == ConstraintSet.VISIBLE) {
+ return true;
+ }
+ }
+ return false;
}
private void setSemanticButton(final ImageButton button, MediaAction mediaAction,
ConstraintSet collapsedSet, ConstraintSet expandedSet, boolean showInCompact) {
+ AnimationBindHandler animHandler;
+ if (button.getTag() == null) {
+ animHandler = new AnimationBindHandler();
+ button.setTag(animHandler);
+ } else {
+ animHandler = (AnimationBindHandler) button.getTag();
+ }
+
+ animHandler.tryExecute(() -> {
+ bindSemanticButton(animHandler, button, mediaAction,
+ collapsedSet, expandedSet, showInCompact);
+ });
+ }
+
+ private void bindSemanticButton(final AnimationBindHandler animHandler,
+ final ImageButton button, MediaAction mediaAction, ConstraintSet collapsedSet,
+ ConstraintSet expandedSet, boolean showInCompact) {
+
+ animHandler.unregisterAll();
if (mediaAction != null) {
- button.setImageIcon(mediaAction.getIcon());
+ final Drawable icon = mediaAction.getIcon();
+ button.setImageDrawable(icon);
button.setContentDescription(mediaAction.getContentDescription());
+ final Drawable bgDrawable = mediaAction.getBackground();
+ button.setBackground(bgDrawable);
+
+ animHandler.tryRegister(icon);
+ animHandler.tryRegister(bgDrawable);
Runnable action = mediaAction.getAction();
if (action == null) {
@@ -630,19 +678,75 @@
logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT,
/* isRecommendationCard */ false);
action.run();
+
+ if (icon instanceof Animatable) {
+ ((Animatable) icon).start();
+ }
+ if (bgDrawable instanceof Animatable) {
+ ((Animatable) bgDrawable).start();
+ }
}
});
}
} else {
- button.setImageIcon(null);
+ button.setImageDrawable(null);
button.setContentDescription(null);
button.setEnabled(false);
+ button.setBackground(null);
}
setVisibleAndAlpha(collapsedSet, button.getId(), mediaAction != null && showInCompact);
setVisibleAndAlpha(expandedSet, button.getId(), mediaAction != null);
}
+ private static class AnimationBindHandler extends Animatable2.AnimationCallback {
+ private ArrayList<Runnable> mOnAnimationsComplete = new ArrayList<>();
+ private ArrayList<Animatable2> mRegistrations = new ArrayList<>();
+
+ public void tryRegister(Drawable drawable) {
+ if (drawable instanceof Animatable2) {
+ Animatable2 anim = (Animatable2) drawable;
+ anim.registerAnimationCallback(this);
+ mRegistrations.add(anim);
+ }
+ }
+
+ public void unregisterAll() {
+ for (Animatable2 anim : mRegistrations) {
+ anim.unregisterAnimationCallback(this);
+ }
+ mRegistrations.clear();
+ }
+
+ public boolean isAnimationRunning() {
+ for (Animatable2 anim : mRegistrations) {
+ if (anim.isRunning()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void tryExecute(Runnable action) {
+ if (isAnimationRunning()) {
+ mOnAnimationsComplete.add(action);
+ } else {
+ action.run();
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Drawable drawable) {
+ super.onAnimationEnd(drawable);
+ if (!isAnimationRunning()) {
+ for (Runnable action : mOnAnimationsComplete) {
+ action.run();
+ }
+ mOnAnimationsComplete.clear();
+ }
+ }
+ }
+
@Nullable
private ActivityLaunchAnimator.Controller buildLaunchAnimatorController(
TransitionLayout player) {
@@ -718,18 +822,33 @@
icon.setColorFilter(getGrayscaleFilter());
ImageView headerLogoImageView = mRecommendationViewHolder.getCardIcon();
headerLogoImageView.setImageDrawable(icon);
+
// Set up media source app's label text.
- CharSequence appLabel = packageManager.getApplicationLabel(applicationInfo);
- if (appLabel.length() != 0) {
- TextView headerTitleText = mRecommendationViewHolder.getCardText();
- headerTitleText.setText(appLabel);
+ CharSequence appName = getAppName(data.getCardAction());
+ if (TextUtils.isEmpty(appName)) {
+ Intent launchIntent =
+ packageManager.getLaunchIntentForPackage(data.getPackageName());
+ if (launchIntent != null) {
+ ActivityInfo launchActivity = launchIntent.resolveActivityInfo(packageManager, 0);
+ appName = launchActivity.loadLabel(packageManager);
+ } else {
+ Log.w(TAG, "Package " + data.getPackageName()
+ + " does not have a main launcher activity. Fallback to full app name");
+ appName = packageManager.getApplicationLabel(applicationInfo);
+ }
}
+ // Set the app name as card's title.
+ if (!TextUtils.isEmpty(appName)) {
+ TextView headerTitleText = mRecommendationViewHolder.getCardText();
+ headerTitleText.setText(appName);
+ }
+
// Set up media rec card's tap action if applicable.
setSmartspaceRecItemOnClickListener(recommendationCard, data.getCardAction(),
/* interactedSubcardRank */ -1);
// Set up media rec card's accessibility label.
recommendationCard.setContentDescription(
- mContext.getString(R.string.controls_media_smartspace_rec_description, appLabel));
+ mContext.getString(R.string.controls_media_smartspace_rec_description, appName));
List<ImageView> mediaCoverItems = mRecommendationViewHolder.getMediaCoverItems();
List<ViewGroup> mediaCoverContainers = mRecommendationViewHolder.getMediaCoverContainers();
@@ -774,12 +893,12 @@
mediaCoverImageView.setContentDescription(
mContext.getString(
R.string.controls_media_smartspace_rec_item_no_artist_description,
- recommendation.getTitle(), appLabel));
+ recommendation.getTitle(), appName));
} else {
mediaCoverImageView.setContentDescription(
mContext.getString(
R.string.controls_media_smartspace_rec_item_description,
- recommendation.getTitle(), artistName, appLabel));
+ recommendation.getTitle(), artistName, appName));
}
if (uiComponentIndex < MEDIA_RECOMMENDATION_ITEMS_PER_ROW) {
@@ -961,6 +1080,17 @@
});
}
+ /** Returns the upstream app name if available. */
+ @Nullable
+ private String getAppName(SmartspaceAction action) {
+ if (action == null || action.getIntent() == null
+ || action.getIntent().getExtras() == null) {
+ return null;
+ }
+
+ return action.getIntent().getExtras().getString(KEY_SMARTSPACE_APP_NAME);
+ }
+
/** Returns if the Smartspace action will open the activity in foreground. */
private boolean shouldSmartspaceRecItemOpenInForeground(SmartspaceAction action) {
if (action == null || action.getIntent() == null
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
index f1712db..47a0991 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -170,9 +170,10 @@
/** State of a media action. */
data class MediaAction(
- val icon: Icon?,
+ val icon: Drawable?,
val action: Runnable?,
- val contentDescription: CharSequence?
+ val contentDescription: CharSequence?,
+ val background: Drawable?
)
/** State of the media device. */
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index f457ae7..029ea9a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -695,11 +695,12 @@
Icon.createWithResource(sbn.packageName, action.getIcon()!!.getResId())
} else {
action.getIcon()
- }.setTint(themeText)
+ }.setTint(themeText).loadDrawable(context)
val mediaAction = MediaAction(
mediaActionIcon,
runnable,
- action.title)
+ action.title,
+ null)
actionIcons.add(mediaAction)
}
}
@@ -789,30 +790,34 @@
return when (action) {
PlaybackState.ACTION_PLAY -> {
MediaAction(
- Icon.createWithResource(context, R.drawable.ic_media_play),
+ context.getDrawable(R.drawable.ic_media_play),
{ controller.transportControls.play() },
- context.getString(R.string.controls_media_button_play)
+ context.getString(R.string.controls_media_button_play),
+ context.getDrawable(R.drawable.ic_media_play_container)
)
}
PlaybackState.ACTION_PAUSE -> {
MediaAction(
- Icon.createWithResource(context, R.drawable.ic_media_pause),
+ context.getDrawable(R.drawable.ic_media_pause),
{ controller.transportControls.pause() },
- context.getString(R.string.controls_media_button_pause)
+ context.getString(R.string.controls_media_button_pause),
+ context.getDrawable(R.drawable.ic_media_pause_container)
)
}
PlaybackState.ACTION_SKIP_TO_PREVIOUS -> {
MediaAction(
- Icon.createWithResource(context, R.drawable.ic_media_prev),
+ context.getDrawable(R.drawable.ic_media_prev),
{ controller.transportControls.skipToPrevious() },
- context.getString(R.string.controls_media_button_prev)
+ context.getString(R.string.controls_media_button_prev),
+ null
)
}
PlaybackState.ACTION_SKIP_TO_NEXT -> {
MediaAction(
- Icon.createWithResource(context, R.drawable.ic_media_next),
+ context.getDrawable(R.drawable.ic_media_next),
{ controller.transportControls.skipToNext() },
- context.getString(R.string.controls_media_button_next)
+ context.getString(R.string.controls_media_button_next),
+ null
)
}
else -> null
@@ -835,9 +840,10 @@
val it = state.customActions[index]
return MediaAction(
- Icon.createWithResource(packageName, it.icon),
+ Icon.createWithResource(packageName, it.icon).loadDrawable(context),
{ controller.transportControls.sendCustomAction(it, it.extras) },
- it.name
+ it.name,
+ null
)
}
@@ -900,9 +906,11 @@
private fun getResumeMediaAction(action: Runnable): MediaAction {
return MediaAction(
- Icon.createWithResource(context, R.drawable.ic_media_play).setTint(themeText),
+ Icon.createWithResource(context, R.drawable.ic_media_play)
+ .setTint(themeText).loadDrawable(context),
action,
- context.getString(R.string.controls_media_resume)
+ context.getString(R.string.controls_media_resume),
+ context.getDrawable(R.drawable.ic_media_play_container)
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index b0159ed..3d9f933 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -809,11 +809,11 @@
return resultBounds
}
- /**
- * @return true if this transformation is guided by an external progress like a finger
- */
- private fun isCurrentlyInGuidedTransformation(): Boolean {
- return hasValidStartAndEndLocations() && getTransformationProgress() >= 0
+ /** @return true if this transformation is guided by an external progress like a finger */
+ fun isCurrentlyInGuidedTransformation(): Boolean {
+ return hasValidStartAndEndLocations() &&
+ getTransformationProgress() >= 0 &&
+ areGuidedTransitionHostsVisible()
}
private fun hasValidStartAndEndLocations(): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
index 836b5cb..e9c8886 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
@@ -24,6 +24,7 @@
import android.widget.ImageView
import android.widget.SeekBar
import android.widget.TextView
+import androidx.constraintlayout.widget.Barrier
import com.android.systemui.R
import com.android.systemui.util.animation.TransitionLayout
@@ -70,6 +71,8 @@
val action3 = itemView.requireViewById<ImageButton>(R.id.action3)
val action4 = itemView.requireViewById<ImageButton>(R.id.action4)
+ val actionsTopBarrier = itemView.requireViewById<Barrier>(R.id.media_action_barrier_top)
+
init {
(player.background as IlluminationDrawable).let {
it.registerLightSource(seamless)
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
index e5b41b1..b76f6bb 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
@@ -78,7 +78,7 @@
holder.seekBar.thumb.alpha = if (data.seekAvailable) 255 else 0
holder.seekBar.isEnabled = data.seekAvailable
- progressDrawable?.animate = data.playing
+ progressDrawable?.animate = data.playing && !data.scrubbing
if (holder.seekBar.maxHeight != seekBarEnabledMaxHeight) {
holder.seekBar.maxHeight = seekBarEnabledMaxHeight
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
index 49cd161..a9a8fd1c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
@@ -74,7 +74,7 @@
class SeekBarViewModel @Inject constructor(
@Background private val bgExecutor: RepeatableExecutor
) {
- private var _data = Progress(false, false, false, null, 0)
+ private var _data = Progress(false, false, false, false, null, 0)
set(value) {
field = value
_progress.postValue(value)
@@ -127,6 +127,7 @@
if (field != value) {
field = value
checkIfPollingNeeded()
+ _data = _data.copy(scrubbing = value)
}
}
@@ -200,7 +201,7 @@
val enabled = if (playbackState == null ||
playbackState?.getState() == PlaybackState.STATE_NONE ||
(duration <= 0)) false else true
- _data = Progress(enabled, seekAvailable, playing, position, duration)
+ _data = Progress(enabled, seekAvailable, playing, scrubbing, position, duration)
checkIfPollingNeeded()
}
@@ -418,6 +419,7 @@
val enabled: Boolean,
val seekAvailable: Boolean,
val playing: Boolean,
+ val scrubbing: Boolean,
val elapsedTime: Int?,
val duration: Int
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 4e63104..8d0494a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -37,6 +37,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.animation.ShadeInterpolation;
@@ -92,6 +93,7 @@
private float mLastPanelFraction;
private float mSquishinessFraction = 1;
private boolean mQsDisabled;
+ private int[] mTemp = new int[2];
private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
private final MediaHost mQsMediaHost;
@@ -141,6 +143,8 @@
*/
private float mFullShadeProgress;
+ private boolean mOverScrolling;
+
@Inject
public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
QSTileHost qsTileHost,
@@ -498,6 +502,12 @@
}
@Override
+ public void setOverScrollAmount(int overScrollAmount) {
+ mOverScrolling = overScrollAmount != 0;
+ getView().setTranslationY(overScrollAmount);
+ }
+
+ @Override
public int getHeightDiff() {
return mQSPanelScrollView.getBottom() - mHeader.getBottom()
+ mHeader.getPaddingBottom();
@@ -515,7 +525,7 @@
? 1 : QSAnimator.SHORT_PARALLAX_AMOUNT) * (expansion - 1);
boolean onKeyguard = isKeyguardState();
boolean onKeyguardAndExpanded = onKeyguard && !mShowCollapsedOnKeyguard;
- if (!mHeaderAnimating && !headerWillBeAnimating()) {
+ if (!mHeaderAnimating && !headerWillBeAnimating() && !mOverScrolling) {
getView().setTranslationY(
onKeyguardAndExpanded
? translationScaleY * mHeader.getHeight()
@@ -584,7 +594,9 @@
} else if (progress > 0 && view.getVisibility() != View.VISIBLE) {
view.setVisibility((View.VISIBLE));
}
- float alpha = ShadeInterpolation.getContentAlpha(progress);
+ float alpha = (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)
+ ? BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(progress)
+ : ShadeInterpolation.getContentAlpha(progress);
view.setAlpha(alpha);
}
@@ -600,8 +612,11 @@
}
mQSPanelScrollView.setClipBounds(mQsBounds);
- mQsMediaHost.getCurrentClipping().set(0, 0, getView().getMeasuredWidth(),
- mQSPanelScrollView.getMeasuredHeight() - mQSPanelScrollView.getPaddingBottom());
+ mQSPanelScrollView.getLocationOnScreen(mTemp);
+ int top = mTemp[1];
+ mQsMediaHost.getCurrentClipping().set(0, top, getView().getMeasuredWidth(),
+ top + mQSPanelScrollView.getMeasuredHeight()
+ - mQSPanelScrollView.getPaddingBottom());
}
private void updateMediaPositions() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 58007c0..74d1a3d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -217,7 +217,12 @@
/** */
public void refreshAllTiles() {
for (QSPanelControllerBase.TileRecord r : mRecords) {
- r.tile.refreshState();
+ if (!r.tile.isListening()) {
+ // Only refresh tiles that were not already in the listening state. Tiles that are
+ // already listening is as if they are already expanded (for example, tiles that
+ // are both in QQS and QS).
+ r.tile.refreshState();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 999818f..8755bc9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -331,6 +331,11 @@
refreshState(null);
}
+ @Override
+ public final boolean isListening() {
+ return getLifecycle().getCurrentState().isAtLeast(RESUMED);
+ }
+
protected final void refreshState(@Nullable Object arg) {
mHandler.obtainMessage(H.REFRESH_STATE, arg).sendToTarget();
}
@@ -416,7 +421,7 @@
@Nullable
public abstract Intent getLongClickIntent();
- protected void handleRefreshState(@Nullable Object arg) {
+ protected final void handleRefreshState(@Nullable Object arg) {
handleUpdateState(mTmpState, arg);
boolean changed = mTmpState.copyTo(mState);
if (mReadyState == READY_STATE_READYING) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java b/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java
index 0b98767..4f0455d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java
@@ -44,10 +44,13 @@
public class DraggableConstraintLayout extends ConstraintLayout
implements ViewTreeObserver.OnComputeInternalInsetsListener {
+ private static final float VELOCITY_DP_PER_MS = 1;
+
private final SwipeDismissHandler mSwipeDismissHandler;
private final GestureDetector mSwipeDetector;
private View mActionsContainer;
private SwipeDismissCallbacks mCallbacks;
+ private final DisplayMetrics mDisplayMetrics;
/**
* Stores the callbacks when the view is interacted with or dismissed.
@@ -86,6 +89,9 @@
public DraggableConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ mDisplayMetrics = new DisplayMetrics();
+ mContext.getDisplay().getRealMetrics(mDisplayMetrics);
+
mSwipeDismissHandler = new SwipeDismissHandler(mContext, this);
setOnTouchListener(mSwipeDismissHandler);
@@ -283,7 +289,8 @@
}
void dismiss() {
- ValueAnimator anim = createSwipeDismissAnimation(3);
+ float velocityPxPerMs = FloatingWindowUtil.dpToPx(mDisplayMetrics, VELOCITY_DP_PER_MS);
+ ValueAnimator anim = createSwipeDismissAnimation(velocityPxPerMs);
mCallbacks.onSwipeDismissInitiated(anim);
dismiss(anim);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockScreenShadeOverScroller.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockScreenShadeOverScroller.kt
new file mode 100644
index 0000000..de37a38
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockScreenShadeOverScroller.kt
@@ -0,0 +1,8 @@
+package com.android.systemui.statusbar
+
+/** Represents an over scroller for the transition to full shade on lock screen. */
+interface LockScreenShadeOverScroller {
+
+ /** The amount in pixels that the user has dragged to expand the shade. */
+ var expansionDragDownAmount: Float
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 310eb4f..63ab3de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -64,6 +64,8 @@
private val scrimController: ScrimController,
private val depthController: NotificationShadeDepthController,
private val context: Context,
+ private val splitShadeOverScrollerFactory: SplitShadeLockScreenOverScroller.Factory,
+ private val singleShadeOverScrollerFactory: SingleShadeLockScreenOverScroller.Factory,
wakefulnessLifecycle: WakefulnessLifecycle,
configurationController: ConfigurationController,
falsingManager: FalsingManager,
@@ -162,6 +164,17 @@
private var statusBarTransitionDistance = 0
/**
+ * Distance that the full shade transition takes in order for the keyguard elements to fully
+ * translate into their final position
+ */
+ private var keyguardTransitionDistance = 0
+
+ /**
+ * The amount of vertical offset for the keyguard during the full shade transition.
+ */
+ private var keyguardTransitionOffset = 0
+
+ /**
* Flag to make sure that the dragDownAmount is applied to the listeners even when in the
* locked down shade.
*/
@@ -194,6 +207,27 @@
*/
val touchHelper = DragDownHelper(falsingManager, falsingCollector, this, context)
+ private val splitShadeOverScroller: SplitShadeLockScreenOverScroller by lazy {
+ splitShadeOverScrollerFactory.create(qS, nsslController)
+ }
+
+ private val phoneShadeOverScroller: SingleShadeLockScreenOverScroller by lazy {
+ singleShadeOverScrollerFactory.create(nsslController)
+ }
+
+ /**
+ * [LockScreenShadeOverScroller] property that delegates to either
+ * [SingleShadeLockScreenOverScroller] or [SplitShadeLockScreenOverScroller].
+ *
+ * There are currently two different implementations, as the over scroll behavior is different
+ * on single shade and split shade.
+ *
+ * On single shade, only notifications are over scrolled, whereas on split shade, everything is
+ * over scrolled.
+ */
+ private val shadeOverScroller: LockScreenShadeOverScroller
+ get() = if (useSplitShade) splitShadeOverScroller else phoneShadeOverScroller
+
init {
updateResources()
configurationController.addCallback(object : ConfigurationController.ConfigurationListener {
@@ -252,6 +286,10 @@
statusBarTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_status_bar_transition_distance)
useSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
+ keyguardTransitionDistance = context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_keyguard_transition_distance)
+ keyguardTransitionOffset = context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_keyguard_transition_vertical_offset)
}
fun setStackScroller(nsslController: NotificationStackScrollLayoutController) {
@@ -410,7 +448,7 @@
if (!nsslController.isInLockedDownShade() || field == 0f || forceApplyAmount) {
val notificationShelfProgress =
MathUtils.saturate(dragDownAmount / notificationShelfTransitionDistance)
- nsslController.setTransitionToFullShadeAmount(field, notificationShelfProgress)
+ nsslController.setTransitionToFullShadeAmount(notificationShelfProgress)
qSDragProgress = MathUtils.saturate(dragDownAmount / qsTransitionDistance)
qS.setTransitionToFullShadeAmount(field, qSDragProgress)
@@ -422,6 +460,7 @@
transitionToShadeAmountScrim(field)
transitionToShadeAmountCommon(field)
transitionToShadeAmountKeyguard(field)
+ shadeOverScroller.expansionDragDownAmount = dragDownAmount
}
}
}
@@ -461,15 +500,27 @@
val keyguardAlphaProgress =
MathUtils.saturate(dragDownAmount / npvcKeyguardContentAlphaTransitionDistance)
val keyguardAlpha = 1f - keyguardAlphaProgress
- val keyguardTranslationY = if (useSplitShade) {
- // On split-shade, the translationY of the keyguard should stay in sync with the
- // translation of media.
- mediaHierarchyManager.getGuidedTransformationTranslationY()
- } else {
- 0
- }
+ val keyguardTranslationY = calculateKeyguardTranslationY(dragDownAmount)
notificationPanelController
.setKeyguardTransitionProgress(keyguardAlpha, keyguardTranslationY)
+
+ val statusBarAlpha = if (useSplitShade) keyguardAlpha else -1f
+ notificationPanelController.setKeyguardStatusBarAlpha(statusBarAlpha)
+ }
+
+ private fun calculateKeyguardTranslationY(dragDownAmount: Float): Int {
+ if (!useSplitShade) {
+ return 0
+ }
+ // On split-shade, the translationY of the keyguard should stay in sync with the
+ // translation of media.
+ if (mediaHierarchyManager.isCurrentlyInGuidedTransformation()) {
+ return mediaHierarchyManager.getGuidedTransformationTranslationY()
+ }
+ // When media is not showing, apply the default distance
+ val translationProgress = MathUtils.saturate(dragDownAmount / keyguardTransitionDistance)
+ val translationY = translationProgress * keyguardTransitionOffset
+ return translationY.toInt()
}
private fun setDragDownAmountAnimated(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt b/packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt
new file mode 100644
index 0000000..575f354
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt
@@ -0,0 +1,74 @@
+package com.android.systemui.statusbar
+
+import android.content.Context
+import android.content.res.Configuration
+import android.util.MathUtils
+import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+class SingleShadeLockScreenOverScroller
+@AssistedInject
+constructor(
+ configurationController: ConfigurationController,
+ private val context: Context,
+ private val statusBarStateController: SysuiStatusBarStateController,
+ @Assisted private val nsslController: NotificationStackScrollLayoutController
+) : LockScreenShadeOverScroller {
+
+ private var maxOverScrollAmount = 0
+ private var totalDistanceForFullShadeTransition = 0
+
+ init {
+ updateResources()
+ configurationController.addCallback(
+ object : ConfigurationController.ConfigurationListener {
+ override fun onConfigChanged(newConfig: Configuration?) {
+ updateResources()
+ }
+ })
+ }
+
+ private fun updateResources() {
+ val resources = context.resources
+ totalDistanceForFullShadeTransition =
+ resources.getDimensionPixelSize(R.dimen.lockscreen_shade_qs_transition_distance)
+ maxOverScrollAmount =
+ resources.getDimensionPixelSize(R.dimen.lockscreen_shade_max_over_scroll_amount)
+ }
+
+ override var expansionDragDownAmount: Float = 0f
+ set(value) {
+ if (value == field) {
+ return
+ }
+ field = value
+ overScroll()
+ }
+
+ private fun overScroll() {
+ var extraTopInset = 0.0f
+ if (statusBarStateController.state == StatusBarState.KEYGUARD) {
+ val viewHeight = nsslController.height
+ val overallProgress = MathUtils.saturate(expansionDragDownAmount / viewHeight)
+ val transitionProgress =
+ Interpolators.getOvershootInterpolation(
+ overallProgress,
+ 0.6f,
+ totalDistanceForFullShadeTransition.toFloat() / viewHeight.toFloat())
+ extraTopInset = transitionProgress * maxOverScrollAmount
+ }
+ nsslController.setOverScrollAmount(extraTopInset.toInt())
+ }
+
+ @AssistedFactory
+ fun interface Factory {
+ fun create(
+ nsslController: NotificationStackScrollLayoutController
+ ): SingleShadeLockScreenOverScroller
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt b/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
new file mode 100644
index 0000000..96ce6b4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
@@ -0,0 +1,129 @@
+package com.android.systemui.statusbar
+
+import android.animation.Animator
+import android.animation.ValueAnimator
+import android.content.Context
+import android.content.res.Configuration
+import android.util.MathUtils
+import android.view.animation.PathInterpolator
+import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
+import com.android.systemui.plugins.qs.QS
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
+import com.android.systemui.statusbar.phone.ScrimController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+class SplitShadeLockScreenOverScroller
+@AssistedInject
+constructor(
+ configurationController: ConfigurationController,
+ private val context: Context,
+ private val scrimController: ScrimController,
+ private val statusBarStateController: SysuiStatusBarStateController,
+ @Assisted private val qS: QS,
+ @Assisted private val nsslController: NotificationStackScrollLayoutController
+) : LockScreenShadeOverScroller {
+
+ private var releaseOverScrollAnimator: Animator? = null
+ private var transitionToFullShadeDistance = 0
+ private var releaseOverScrollDuration = 0L
+ private var maxOverScrollAmount = 0
+ private var previousOverscrollAmount = 0
+
+ init {
+ updateResources()
+ configurationController.addCallback(
+ object : ConfigurationController.ConfigurationListener {
+ override fun onConfigChanged(newConfig: Configuration?) {
+ updateResources()
+ }
+ })
+ }
+
+ private fun updateResources() {
+ val resources = context.resources
+ transitionToFullShadeDistance =
+ resources.getDimensionPixelSize(R.dimen.lockscreen_shade_full_transition_distance)
+ maxOverScrollAmount =
+ resources.getDimensionPixelSize(R.dimen.lockscreen_shade_max_over_scroll_amount)
+ releaseOverScrollDuration =
+ resources.getInteger(R.integer.lockscreen_shade_over_scroll_release_duration).toLong()
+ }
+
+ override var expansionDragDownAmount: Float = 0f
+ set(dragDownAmount) {
+ if (field == dragDownAmount) {
+ return
+ }
+ field = dragDownAmount
+ if (shouldOverscroll()) {
+ overScroll(dragDownAmount)
+ } else if (shouldReleaseOverscroll()) {
+ releaseOverScroll()
+ }
+ }
+
+ private fun shouldOverscroll() = statusBarStateController.state == StatusBarState.KEYGUARD
+
+ private fun shouldReleaseOverscroll() = !shouldOverscroll() && previousOverscrollAmount != 0
+
+ private fun overScroll(dragDownAmount: Float) {
+ val overscrollAmount: Int = calculateOverscrollAmount(dragDownAmount)
+ applyOverscroll(overscrollAmount)
+ previousOverscrollAmount = overscrollAmount
+ }
+
+ private fun applyOverscroll(overscrollAmount: Int) {
+ qS.setOverScrollAmount(overscrollAmount)
+ scrimController.setNotificationsOverScrollAmount(overscrollAmount)
+ nsslController.setOverScrollAmount(overscrollAmount)
+ }
+
+ private fun calculateOverscrollAmount(dragDownAmount: Float): Int {
+ val fullHeight: Int = nsslController.height
+ val fullHeightProgress: Float = MathUtils.saturate(dragDownAmount / fullHeight)
+ val overshootStart: Float = transitionToFullShadeDistance / fullHeight.toFloat()
+ val overShootTransitionProgress: Float =
+ Interpolators.getOvershootInterpolation(
+ fullHeightProgress, OVER_SHOOT_AMOUNT, overshootStart)
+ return (overShootTransitionProgress * maxOverScrollAmount).toInt()
+ }
+
+ private fun releaseOverScroll() {
+ val animator = ValueAnimator.ofInt(previousOverscrollAmount, 0)
+ animator.addUpdateListener {
+ val overScrollAmount = it.animatedValue as Int
+ qS.setOverScrollAmount(overScrollAmount)
+ scrimController.setNotificationsOverScrollAmount(overScrollAmount)
+ nsslController.setOverScrollAmount(overScrollAmount)
+ }
+ animator.interpolator = RELEASE_OVER_SCROLL_INTERPOLATOR
+ animator.duration = releaseOverScrollDuration
+ animator.start()
+ releaseOverScrollAnimator = animator
+ previousOverscrollAmount = 0
+ }
+
+ @VisibleForTesting
+ internal fun finishAnimations() {
+ releaseOverScrollAnimator?.end()
+ releaseOverScrollAnimator = null
+ }
+
+ @AssistedFactory
+ fun interface Factory {
+ fun create(
+ qS: QS,
+ nsslController: NotificationStackScrollLayoutController
+ ): SplitShadeLockScreenOverScroller
+ }
+
+ companion object {
+ private const val OVER_SHOOT_AMOUNT = 0.6f
+ private val RELEASE_OVER_SCROLL_INTERPOLATOR = PathInterpolator(0.17f, 0f, 0f, 1f)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 2baa079..477db3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -641,28 +641,37 @@
* Returns true if the group change was suppressed, else false
*/
private boolean maybeSuppressGroupChange(NotificationEntry entry, List<ListEntry> out) {
- if (!entry.wasAttachedInPreviousPass()) {
- return false; // new entries are allowed
- }
-
final GroupEntry prevParent = entry.getPreviousAttachState().getParent();
+ if (prevParent == null) {
+ // New entries are always allowed.
+ return false;
+ }
final GroupEntry assignedParent = entry.getParent();
- if (prevParent != assignedParent
- && !getStabilityManager().isGroupChangeAllowed(entry.getRepresentativeEntry())) {
+ if (prevParent == assignedParent) {
+ // Nothing to change.
+ return false;
+ }
+ if (prevParent != ROOT_ENTRY && prevParent.getParent() == null) {
+ // Previous parent was a group, which has been removed (hence, its parent is null).
+ // Always allow this group change, otherwise the child will remain attached to the
+ // removed group and be removed from the shade until visual stability ends.
+ return false;
+ }
+ // TODO: Rather than perform "half" of the move here and require the caller remove the child
+ // from the assignedParent, ideally we would have an atomic "move" operation.
+ if (!getStabilityManager().isGroupChangeAllowed(entry.getRepresentativeEntry())) {
entry.getAttachState().getSuppressedChanges().setParent(assignedParent);
entry.setParent(prevParent);
if (prevParent == ROOT_ENTRY) {
out.add(entry);
- } else if (prevParent != null) {
+ } else {
prevParent.addChild(entry);
if (!mGroups.containsKey(prevParent.getKey())) {
mGroups.put(prevParent.getKey(), prevParent);
}
}
-
return true;
}
-
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt
index ff0e47f..e436ccf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt
@@ -77,6 +77,8 @@
private val secureSettings: SecureSettings,
private val globalSettings: GlobalSettings
) : CoreStartable(context), KeyguardNotificationVisibilityProvider {
+ private val showSilentNotifsUri =
+ secureSettings.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS)
private val onStateChangedListeners = ListenerSet<Consumer<String>>()
private var hideSilentNotificationsOnLockscreen: Boolean = false
@@ -100,6 +102,9 @@
// register lockscreen settings changed callbacks:
val settingsObserver: ContentObserver = object : ContentObserver(handler) {
override fun onChange(selfChange: Boolean, uri: Uri?) {
+ if (uri == showSilentNotifsUri) {
+ readShowSilentNotificationSetting()
+ }
if (keyguardStateController.isShowing) {
notifyStateChanged("Settings $uri changed")
}
@@ -152,62 +157,50 @@
onStateChangedListeners.forEach { it.accept(reason) }
}
- override fun shouldHideNotification(entry: NotificationEntry): Boolean {
- val sbn = entry.sbn
- // FILTER OUT the notification when the keyguard is showing and...
- if (keyguardStateController.isShowing) {
- // ... user settings or the device policy manager doesn't allow lockscreen
- // notifications;
- if (!lockscreenUserManager.shouldShowLockscreenNotifications()) {
- return true
- }
- val currUserId: Int = lockscreenUserManager.currentUserId
- val notifUserId =
- if (sbn.user.identifier == UserHandle.USER_ALL) currUserId
- else sbn.user.identifier
-
- // ... user is in lockdown
- if (keyguardUpdateMonitor.isUserInLockdown(currUserId) ||
- keyguardUpdateMonitor.isUserInLockdown(notifUserId)) {
- return true
- }
-
- // ... device is in public mode and the user's settings doesn't allow
- // notifications to show in public mode
- if (lockscreenUserManager.isLockscreenPublicMode(currUserId) ||
- lockscreenUserManager.isLockscreenPublicMode(notifUserId)) {
- if (entry.ranking.lockscreenVisibilityOverride == Notification.VISIBILITY_SECRET) {
- return true
- }
- if (!lockscreenUserManager.userAllowsNotificationsInPublic(currUserId) ||
- !lockscreenUserManager.userAllowsNotificationsInPublic(
- notifUserId)) {
- return true
- }
- }
-
- // ... neither this notification nor its group have high enough priority
- // to be shown on the lockscreen
- if (entry.parent != null) {
- val parent = entry.parent
- if (priorityExceedsLockscreenShowingThreshold(parent)) {
- return false
- }
- }
- return !priorityExceedsLockscreenShowingThreshold(entry)
- }
- return false
+ override fun shouldHideNotification(entry: NotificationEntry): Boolean = when {
+ // Keyguard state doesn't matter if the keyguard is not showing.
+ !keyguardStateController.isShowing -> false
+ // Notifications not allowed on the lockscreen, always hide.
+ !lockscreenUserManager.shouldShowLockscreenNotifications() -> true
+ // User settings do not allow this notification on the lockscreen, so hide it.
+ userSettingsDisallowNotification(entry) -> true
+ // Parent priority is high enough to be shown on the lockscreen, do not hide.
+ entry.parent?.let(::priorityExceedsLockscreenShowingThreshold) == true -> false
+ // Entry priority is high enough to be shown on the lockscreen, do not hide.
+ priorityExceedsLockscreenShowingThreshold(entry) -> false
+ // Priority is too low, hide.
+ else -> true
}
- private fun priorityExceedsLockscreenShowingThreshold(entry: ListEntry?): Boolean =
- when {
- entry == null -> false
- hideSilentNotificationsOnLockscreen -> highPriorityProvider.isHighPriority(entry)
- else -> entry.representativeEntry?.ranking?.isAmbient == false
+ private fun userSettingsDisallowNotification(entry: NotificationEntry): Boolean {
+ fun disallowForUser(user: Int) = when {
+ // user is in lockdown, always disallow
+ keyguardUpdateMonitor.isUserInLockdown(user) -> true
+ // device isn't public, no need to check public-related settings, so allow
+ !lockscreenUserManager.isLockscreenPublicMode(user) -> false
+ // entry is meant to be secret on the lockscreen, disallow
+ entry.ranking.lockscreenVisibilityOverride == Notification.VISIBILITY_SECRET -> true
+ // disallow if user disallows notifications in public
+ else -> !lockscreenUserManager.userAllowsNotificationsInPublic(user)
}
+ val currentUser = lockscreenUserManager.currentUserId
+ val notifUser = entry.sbn.user.identifier
+ return when {
+ disallowForUser(currentUser) -> true
+ notifUser == UserHandle.USER_ALL -> false
+ notifUser == currentUser -> false
+ else -> disallowForUser(notifUser)
+ }
+ }
+
+ private fun priorityExceedsLockscreenShowingThreshold(entry: ListEntry): Boolean = when {
+ hideSilentNotificationsOnLockscreen -> highPriorityProvider.isHighPriority(entry)
+ else -> entry.representativeEntry?.ranking?.isAmbient == false
+ }
private fun readShowSilentNotificationSetting() {
- hideSilentNotificationsOnLockscreen =
+ val showSilentNotifs =
secureSettings.getBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, true)
+ hideSilentNotificationsOnLockscreen = !showSilentNotifs
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 3e6f94c..32d37d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -5026,6 +5026,7 @@
.append(" qsExpandFraction=").append(mQsExpansionFraction)
.append(" isCurrentUserSetup=").append(mIsCurrentUserSetup)
.append(" hideAmount=").append(mAmbientState.getHideAmount())
+ .append(" ambientStateSwipingUp=").append(mAmbientState.isSwipingUp())
.append("]");
pw.println(sb.toString());
DumpUtilsKt.withIncreasedIndent(pw, () -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index d98f8a7..5bc50ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -41,7 +41,6 @@
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
-import android.util.MathUtils;
import android.util.Pair;
import android.view.Display;
import android.view.LayoutInflater;
@@ -65,7 +64,6 @@
import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
import com.android.systemui.SwipeHelper;
-import com.android.systemui.animation.Interpolators;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.colorextraction.SysuiColorExtractor;
@@ -205,18 +203,6 @@
private ColorExtractor.OnColorsChangedListener mOnColorsChangedListener;
- /**
- * The total distance in pixels that the full shade transition takes to transition entirely to
- * the full shade.
- */
- private int mTotalDistanceForFullShadeTransition;
-
- /**
- * The amount of movement the notifications do when transitioning to the full shade before
- * reaching the overstrech
- */
- private int mNotificationDragDownMovement;
-
@VisibleForTesting
final View.OnAttachStateChangeListener mOnAttachStateChangeListener =
new View.OnAttachStateChangeListener() {
@@ -304,10 +290,6 @@
private NotifStats mNotifStats = NotifStats.getEmpty();
private void updateResources() {
- mNotificationDragDownMovement = mResources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_notification_movement);
- mTotalDistanceForFullShadeTransition = mResources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_qs_transition_distance);
mNotificationStackSizeCalculator.updateResources();
}
@@ -1537,8 +1519,6 @@
}
/**
- * @param amount The amount of pixels we have currently dragged down
- * for the lockscreen to shade transition. 0f for all other states.
* @param fraction The fraction of lockscreen to shade transition.
* 0f for all other states.
*
@@ -1546,18 +1526,15 @@
* LockscreenShadeTransitionController resets amount and fraction to 0, where they remain
* until the next lockscreen-to-shade transition.
*/
- public void setTransitionToFullShadeAmount(float amount, float fraction) {
+ public void setTransitionToFullShadeAmount(float fraction) {
mView.setFractionToShade(fraction);
+ }
- float extraTopInset = 0.0f;
- if (mStatusBarStateController.getState() == KEYGUARD) {
- float overallProgress = MathUtils.saturate(amount / mView.getHeight());
- float transitionProgress = Interpolators.getOvershootInterpolation(overallProgress,
- 0.6f,
- (float) mTotalDistanceForFullShadeTransition / (float) mView.getHeight());
- extraTopInset = transitionProgress * mNotificationDragDownMovement;
- }
- mView.setExtraTopInsetForFullShadeTransition(extraTopInset);
+ /**
+ * Sets the amount of vertical over scroll that should be performed on NSSL.
+ */
+ public void setOverScrollAmount(int overScrollAmount) {
+ mView.setExtraTopInsetForFullShadeTransition(overScrollAmount);
}
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
index 3f971552..6c6ed85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
@@ -22,10 +22,8 @@
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.StatusBarState.KEYGUARD
import com.android.systemui.statusbar.SysuiStatusBarStateController
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.util.children
@@ -41,8 +39,6 @@
class NotificationStackSizeCalculator
@Inject
constructor(
- private val groupManager: NotificationGroupManagerLegacy,
- private val lockscreenUserManager: NotificationLockscreenUserManager,
private val statusBarStateController: SysuiStatusBarStateController,
@Main private val resources: Resources
) {
@@ -191,7 +187,7 @@
if (onLockscreen) {
when (this) {
is ExpandableNotificationRow -> {
- if (isSummaryOfSuppressedGroup() || !canShowViewOnLockscreen() || isRemoved) {
+ if (!canShowViewOnLockscreen() || isRemoved) {
return false
}
}
@@ -208,9 +204,6 @@
visibleIndex: Int
) = stack.calculateGapHeight(previous, /* current= */ this, visibleIndex)
- private fun ExpandableNotificationRow.isSummaryOfSuppressedGroup() =
- groupManager.isSummaryOfSuppressedGroup(entry.sbn)
-
/**
* Can a view be shown on the lockscreen when calculating the number of allowed notifications to
* show?
@@ -220,31 +213,12 @@
private fun ExpandableView.canShowViewOnLockscreen(): Boolean {
if (hasNoContentHeight()) {
return false
- }
- if (this is ExpandableNotificationRow && !canShowRowOnLockscreen()) {
- return false
} else if (visibility == GONE) {
return false
}
return true
}
- /**
- * Can a row be shown on the lockscreen when calculating the number of allowed notifications to
- * show?
- *
- * @return true if it can be shown
- */
- private fun ExpandableNotificationRow.canShowRowOnLockscreen(): Boolean {
- if (isSummaryOfSuppressedGroup()) {
- return false
- }
- if (!lockscreenUserManager.shouldShowOnKeyguard(entry)) {
- return false
- }
- return !isRemoved
- }
-
private fun log(s: () -> String) {
if (DEBUG) {
Log.d(TAG, s())
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index c2c8bd3..a2d22bc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -641,6 +641,7 @@
private boolean mWallpaperSupported;
private Runnable mLaunchTransitionEndRunnable;
+ private Runnable mLaunchTransitionCancelRunnable;
private boolean mLaunchCameraWhenFinishedWaking;
private boolean mLaunchCameraOnFinishedGoingToSleep;
private boolean mLaunchEmergencyActionWhenFinishedWaking;
@@ -2967,12 +2968,15 @@
*
* @param beforeFading the runnable to be run when the circle is fully expanded and the fading
* starts
- * @param endRunnable the runnable to be run when the transition is done
+ * @param endRunnable the runnable to be run when the transition is done. Will not run
+ * if the transition is cancelled, instead cancelRunnable will run
+ * @param cancelRunnable the runnable to be run if the transition is cancelled
*/
public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
- Runnable endRunnable) {
+ Runnable endRunnable, Runnable cancelRunnable) {
mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
mLaunchTransitionEndRunnable = endRunnable;
+ mLaunchTransitionCancelRunnable = cancelRunnable;
Runnable hideRunnable = () -> {
mKeyguardStateController.setLaunchTransitionFadingAway(true);
if (beforeFading != null) {
@@ -2994,6 +2998,15 @@
}
}
+ private void cancelAfterLaunchTransitionRunnables() {
+ if (mLaunchTransitionCancelRunnable != null) {
+ mLaunchTransitionCancelRunnable.run();
+ }
+ mLaunchTransitionEndRunnable = null;
+ mLaunchTransitionCancelRunnable = null;
+ mNotificationPanelViewController.setLaunchTransitionEndRunnable(null);
+ }
+
/**
* Fades the content of the Keyguard while we are dozing and makes it invisible when finished
* fading.
@@ -3033,6 +3046,7 @@
}
private void runLaunchTransitionEndRunnable() {
+ mLaunchTransitionCancelRunnable = null;
if (mLaunchTransitionEndRunnable != null) {
Runnable r = mLaunchTransitionEndRunnable;
@@ -3524,6 +3538,10 @@
public void onStartedGoingToSleep() {
String tag = "CentralSurfaces#onStartedGoingToSleep";
DejankUtils.startDetectingBlockingIpcs(tag);
+
+ // cancel stale runnables that could put the device in the wrong state
+ cancelAfterLaunchTransitionRunnables();
+
updateRevealEffect(false /* wakingUp */);
updateNotificationPanelTouchState();
maybeEscalateHeadsUp();
@@ -3727,6 +3745,14 @@
mTransitionToFullShadeProgress = transitionToFullShadeProgress;
}
+ /**
+ * Sets the amount of progress to the bouncer being fully hidden/visible. 1 means the bouncer
+ * is fully hidden, while 0 means the bouncer is visible.
+ */
+ public void setBouncerHiddenFraction(float expansion) {
+ mScrimController.setBouncerHiddenFraction(expansion);
+ }
+
@VisibleForTesting
public void updateScrimController() {
Trace.beginSection("CentralSurfaces#updateScrimController");
@@ -3779,6 +3805,8 @@
mScrimController.transitionTo(ScrimState.AOD);
} else if (mKeyguardStateController.isShowing() && !isOccluded() && !unlocking) {
mScrimController.transitionTo(ScrimState.KEYGUARD);
+ } else if (mKeyguardStateController.isShowing() && mKeyguardUpdateMonitor.isDreaming()) {
+ mScrimController.transitionTo(ScrimState.DREAMING);
} else {
mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
}
@@ -4185,6 +4213,7 @@
new KeyguardUpdateMonitorCallback() {
@Override
public void onDreamingStateChanged(boolean dreaming) {
+ updateScrimController();
if (dreaming) {
maybeEscalateHeadsUp();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index a70ba82..57d6348 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -229,6 +229,11 @@
private boolean mShowingKeyguardHeadsUp;
private StatusBarSystemEventAnimator mSystemEventAnimator;
+ /**
+ * The alpha value to be set on the View. If -1, this value is to be ignored.
+ */
+ private float mExplicitAlpha = -1f;
+
@Inject
public KeyguardStatusBarViewController(
KeyguardStatusBarView view,
@@ -425,9 +430,15 @@
float alphaQsExpansion = 1 - Math.min(
1, mNotificationPanelViewStateProvider.getLockscreenShadeDragProgress() * 2);
- float newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
- * mKeyguardStatusBarAnimateAlpha
- * (1.0f - mKeyguardHeadsUpShowingAmount);
+
+ float newAlpha;
+ if (mExplicitAlpha != -1) {
+ newAlpha = mExplicitAlpha;
+ } else {
+ newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
+ * mKeyguardStatusBarAnimateAlpha
+ * (1.0f - mKeyguardHeadsUpShowingAmount);
+ }
boolean hideForBypass =
mFirstBypassAttempt && mKeyguardUpdateMonitor.shouldListenForFace()
@@ -510,7 +521,17 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("KeyguardStatusBarView:");
pw.println(" mBatteryListening: " + mBatteryListening);
+ pw.println(" mExplicitAlpha: " + mExplicitAlpha);
mView.dump(fd, pw, args);
}
+ /**
+ * Sets the alpha to be set on the view.
+ *
+ * @param alpha a value between 0 and 1. -1 if the value is to be reset/ignored.
+ */
+ public void setAlpha(float alpha) {
+ mExplicitAlpha = alpha;
+ updateViewState();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index ebdd257..2d16b52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -894,10 +894,17 @@
mDepthController.setBlursDisabledForUnlock(mTracking);
if (playingCannedAnimation && !isWakeAndUnlock) {
- // Fling the panel away so it's not in the way or the surface behind the
+ // Hide the panel so it's not in the way or the surface behind the
// keyguard, which will be appearing. If we're wake and unlocking, the
// lock screen is hidden instantly so should not be flung away.
- fling(0f, false, 0.7f, false);
+ if (isTracking() || isFlinging()) {
+ // Instant collpase the notification panel since the notification
+ // panel is already in the middle animating
+ onTrackingStopped(false);
+ instantCollapse();
+ } else {
+ fling(0f, false, 0.7f, false);
+ }
}
}
});
@@ -2675,6 +2682,15 @@
updateClock();
}
+ /**
+ * Sets the alpha value to be set on the keyguard status bar.
+ *
+ * @param alpha value between 0 and 1. -1 if the value is to be reset.
+ */
+ public void setKeyguardStatusBarAlpha(float alpha) {
+ mKeyguardStatusBarViewController.setAlpha(alpha);
+ }
+
private void trackMovement(MotionEvent event) {
if (mQsVelocityTracker != null) mQsVelocityTracker.addMovement(event);
}
@@ -3203,12 +3219,14 @@
@Override
protected void onUnlockHintFinished() {
super.onUnlockHintFinished();
+ mScrimController.setExpansionAffectsAlpha(true);
mNotificationStackScrollLayoutController.setUnlockHintRunning(false);
}
@Override
protected void onUnlockHintStarted() {
super.onUnlockHintStarted();
+ mScrimController.setExpansionAffectsAlpha(false);
mNotificationStackScrollLayoutController.setUnlockHintRunning(true);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index 16e5732..ffbf282 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -285,14 +285,12 @@
}
private void applyKeyguardFlags(State state) {
- final boolean scrimsOccludingWallpaper =
- state.mScrimsVisibility == ScrimController.OPAQUE || state.mLightRevealScrimOpaque;
final boolean keyguardOrAod = state.mKeyguardShowing
|| (state.mDozing && mDozeParameters.getAlwaysOn());
- if ((keyguardOrAod && !state.mBackdropShowing && !scrimsOccludingWallpaper)
+ if ((keyguardOrAod && !state.mBackdropShowing && !state.mLightRevealScrimOpaque)
|| mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe()) {
// Show the wallpaper if we're on keyguard/AOD and the wallpaper is not occluded by a
- // solid backdrop or scrim. Also, show it if we are currently animating between the
+ // solid backdrop. Also, show it if we are currently animating between the
// keyguard and the surface behind the keyguard - we want to use the wallpaper as a
// backdrop for this animation.
mLpChanged.flags |= LayoutParams.FLAG_SHOW_WALLPAPER;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
index 101c86f..787c4c03 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
@@ -36,12 +36,14 @@
import com.android.systemui.R;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dock.DockManager;
+import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.lowlightclock.LowLightClockController;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
@@ -71,6 +73,8 @@
private final LockIconViewController mLockIconViewController;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final StatusBarWindowStateController mStatusBarWindowStateController;
+ private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
+ private final AmbientState mAmbientState;
private GestureDetector mGestureDetector;
private View mBrightnessMirror;
@@ -109,7 +113,9 @@
LockIconViewController lockIconViewController,
Optional<LowLightClockController> lowLightClockController,
CentralSurfaces centralSurfaces,
- NotificationShadeWindowController controller) {
+ NotificationShadeWindowController controller,
+ KeyguardUnlockAnimationController keyguardUnlockAnimationController,
+ AmbientState ambientState) {
mLockscreenShadeTransitionController = transitionController;
mFalsingCollector = falsingCollector;
mTunerService = tunerService;
@@ -126,6 +132,8 @@
mLowLightClockController = lowLightClockController;
mService = centralSurfaces;
mNotificationShadeWindowController = controller;
+ mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
+ mAmbientState = ambientState;
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
@@ -203,7 +211,6 @@
// Reset manual touch dispatch state here but make sure the UP/CANCEL event still
// gets
// delivered.
-
if (!isCancel && mService.shouldIgnoreTouch()) {
return false;
}
@@ -219,6 +226,16 @@
return false;
}
+ if (mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
+ // If the user was sliding their finger across the lock screen,
+ // we may have been intercepting the touch and forwarding it to the
+ // UDFPS affordance via mStatusBarKeyguardViewManager.onTouch (see below).
+ // If this touch ended up unlocking the device, we want to cancel the touch
+ // immediately, so we don't cause swipe or expand animations afterwards.
+ cancelCurrentTouch();
+ return true;
+ }
+
mFalsingCollector.onTouchEvent(ev);
mGestureDetector.onTouchEvent(ev);
mStatusBarKeyguardViewManager.onTouch(ev);
@@ -430,6 +447,7 @@
event.recycle();
mTouchCancelled = true;
}
+ mAmbientState.setSwipingUp(false);
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 78edc07..be50a17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -48,6 +48,7 @@
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
+import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.systemui.DejankUtils;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
@@ -796,7 +797,10 @@
}
mExpandedFraction = Math.min(1f,
maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
- mAmbientState.setExpansionFraction(mExpandedFraction);
+ mAmbientState.setExpansionFraction(mKeyguardStateController.isUnlocked()
+ ? mExpandedFraction
+ : BouncerPanelExpansionCalculator
+ .getBackScrimScaledExpansion(mExpandedFraction));
onHeightUpdated(mExpandedHeight);
updatePanelExpansionAndVisibility();
});
@@ -865,6 +869,10 @@
return mClosing || mIsLaunchAnimationRunning;
}
+ public boolean isFlinging() {
+ return mIsFlinging;
+ }
+
public boolean isTracking() {
return mTracking;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 029a7a5..8272ed9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -52,6 +52,7 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
+import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.statusbar.notification.stack.ViewState;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
@@ -137,6 +138,13 @@
private boolean mUnOcclusionAnimationRunning;
/**
+ * The percentage of the bouncer which is hidden. If 1, the bouncer is completely hidden. If
+ * 0, the bouncer is visible.
+ */
+ @FloatRange(from = 0, to = 1)
+ private float mBouncerHiddenFraction = KeyguardBouncer.EXPANSION_HIDDEN;
+
+ /**
* Set whether an unocclusion animation is currently running on the notification panel. Used
* to avoid bright flickers of the notification scrim.
*/
@@ -195,6 +203,7 @@
private final Handler mHandler;
private final Executor mMainExecutor;
private final ScreenOffAnimationController mScreenOffAnimationController;
+ private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private GradientColors mColors;
private boolean mNeedsDrawableColorUpdate;
@@ -211,6 +220,7 @@
private float mPanelExpansionFraction = 1f; // Assume shade is expanded during initialization
private float mQsExpansion;
private boolean mQsBottomVisible;
+ private boolean mAnimatingPanelExpansionOnUnlock; // don't animate scrim
private boolean mDarkenWhileDragging;
private boolean mExpansionAffectsAlpha = true;
@@ -255,7 +265,8 @@
KeyguardUpdateMonitor keyguardUpdateMonitor, DockManager dockManager,
ConfigurationController configurationController, @Main Executor mainExecutor,
ScreenOffAnimationController screenOffAnimationController,
- PanelExpansionStateManager panelExpansionStateManager) {
+ PanelExpansionStateManager panelExpansionStateManager,
+ KeyguardUnlockAnimationController keyguardUnlockAnimationController) {
mScrimStateListener = lightBarController::setScrimState;
mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;
@@ -273,6 +284,7 @@
// to make sure that text on top of it is legible.
mDozeParameters = dozeParameters;
mDockManager = dockManager;
+ mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@Override
public void onKeyguardFadingAwayChanged() {
@@ -497,6 +509,9 @@
public void onTrackingStarted() {
mTracking = true;
mDarkenWhileDragging = !mKeyguardStateController.canDismissLockScreen();
+ if (!mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
+ mAnimatingPanelExpansionOnUnlock = false;
+ }
}
public void onExpandingFinished() {
@@ -567,13 +582,21 @@
}
if (mPanelExpansionFraction != panelExpansionFraction) {
+ if (panelExpansionFraction != 0f
+ && mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
+ mAnimatingPanelExpansionOnUnlock = true;
+ } else if (panelExpansionFraction == 0f) {
+ mAnimatingPanelExpansionOnUnlock = false;
+ }
+
mPanelExpansionFraction = panelExpansionFraction;
boolean relevantState = (mState == ScrimState.UNLOCKED
|| mState == ScrimState.KEYGUARD
+ || mState == ScrimState.DREAMING
|| mState == ScrimState.SHADE_LOCKED
|| mState == ScrimState.PULSING);
- if (!(relevantState && mExpansionAffectsAlpha)) {
+ if (!(relevantState && mExpansionAffectsAlpha) || mAnimatingPanelExpansionOnUnlock) {
return;
}
applyAndDispatchState();
@@ -630,6 +653,13 @@
}
/**
+ * Sets the amount of vertical over scroll that should be performed on the notifications scrim.
+ */
+ public void setNotificationsOverScrollAmount(int overScrollAmount) {
+ mNotificationsScrim.setTranslationY(overScrollAmount);
+ }
+
+ /**
* Current state of the QuickSettings when pulling it from the top.
*
* @param expansionFraction From 0 to 1 where 0 means collapsed and 1 expanded.
@@ -655,6 +685,21 @@
}
/**
+ * Updates the percentage of the bouncer which is hidden.
+ */
+ public void setBouncerHiddenFraction(@FloatRange(from = 0, to = 1) float bouncerHiddenAmount) {
+ if (mBouncerHiddenFraction == bouncerHiddenAmount) {
+ return;
+ }
+ mBouncerHiddenFraction = bouncerHiddenAmount;
+ if (mState == ScrimState.DREAMING) {
+ // Only the dreaming state requires this for the scrim calculation, so we should
+ // only trigger an update if dreaming.
+ applyAndDispatchState();
+ }
+ }
+
+ /**
* If QS and notification scrims should not overlap, and should be clipped to each other's
* bounds instead.
*/
@@ -719,10 +764,12 @@
return;
}
- if (mState == ScrimState.UNLOCKED) {
+ if (mState == ScrimState.UNLOCKED || mState == ScrimState.DREAMING) {
// Darken scrim as you pull down the shade when unlocked, unless the shade is expanding
- // because we're doing the screen off animation.
- if (!mScreenOffAnimationController.shouldExpandNotifications()) {
+ // because we're doing the screen off animation OR the shade is collapsing because
+ // we're playing the unlock animation
+ if (!mScreenOffAnimationController.shouldExpandNotifications()
+ && !mAnimatingPanelExpansionOnUnlock) {
float behindFraction = getInterpolatedFraction();
behindFraction = (float) Math.pow(behindFraction, 0.8f);
if (mClipsQsScrim) {
@@ -735,14 +782,30 @@
mNotificationsAlpha = MathUtils.constrainedMap(0f, 1f, 0.3f, 0.75f,
mPanelExpansionFraction);
}
+ mBehindTint = mState.getBehindTint();
mInFrontAlpha = 0;
}
+
+ if (mBouncerHiddenFraction != KeyguardBouncer.EXPANSION_HIDDEN) {
+ final float interpolatedFraction =
+ BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(
+ mBouncerHiddenFraction);
+ mBehindAlpha = MathUtils.lerp(mDefaultScrimAlpha, mBehindAlpha,
+ interpolatedFraction);
+ mBehindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(),
+ mBehindTint,
+ interpolatedFraction);
+ }
} else if (mState == ScrimState.AUTH_SCRIMMED_SHADE) {
float behindFraction = getInterpolatedFraction();
behindFraction = (float) Math.pow(behindFraction, 0.8f);
mBehindAlpha = behindFraction * mDefaultScrimAlpha;
mNotificationsAlpha = mBehindAlpha;
+ if (mClipsQsScrim) {
+ mBehindAlpha = 1;
+ mBehindTint = Color.BLACK;
+ }
} else if (mState == ScrimState.KEYGUARD || mState == ScrimState.SHADE_LOCKED
|| mState == ScrimState.PULSING) {
Pair<Integer, Float> result = calculateBackStateForState(mState);
@@ -794,6 +857,9 @@
mNotificationsTint = ScrimState.KEYGUARD.getNotifTint();
}
}
+ if (mState != ScrimState.UNLOCKED) {
+ mAnimatingPanelExpansionOnUnlock = false;
+ }
assertAlphasValid();
}
@@ -809,14 +875,7 @@
private Pair<Integer, Float> calculateBackStateForState(ScrimState state) {
// Either darken of make the scrim transparent when you
// pull down the shade
- float interpolatedFract;
-
- if (state == ScrimState.KEYGUARD) {
- interpolatedFract = BouncerPanelExpansionCalculator
- .getBackScrimScaledExpansion(mPanelExpansionFraction);
- } else {
- interpolatedFract = getInterpolatedFraction();
- }
+ float interpolatedFract = getInterpolatedFraction();
float stateBehind = mClipsQsScrim ? state.getNotifAlpha() : state.getBehindAlpha();
float behindAlpha;
@@ -998,6 +1057,10 @@
}
private float getInterpolatedFraction() {
+ if (mState == ScrimState.KEYGUARD || mState == ScrimState.SHADE_LOCKED) {
+ return BouncerPanelExpansionCalculator
+ .getBackScrimScaledExpansion(mPanelExpansionFraction);
+ }
return ShadeInterpolation.getNotificationScrimAlpha(mPanelExpansionFraction);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 9028870..47b7058 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -262,6 +262,25 @@
updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK);
}
}
+ },
+
+ DREAMING {
+ @Override
+ public void prepare(ScrimState previousState) {
+ mFrontTint = Color.TRANSPARENT;
+ mBehindTint = Color.BLACK;
+ mNotifTint = mClipQsScrim ? Color.BLACK : Color.TRANSPARENT;
+
+ mFrontAlpha = 0;
+ mBehindAlpha = mClipQsScrim ? 1 : 0;
+ mNotifAlpha = 0;
+
+ mBlankScreen = false;
+
+ if (mClipQsScrim) {
+ updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK);
+ }
+ }
};
boolean mBlankScreen = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 23a1087..ff352e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -19,6 +19,7 @@
import static android.view.WindowInsets.Type.navigationBars;
import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_COLLAPSING;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_FADING;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
@@ -120,9 +121,13 @@
private final FoldAodAnimationController mFoldAodAnimationController;
private KeyguardMessageAreaController mKeyguardMessageAreaController;
private final Lazy<ShadeController> mShadeController;
+
private final BouncerExpansionCallback mExpansionCallback = new BouncerExpansionCallback() {
+ private boolean mBouncerAnimating;
+
@Override
public void onFullyShown() {
+ mBouncerAnimating = false;
updateStates();
mCentralSurfaces.wakeUpIfDozing(SystemClock.uptimeMillis(),
mCentralSurfaces.getBouncerContainer(), "BOUNCER_VISIBLE");
@@ -130,16 +135,19 @@
@Override
public void onStartingToHide() {
+ mBouncerAnimating = true;
updateStates();
}
@Override
public void onStartingToShow() {
+ mBouncerAnimating = true;
updateStates();
}
@Override
public void onFullyHidden() {
+ mBouncerAnimating = false;
}
@Override
@@ -147,6 +155,9 @@
if (mAlternateAuthInterceptor != null) {
mAlternateAuthInterceptor.setBouncerExpansionChanged(expansion);
}
+ if (mBouncerAnimating) {
+ mCentralSurfaces.setBouncerHiddenFraction(expansion);
+ }
updateStates();
}
@@ -154,6 +165,7 @@
public void onVisibilityChanged(boolean isVisible) {
if (!isVisible) {
cancelPostAuthActions();
+ mCentralSurfaces.setBouncerHiddenFraction(KeyguardBouncer.EXPANSION_HIDDEN);
}
if (mAlternateAuthInterceptor != null) {
mAlternateAuthInterceptor.onBouncerVisibilityChanged();
@@ -360,7 +372,9 @@
} else if (bouncerNeedsScrimming()) {
mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
} else if (mShowing) {
- if (!isWakeAndUnlocking() && !mCentralSurfaces.isInLaunchTransition()) {
+ if (!isWakeAndUnlocking()
+ && !mCentralSurfaces.isInLaunchTransition()
+ && !isUnlockCollapsing()) {
mBouncer.setExpansion(fraction);
}
if (fraction != KeyguardBouncer.EXPANSION_HIDDEN && tracking
@@ -528,6 +542,11 @@
return mode == MODE_WAKE_AND_UNLOCK || mode == MODE_WAKE_AND_UNLOCK_PULSING;
}
+ private boolean isUnlockCollapsing() {
+ int mode = mBiometricUnlockController.getMode();
+ return mode == MODE_UNLOCK_COLLAPSING;
+ }
+
/**
* Adds a {@param runnable} to be executed after Keyguard is gone.
*/
@@ -657,14 +676,17 @@
SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__OCCLUDED);
if (mCentralSurfaces.isInLaunchTransition()) {
setOccludedAndUpdateStates(true);
- mCentralSurfaces.fadeKeyguardAfterLaunchTransition(null /* beforeFading */,
- new Runnable() {
- @Override
- public void run() {
- mNotificationShadeWindowController.setKeyguardOccluded(mOccluded);
- reset(true /* hideBouncerWhenShowing */);
- }
- });
+ final Runnable endRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mNotificationShadeWindowController.setKeyguardOccluded(mOccluded);
+ reset(true /* hideBouncerWhenShowing */);
+ }
+ };
+ mCentralSurfaces.fadeKeyguardAfterLaunchTransition(
+ null /* beforeFading */,
+ endRunnable,
+ endRunnable);
return;
}
@@ -759,7 +781,7 @@
hideBouncer(true /* destroyView */);
updateStates();
}
- }, new Runnable() {
+ }, /* endRunnable */ new Runnable() {
@Override
public void run() {
mCentralSurfaces.hideKeyguard();
@@ -772,6 +794,15 @@
mViewMediatorCallback.keyguardGone();
executeAfterKeyguardGoneAction();
}
+ }, /* cancelRunnable */ new Runnable() {
+ @Override
+ public void run() {
+ mNotificationShadeWindowController.setKeyguardFadingAway(false);
+ if (wasFlingingToDismissKeyguard) {
+ mCentralSurfaces.finishKeyguardFadingAway();
+ }
+ cancelPostAuthActions();
+ }
});
} else {
executeAfterKeyguardGoneAction();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
index 62549a7..0d52f46 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
@@ -19,10 +19,10 @@
import android.content.Intent
import android.os.UserHandle
import android.view.View
-import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.FalsingManager
import com.android.systemui.qs.user.UserSwitchDialogController
import com.android.systemui.user.UserSwitcherActivity
@@ -39,7 +39,8 @@
private val featureController: StatusBarUserSwitcherFeatureController,
private val userSwitcherDialogController: UserSwitchDialogController,
private val featureFlags: FeatureFlags,
- private val activityStarter: ActivityStarter
+ private val activityStarter: ActivityStarter,
+ private val falsingManager: FalsingManager
) : ViewController<StatusBarUserSwitcherContainer>(view),
StatusBarUserSwitcherController {
private val listener = object : CurrentUserChipInfoUpdatedListener {
@@ -58,16 +59,20 @@
}
}
- override fun onViewAttached() {
+ public override fun onViewAttached() {
tracker.addCallback(listener)
featureController.addCallback(featureFlagListener)
mView.setOnClickListener { view: View ->
+ if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
+ return@setOnClickListener
+ }
+
if (featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)) {
val intent = Intent(context, UserSwitcherActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
activityStarter.startActivity(intent, true /* dismissShade */,
- ActivityLaunchAnimator.Controller.fromView(view, null),
+ null /* ActivityLaunchAnimator.Controller */,
true /* showOverlockscreenwhenlocked */, UserHandle.SYSTEM)
} else {
userSwitcherDialogController.showDialog(view)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
index 3b272da8..bc2ae64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
@@ -68,6 +68,7 @@
internal const val PREFS_CONTROLS_SEEDING_COMPLETED = "SeedingCompleted"
internal const val PREFS_CONTROLS_FILE = "controls_prefs"
+ internal const val PREFS_SETTINGS_DIALOG_ATTEMPTS = "show_settings_attempts"
private const val SEEDING_MAX = 2
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index 978564f..189dca6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -207,6 +207,8 @@
private void setKeyguardFadingAway(boolean keyguardFadingAway) {
if (mKeyguardFadingAway != keyguardFadingAway) {
+ Trace.traceCounter(Trace.TRACE_TAG_APP, "keyguardFadingAway",
+ keyguardFadingAway ? 1 : 0);
mKeyguardFadingAway = keyguardFadingAway;
ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks);
for (int i = 0; i < callbacks.size(); i++) {
@@ -217,7 +219,7 @@
@Override
public void notifyKeyguardDoneFading() {
- mKeyguardGoingAway = false;
+ notifyKeyguardGoingAway(false);
setKeyguardFadingAway(false);
}
@@ -318,7 +320,11 @@
@Override
public void notifyKeyguardGoingAway(boolean keyguardGoingAway) {
- mKeyguardGoingAway = keyguardGoingAway;
+ if (mKeyguardGoingAway != keyguardGoingAway) {
+ Trace.traceCounter(Trace.TRACE_TAG_APP, "keyguardGoingAway",
+ keyguardGoingAway ? 1 : 0);
+ mKeyguardGoingAway = keyguardGoingAway;
+ }
}
@Override
@@ -368,6 +374,8 @@
pw.println(" mTrusted: " + mTrusted);
pw.println(" mDebugUnlocked: " + mDebugUnlocked);
pw.println(" mFaceAuthEnabled: " + mFaceAuthEnabled);
+ pw.println(" isKeyguardFadingAway: " + isKeyguardFadingAway());
+ pw.println(" isKeyguardGoingAway: " + isKeyguardGoingAway());
}
private class UpdateMonitorCallback extends KeyguardUpdateMonitorCallback {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index ca5edb5..8396639 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -51,6 +51,7 @@
import android.view.View;
import android.view.WindowManagerGlobal;
import android.widget.BaseAdapter;
+import android.widget.Toast;
import androidx.annotation.Nullable;
@@ -59,6 +60,8 @@
import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.LatencyTracker;
import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.android.settingslib.users.UserCreatingDialog;
+import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.Dumpable;
import com.android.systemui.GuestResumeSessionReceiver;
import com.android.systemui.Prefs;
@@ -89,6 +92,7 @@
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
import javax.inject.Inject;
@@ -482,26 +486,25 @@
@VisibleForTesting
void onUserListItemClicked(UserRecord record, DialogShower dialogShower) {
- int id;
if (record.isGuest && record.info == null) {
// No guest user. Create one.
- int guestId = createGuest();
- if (guestId == UserHandle.USER_NULL) {
- // This may happen if we haven't reloaded the user list yet.
- return;
- }
- mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_ADD);
- id = guestId;
+ createGuestAsync(guestId -> {
+ // guestId may be USER_NULL if we haven't reloaded the user list yet.
+ if (guestId != UserHandle.USER_NULL) {
+ mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_ADD);
+ onUserListItemClicked(guestId, record, dialogShower);
+ }
+ });
} else if (record.isAddUser) {
showAddUserDialog(dialogShower);
- return;
} else if (record.isAddSupervisedUser) {
startSupervisedUserActivity();
- return;
} else {
- id = record.info.id;
+ onUserListItemClicked(record.info.id, record, dialogShower);
}
+ }
+ private void onUserListItemClicked(int id, UserRecord record, DialogShower dialogShower) {
int currUserId = mUserTracker.getUserId();
if (currUserId == id) {
if (record.isGuest) {
@@ -509,7 +512,6 @@
}
return;
}
-
if (UserManager.isGuestUserEphemeral()) {
// If switching from guest, we want to bring up the guest exit dialog instead of switching
UserInfo currUserInfo = mUserManager.getUserInfo(currUserId);
@@ -760,29 +762,30 @@
return;
}
- try {
- if (targetUserId == UserHandle.USER_NULL) {
- // Create a new guest in the foreground, and then immediately switch to it
- int newGuestId = createGuest();
+ if (targetUserId == UserHandle.USER_NULL) {
+ // Create a new guest in the foreground, and then immediately switch to it
+ createGuestAsync(newGuestId -> {
if (newGuestId == UserHandle.USER_NULL) {
Log.e(TAG, "Could not create new guest, switching back to system user");
switchToUserId(UserHandle.USER_SYSTEM);
mUserManager.removeUser(currentUser.id);
- WindowManagerGlobal.getWindowManagerService().lockNow(/* options= */ null);
+ try {
+ WindowManagerGlobal.getWindowManagerService().lockNow(/* options= */ null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't remove guest because ActivityManager "
+ + "or WindowManager is dead");
+ }
return;
}
switchToUserId(newGuestId);
mUserManager.removeUser(currentUser.id);
- } else {
- if (mGuestUserAutoCreated) {
- mGuestIsResetting.set(true);
- }
- switchToUserId(targetUserId);
- mUserManager.removeUser(currentUser.id);
+ });
+ } else {
+ if (mGuestUserAutoCreated) {
+ mGuestIsResetting.set(true);
}
- } catch (RemoteException e) {
- Log.e(TAG, "Couldn't remove guest because ActivityManager or WindowManager is dead");
- return;
+ switchToUserId(targetUserId);
+ mUserManager.removeUser(currentUser.id);
}
}
@@ -831,6 +834,24 @@
}
}
+ private void createGuestAsync(Consumer<Integer> callback) {
+ final Dialog guestCreationProgressDialog =
+ new UserCreatingDialog(mContext, /* isGuest= */true);
+ guestCreationProgressDialog.show();
+
+ // userManager.createGuest will block the thread so post is needed for the dialog to show
+ ThreadUtils.postOnMainThread(() -> {
+ final int guestId = createGuest();
+ guestCreationProgressDialog.dismiss();
+ if (guestId == UserHandle.USER_NULL) {
+ Toast.makeText(mContext,
+ com.android.settingslib.R.string.add_guest_failed,
+ Toast.LENGTH_SHORT).show();
+ }
+ callback.accept(guestId);
+ });
+ }
+
/**
* Creates a guest user and return its multi-user user ID.
*
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index fb80551..c06b8e6 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -38,6 +38,7 @@
import android.content.om.OverlayIdentifier;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Color;
import android.net.Uri;
@@ -53,6 +54,7 @@
import android.util.TypedValue;
import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
import com.android.systemui.CoreStartable;
@@ -114,10 +116,12 @@
private final boolean mIsMonetEnabled;
private final UserTracker mUserTracker;
private final DeviceProvisionedController mDeviceProvisionedController;
+ private final Resources mResources;
// Current wallpaper colors associated to a user.
private final SparseArray<WallpaperColors> mCurrentColors = new SparseArray<>();
private final WallpaperManager mWallpaperManager;
- private ColorScheme mColorScheme;
+ @VisibleForTesting
+ protected ColorScheme mColorScheme;
// If fabricated overlays were already created for the current theme.
private boolean mNeedsOverlayCreation;
// Dominant color extracted from wallpaper, NOT the color used on the overlay
@@ -344,7 +348,7 @@
SecureSettings secureSettings, WallpaperManager wallpaperManager,
UserManager userManager, DeviceProvisionedController deviceProvisionedController,
UserTracker userTracker, DumpManager dumpManager, FeatureFlags featureFlags,
- WakefulnessLifecycle wakefulnessLifecycle) {
+ @Main Resources resources, WakefulnessLifecycle wakefulnessLifecycle) {
super(context);
mIsMonetEnabled = featureFlags.isEnabled(Flags.MONET);
@@ -358,6 +362,7 @@
mSecureSettings = secureSettings;
mWallpaperManager = wallpaperManager;
mUserTracker = userTracker;
+ mResources = resources;
mWakefulnessLifecycle = wakefulnessLifecycle;
dumpManager.registerDumpable(TAG, this);
}
@@ -466,8 +471,13 @@
mMainWallpaperColor = mainColor;
if (mIsMonetEnabled) {
+ mThemeStyle = fetchThemeStyleFromSetting();
mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle);
mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle);
+ if (colorSchemeIsApplied()) {
+ Log.d(TAG, "Skipping overlay creation. Theme was already: " + mColorScheme);
+ return;
+ }
mNeedsOverlayCreation = true;
if (DEBUG) {
Log.d(TAG, "fetched overlays. accent: " + mSecondaryOverlay
@@ -493,7 +503,7 @@
* Given a color candidate, return an overlay definition.
*/
protected @Nullable FabricatedOverlay getOverlay(int color, int type, Style style) {
- boolean nightMode = (mContext.getResources().getConfiguration().uiMode
+ boolean nightMode = (mResources.getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
mColorScheme = new ColorScheme(color, nightMode, style);
@@ -525,6 +535,23 @@
return overlay.build();
}
+ /**
+ * Checks if the color scheme in mColorScheme matches the current system palettes.
+ */
+ private boolean colorSchemeIsApplied() {
+ return mResources.getColor(
+ android.R.color.system_accent1_500, mContext.getTheme())
+ == mColorScheme.getAccent1().get(6)
+ && mResources.getColor(android.R.color.system_accent2_500, mContext.getTheme())
+ == mColorScheme.getAccent2().get(6)
+ && mResources.getColor(android.R.color.system_accent3_500, mContext.getTheme())
+ == mColorScheme.getAccent3().get(6)
+ && mResources.getColor(android.R.color.system_neutral1_500, mContext.getTheme())
+ == mColorScheme.getNeutral1().get(6)
+ && mResources.getColor(android.R.color.system_neutral2_500, mContext.getTheme())
+ == mColorScheme.getNeutral2().get(6);
+ }
+
private void updateThemeOverlays() {
final int currentUser = mUserTracker.getUserId();
final String overlayPackageJson = mSecureSettings.getStringForUser(
@@ -532,7 +559,6 @@
currentUser);
if (DEBUG) Log.d(TAG, "updateThemeOverlays. Setting: " + overlayPackageJson);
final Map<String, OverlayIdentifier> categoryToPackage = new ArrayMap<>();
- Style newStyle = mThemeStyle;
if (!TextUtils.isEmpty(overlayPackageJson)) {
try {
JSONObject object = new JSONObject(overlayPackageJson);
@@ -543,25 +569,11 @@
categoryToPackage.put(category, identifier);
}
}
-
- try {
- newStyle = Style.valueOf(
- object.getString(ThemeOverlayApplier.OVERLAY_CATEGORY_THEME_STYLE));
- } catch (IllegalArgumentException e) {
- newStyle = Style.TONAL_SPOT;
- }
} catch (JSONException e) {
Log.i(TAG, "Failed to parse THEME_CUSTOMIZATION_OVERLAY_PACKAGES.", e);
}
}
- if (mIsMonetEnabled && newStyle != mThemeStyle) {
- mThemeStyle = newStyle;
- mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle);
- mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle);
- mNeedsOverlayCreation = true;
- }
-
// Let's generate system overlay if the style picker decided to override it.
OverlayIdentifier systemPalette = categoryToPackage.get(OVERLAY_CATEGORY_SYSTEM_PALETTE);
if (mIsMonetEnabled && systemPalette != null && systemPalette.getPackageName() != null) {
@@ -626,6 +638,24 @@
}
}
+ private Style fetchThemeStyleFromSetting() {
+ Style style = mThemeStyle;
+ final String overlayPackageJson = mSecureSettings.getStringForUser(
+ Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
+ mUserTracker.getUserId());
+ if (!TextUtils.isEmpty(overlayPackageJson)) {
+ try {
+ JSONObject object = new JSONObject(overlayPackageJson);
+ style = Style.valueOf(
+ object.getString(ThemeOverlayApplier.OVERLAY_CATEGORY_THEME_STYLE));
+ } catch (JSONException | IllegalArgumentException e) {
+ Log.i(TAG, "Failed to parse THEME_CUSTOMIZATION_OVERLAY_PACKAGES.", e);
+ style = Style.TONAL_SPOT;
+ }
+ }
+ return style;
+ }
+
@Override
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("mSystemColors=" + mCurrentColors);
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
index 7072890..3c869e7 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
@@ -33,6 +33,7 @@
import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.util.settings.SecureSettings;
@@ -64,6 +65,7 @@
private final Context mContext;
private final Executor mExecutor;
private final Executor mCallbackExecutor;
+ private final Executor mBgExecutor;
private final SecureSettings mSecureSettings;
private final SystemClock mClock;
@@ -80,12 +82,14 @@
Context context,
@Main Executor executor,
@CallbackExecutor Executor callbackExecutor,
+ @Background Executor bgExecutor,
SecureSettings secureSettings,
QuickAccessWalletClient quickAccessWalletClient,
SystemClock clock) {
mContext = context;
mExecutor = executor;
mCallbackExecutor = callbackExecutor;
+ mBgExecutor = bgExecutor;
mSecureSettings = secureSettings;
mQuickAccessWalletClient = quickAccessWalletClient;
mClock = clock;
@@ -182,7 +186,7 @@
* Re-create the {@link QuickAccessWalletClient} of the controller.
*/
public void reCreateWalletClient() {
- mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext);
+ mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext, mBgExecutor);
mQawClientCreatedTimeMillis = mClock.elapsedRealtime();
}
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
index c1f5516..2c901d2 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
@@ -21,8 +21,11 @@
import android.service.quickaccesswallet.QuickAccessWalletClient;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.wallet.ui.WalletActivity;
+import java.util.concurrent.Executor;
+
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
@@ -45,7 +48,8 @@
/** */
@SysUISingleton
@Provides
- public static QuickAccessWalletClient provideQuickAccessWalletClient(Context context) {
- return QuickAccessWalletClient.create(context);
+ public static QuickAccessWalletClient provideQuickAccessWalletClient(Context context,
+ @Background Executor bgExecutor) {
+ return QuickAccessWalletClient.create(context, bgExecutor);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
index 92e7f2d..89c3100 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
@@ -122,7 +122,7 @@
getActionBar().setHomeActionContentDescription(R.string.accessibility_desc_close);
WalletView walletView = requireViewById(R.id.wallet_view);
- mWalletClient = QuickAccessWalletClient.create(this);
+ mWalletClient = QuickAccessWalletClient.create(this, mExecutor);
mWalletScreenController = new WalletScreenController(
this,
walletView,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 6736bfd..14c903c 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -34,6 +34,7 @@
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.graphics.Insets;
+import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.Gravity;
@@ -204,10 +205,14 @@
mKeyguardSecurityContainer.updatePositionByTouchX(
mKeyguardSecurityContainer.getWidth() - 1f);
+ verify(mGlobalSettings).putInt(Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
+ Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT);
verify(mSecurityViewFlipper).setTranslationX(
mKeyguardSecurityContainer.getWidth() - mSecurityViewFlipper.getWidth());
mKeyguardSecurityContainer.updatePositionByTouchX(1f);
+ verify(mGlobalSettings).putInt(Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
+ Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT);
verify(mSecurityViewFlipper).setTranslationX(0.0f);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index ac78626..bcccbc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -33,6 +33,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -60,11 +61,9 @@
import android.view.Display;
import android.view.DisplayCutout;
import android.view.View;
-import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowMetrics;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
@@ -103,7 +102,7 @@
private SecureSettings mSecureSettings;
private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
private FakeThreadFactory mThreadFactory;
- private ArrayList<DecorProvider> mPrivacyDecorProviders;
+ private ArrayList<DecorProvider> mDecorProviders;
@Mock
private Display mDisplay;
@Mock
@@ -126,6 +125,8 @@
private CornerDecorProvider mPrivacyDotBottomLeftDecorProvider;
@Mock
private CornerDecorProvider mPrivacyDotBottomRightDecorProvider;
+ @Mock
+ private Display.Mode mDisplayMode;
@Before
public void setup() {
@@ -198,43 +199,17 @@
reset(mTunerService);
}
- @NonNull
- private int[] getRoundCornerIdsFromOverlayId(@DisplayCutout.BoundsPosition int overlayId) {
- switch (overlayId) {
- case BOUNDS_POSITION_LEFT:
- return new int[] {
- R.id.rounded_corner_top_left,
- R.id.rounded_corner_top_left };
- case BOUNDS_POSITION_TOP:
- return new int[] {
- R.id.rounded_corner_top_left,
- R.id.rounded_corner_top_right };
- case BOUNDS_POSITION_RIGHT:
- return new int[] {
- R.id.rounded_corner_top_right,
- R.id.rounded_corner_bottom_right };
- case BOUNDS_POSITION_BOTTOM:
- return new int[] {
- R.id.rounded_corner_bottom_left,
- R.id.rounded_corner_bottom_right };
- default:
- throw new IllegalArgumentException("unknown overlayId: " + overlayId);
- }
- }
- private void verifyRoundedCornerViewsExist(
+ private void verifyRoundedCornerViewsVisibility(
@DisplayCutout.BoundsPosition final int overlayId,
- @View.Visibility final boolean isExist) {
+ @View.Visibility final int visibility) {
final View overlay = mScreenDecorations.mOverlays[overlayId].getRootView();
- for (int id: getRoundCornerIdsFromOverlayId(overlayId)) {
- final View view = overlay.findViewById(id);
- if (isExist) {
- assertNotNull(view);
- assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
- } else {
- assertNull(view);
- }
- }
+ final View left = overlay.findViewById(R.id.left);
+ final View right = overlay.findViewById(R.id.right);
+ assertNotNull(left);
+ assertNotNull(right);
+ assertThat(left.getVisibility()).isEqualTo(visibility);
+ assertThat(right.getVisibility()).isEqualTo(visibility);
}
@Nullable
@@ -378,8 +353,8 @@
verifyOverlaysExistAndAdded(false, true, false, true);
// Rounded corner views shall not exist
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_TOP, false);
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_BOTTOM, false);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.GONE);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.GONE);
// Privacy dots shall exist but invisible
verifyDotViewsVisibility(View.INVISIBLE);
@@ -407,8 +382,8 @@
verifyOverlaysExistAndAdded(false, true, false, true);
// Rounded corner views shall exist
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_TOP, true);
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_BOTTOM, true);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.VISIBLE);
// Privacy dots shall not exist
verifyDotViewsNullable(true);
@@ -435,8 +410,8 @@
verifyOverlaysExistAndAdded(false, true, false, true);
// Rounded corner views shall exist
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_TOP, true);
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_BOTTOM, true);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.VISIBLE);
// Privacy dots shall exist but invisible
verifyDotViewsVisibility(View.INVISIBLE);
@@ -476,26 +451,21 @@
mScreenDecorations.start();
View leftRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP].getRootView()
- .findViewById(R.id.rounded_corner_top_left);
+ .findViewById(R.id.left);
View rightRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP].getRootView()
- .findViewById(R.id.rounded_corner_top_right);
- ViewGroup.LayoutParams leftParams = leftRoundedCorner.getLayoutParams();
- ViewGroup.LayoutParams rightParams = rightRoundedCorner.getLayoutParams();
- assertEquals(leftParams.width, testTopRadius);
- assertEquals(leftParams.height, testTopRadius);
- assertEquals(rightParams.width, testTopRadius);
- assertEquals(rightParams.height, testTopRadius);
-
+ .findViewById(R.id.right);
+ verify(mScreenDecorations, atLeastOnce())
+ .setSize(leftRoundedCorner, new Size(testTopRadius, testTopRadius));
+ verify(mScreenDecorations, atLeastOnce())
+ .setSize(rightRoundedCorner, new Size(testTopRadius, testTopRadius));
leftRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView()
- .findViewById(R.id.rounded_corner_bottom_left);
+ .findViewById(R.id.left);
rightRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView()
- .findViewById(R.id.rounded_corner_bottom_right);
- leftParams = leftRoundedCorner.getLayoutParams();
- rightParams = rightRoundedCorner.getLayoutParams();
- assertEquals(leftParams.width, testBottomRadius);
- assertEquals(leftParams.height, testBottomRadius);
- assertEquals(rightParams.width, testBottomRadius);
- assertEquals(rightParams.height, testBottomRadius);
+ .findViewById(R.id.right);
+ verify(mScreenDecorations, atLeastOnce())
+ .setSize(leftRoundedCorner, new Size(testBottomRadius, testBottomRadius));
+ verify(mScreenDecorations, atLeastOnce())
+ .setSize(rightRoundedCorner, new Size(testBottomRadius, testBottomRadius));
}
@Test
@@ -511,27 +481,31 @@
.when(mScreenDecorations).getCutout();
mScreenDecorations.start();
- View topRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_LEFT].getRootView()
- .findViewById(R.id.rounded_corner_top_left);
- View bottomRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_LEFT].getRootView()
- .findViewById(R.id.rounded_corner_bottom_left);
- ViewGroup.LayoutParams topParams = topRoundedCorner.getLayoutParams();
- ViewGroup.LayoutParams bottomParams = bottomRoundedCorner.getLayoutParams();
- assertEquals(topParams.width, testTopRadius);
- assertEquals(topParams.height, testTopRadius);
- assertEquals(bottomParams.width, testBottomRadius);
- assertEquals(bottomParams.height, testBottomRadius);
+ final Size topRadius = new Size(testTopRadius, testTopRadius);
+ final Size bottomRadius = new Size(testBottomRadius, testBottomRadius);
+ View leftRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_LEFT].getRootView()
+ .findViewById(R.id.left);
+ boolean isTop = mScreenDecorations.isTopRoundedCorner(BOUNDS_POSITION_LEFT, R.id.left);
+ verify(mScreenDecorations, atLeastOnce())
+ .setSize(leftRoundedCorner, isTop ? topRadius : bottomRadius);
- topRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_RIGHT].getRootView()
- .findViewById(R.id.rounded_corner_top_right);
- bottomRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_RIGHT].getRootView()
- .findViewById(R.id.rounded_corner_bottom_right);
- topParams = topRoundedCorner.getLayoutParams();
- bottomParams = bottomRoundedCorner.getLayoutParams();
- assertEquals(topParams.width, testTopRadius);
- assertEquals(topParams.height, testTopRadius);
- assertEquals(bottomParams.width, testBottomRadius);
- assertEquals(bottomParams.height, testBottomRadius);
+ View rightRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_LEFT].getRootView()
+ .findViewById(R.id.right);
+ isTop = mScreenDecorations.isTopRoundedCorner(BOUNDS_POSITION_LEFT, R.id.right);
+ verify(mScreenDecorations, atLeastOnce())
+ .setSize(rightRoundedCorner, isTop ? topRadius : bottomRadius);
+
+ leftRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_RIGHT].getRootView()
+ .findViewById(R.id.left);
+ isTop = mScreenDecorations.isTopRoundedCorner(BOUNDS_POSITION_RIGHT, R.id.left);
+ verify(mScreenDecorations, atLeastOnce())
+ .setSize(leftRoundedCorner, isTop ? topRadius : bottomRadius);
+
+ rightRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_RIGHT].getRootView()
+ .findViewById(R.id.right);
+ isTop = mScreenDecorations.isTopRoundedCorner(BOUNDS_POSITION_RIGHT, R.id.right);
+ verify(mScreenDecorations, atLeastOnce())
+ .setSize(rightRoundedCorner, isTop ? topRadius : bottomRadius);
}
@Test
@@ -551,8 +525,8 @@
verifyOverlaysExistAndAdded(false, true, false, true);
// Rounded corner views shall exist
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_TOP, true);
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_BOTTOM, true);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.VISIBLE);
// Privacy dots shall not exist
verifyDotViewsNullable(true);
@@ -585,8 +559,8 @@
verifyOverlaysExistAndAdded(false, true, false, true);
// Rounded corner views shall exist
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_TOP, true);
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_BOTTOM, true);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.VISIBLE);
// Privacy dots shall exist but invisible
verifyDotViewsVisibility(View.INVISIBLE);
@@ -645,10 +619,10 @@
// Top rounded corner views shall exist because of cutout
// but be gone because of no rounded corner
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_TOP, false);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.GONE);
// Bottom rounded corner views shall exist because of privacy dot
// but be gone because of no rounded corner
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_BOTTOM, false);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.GONE);
// Privacy dots shall exist but invisible
verifyDotViewsVisibility(View.INVISIBLE);
@@ -676,7 +650,7 @@
// Left rounded corner views shall exist because of cutout
// but be gone because of no rounded corner
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_LEFT, false);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_LEFT, View.GONE);
// Top privacy dots shall not exist because of no privacy
verifyDotViewsNullable(true);
@@ -728,8 +702,8 @@
verifyOverlaysExistAndAdded(false, true, false, true);
// Rounded corner views shall exist
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_TOP, true);
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_BOTTOM, true);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.VISIBLE);
// Top privacy dots shall not exist because of no privacy dot
verifyDotViewsNullable(true);
@@ -756,8 +730,8 @@
verifyOverlaysExistAndAdded(false, true, false, true);
// Rounded corner views shall exist
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_TOP, true);
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_BOTTOM, true);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.VISIBLE);
// Top privacy dots shall exist but invisible
verifyDotViewsVisibility(View.INVISIBLE);
@@ -887,7 +861,7 @@
verifyOverlaysExistAndAdded(true, false, true, false);
// Verify each privacy dot id appears only once
- mPrivacyDecorProviders.stream().map(DecorProvider::getViewId).forEach(viewId -> {
+ mDecorProviders.stream().map(DecorProvider::getViewId).forEach(viewId -> {
int findCount = 0;
for (OverlayWindow overlay: mScreenDecorations.mOverlays) {
if (overlay == null) {
@@ -941,8 +915,8 @@
// Both top and bottom windows should be added because of privacy dot,
// but their visibility shall be gone because of no rounding.
verifyOverlaysExistAndAdded(false, true, false, true);
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_TOP, false);
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_BOTTOM, false);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.GONE);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.GONE);
when(mContext.getResources().getBoolean(
com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout))
@@ -953,8 +927,8 @@
// Both top and bottom windows should be added because of privacy dot,
// but their visibility shall be gone because of no rounding.
verifyOverlaysExistAndAdded(false, true, false, true);
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_TOP, false);
- verifyRoundedCornerViewsExist(BOUNDS_POSITION_BOTTOM, false);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.GONE);
+ verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.GONE);
}
@Test
@@ -1163,6 +1137,56 @@
}
+ @Test
+ public void testOnDisplayChanged_hwcLayer() {
+ setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
+ 0 /* roundedPadding */, false /* multipleRadius */,
+ true /* fillCutout */, false /* privacyDot */);
+ final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
+ decorationSupport.format = PixelFormat.R_8;
+ doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
+
+ // top cutout
+ final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+ doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+ .when(mScreenDecorations).getCutout();
+
+ mScreenDecorations.start();
+
+ final ScreenDecorHwcLayer hwcLayer = mScreenDecorations.mScreenDecorHwcLayer;
+ spyOn(hwcLayer);
+ doReturn(mDisplay).when(hwcLayer).getDisplay();
+ doReturn(mDisplayMode).when(mDisplay).getMode();
+
+ mScreenDecorations.mDisplayListener.onDisplayChanged(1);
+
+ verify(hwcLayer, times(1)).onDisplayChanged(1);
+ }
+
+ @Test
+ public void testOnDisplayChanged_nonHwcLayer() {
+ setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
+ 0 /* roundedPadding */, false /* multipleRadius */,
+ true /* fillCutout */, false /* privacyDot */);
+
+ // top cutout
+ final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
+ doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
+ .when(mScreenDecorations).getCutout();
+
+ mScreenDecorations.start();
+
+ final ScreenDecorations.DisplayCutoutView cutoutView =
+ mScreenDecorations.mCutoutViews[BOUNDS_POSITION_TOP];
+ spyOn(cutoutView);
+ doReturn(mDisplay).when(cutoutView).getDisplay();
+ doReturn(mDisplayMode).when(mDisplay).getMode();
+
+ mScreenDecorations.mDisplayListener.onDisplayChanged(1);
+
+ verify(cutoutView, times(1)).onDisplayChanged(1);
+ }
+
private void setupResources(int radius, int radiusTop, int radiusBottom, int roundedPadding,
boolean multipleRadius, boolean fillCutout, boolean privacyDot) {
mContext.getOrCreateTestableResources().addOverride(
@@ -1202,14 +1226,14 @@
mContext.getOrCreateTestableResources().addOverride(
com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, fillCutout);
- mPrivacyDecorProviders = new ArrayList<>();
+ mDecorProviders = new ArrayList<>();
if (privacyDot) {
- mPrivacyDecorProviders.add(mPrivacyDotTopLeftDecorProvider);
- mPrivacyDecorProviders.add(mPrivacyDotTopRightDecorProvider);
- mPrivacyDecorProviders.add(mPrivacyDotBottomLeftDecorProvider);
- mPrivacyDecorProviders.add(mPrivacyDotBottomRightDecorProvider);
+ mDecorProviders.add(mPrivacyDotTopLeftDecorProvider);
+ mDecorProviders.add(mPrivacyDotTopRightDecorProvider);
+ mDecorProviders.add(mPrivacyDotBottomLeftDecorProvider);
+ mDecorProviders.add(mPrivacyDotBottomRightDecorProvider);
}
- when(mPrivacyDotDecorProviderFactory.getProviders()).thenReturn(mPrivacyDecorProviders);
+ when(mPrivacyDotDecorProviderFactory.getProviders()).thenReturn(mDecorProviders);
when(mPrivacyDotDecorProviderFactory.getHasProviders()).thenReturn(privacyDot);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
index 9418b50..f99b20d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
@@ -42,6 +42,7 @@
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import org.junit.After;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@@ -50,7 +51,6 @@
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
-@Ignore
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@SmallTest
@@ -66,6 +66,11 @@
private AuthBiometricView mBiometricView;
+ @After
+ public void tearDown() {
+ destroyDialog();
+ }
+
@Test
public void testOnAuthenticationSucceeded_noConfirmationRequired_sendsActionAuthenticated() {
initDialog(false /* allowDeviceCredential */, mCallback);
@@ -245,6 +250,7 @@
// TODO: Test dialog size. Should move requireConfirmation to buildBiometricPromptBundle
// Create new dialog and restore the previous state into it
+ destroyDialog();
initDialog(false /* allowDeviceCredential */, mCallback, state, 10000);
mBiometricView.mAnimationDurationHideDialog = 10000;
mBiometricView.setRequireConfirmation(requireConfirmation);
@@ -304,6 +310,12 @@
waitForIdleSync();
}
+ private void destroyDialog() {
+ if (mBiometricView != null && mBiometricView.isAttachedToWindow()) {
+ ViewUtils.detachView(mBiometricView);
+ }
+ }
+
@Override
protected void waitForIdleSync() {
TestableLooper.get(this).processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 6f0a8a6..483dbf5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -41,7 +41,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.google.common.truth.Truth.assertThat
-import org.junit.Ignore
+import org.junit.After
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -52,7 +52,6 @@
import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever
-@Ignore
@RunWith(AndroidTestingRunner::class)
@RunWithLooper
@SmallTest
@@ -72,12 +71,19 @@
@Mock
lateinit var windowToken: IBinder
- private lateinit var authContainer: TestAuthContainerView
+ private var authContainer: TestAuthContainerView? = null
+
+ @After
+ fun tearDown() {
+ if (authContainer?.isAttachedToWindow == true) {
+ ViewUtils.detachView(authContainer)
+ }
+ }
@Test
fun testActionAuthenticated_sendsDismissedAuthenticated() {
- initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
- authContainer.mBiometricCallback.onAction(
+ val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ container.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_AUTHENTICATED
)
waitForIdleSync()
@@ -86,13 +92,13 @@
eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
eq<ByteArray?>(null) /* credentialAttestation */
)
- assertThat(authContainer.parent).isNull()
+ assertThat(container.parent).isNull()
}
@Test
fun testActionUserCanceled_sendsDismissedUserCanceled() {
- initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
- authContainer.mBiometricCallback.onAction(
+ val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ container.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_USER_CANCELED
)
waitForIdleSync()
@@ -104,13 +110,13 @@
eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
eq<ByteArray?>(null) /* credentialAttestation */
)
- assertThat(authContainer.parent).isNull()
+ assertThat(container.parent).isNull()
}
@Test
fun testActionButtonNegative_sendsDismissedButtonNegative() {
- initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
- authContainer.mBiometricCallback.onAction(
+ val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ container.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE
)
waitForIdleSync()
@@ -119,13 +125,13 @@
eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
eq<ByteArray?>(null) /* credentialAttestation */
)
- assertThat(authContainer.parent).isNull()
+ assertThat(container.parent).isNull()
}
@Test
fun testActionTryAgain_sendsTryAgain() {
- initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
- authContainer.mBiometricCallback.onAction(
+ val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ container.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN
)
waitForIdleSync()
@@ -135,8 +141,8 @@
@Test
fun testActionError_sendsDismissedError() {
- initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
- authContainer.mBiometricCallback.onAction(
+ val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ authContainer!!.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_ERROR
)
waitForIdleSync()
@@ -145,53 +151,53 @@
eq(AuthDialogCallback.DISMISSED_ERROR),
eq<ByteArray?>(null) /* credentialAttestation */
)
- assertThat(authContainer.parent).isNull()
+ assertThat(authContainer!!.parent).isNull()
}
@Test
fun testActionUseDeviceCredential_sendsOnDeviceCredentialPressed() {
- initializeContainer(
+ val container = initializeContainer(
BiometricManager.Authenticators.BIOMETRIC_WEAK or
- BiometricManager.Authenticators.DEVICE_CREDENTIAL
+ BiometricManager.Authenticators.DEVICE_CREDENTIAL
)
- authContainer.mBiometricCallback.onAction(
+ container.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL
)
waitForIdleSync()
verify(callback).onDeviceCredentialPressed()
- assertThat(authContainer.hasCredentialView()).isTrue()
+ assertThat(container.hasCredentialView()).isTrue()
}
@Test
fun testAnimateToCredentialUI_invokesStartTransitionToCredentialUI() {
- initializeContainer(
+ val container = initializeContainer(
BiometricManager.Authenticators.BIOMETRIC_WEAK or
- BiometricManager.Authenticators.DEVICE_CREDENTIAL
+ BiometricManager.Authenticators.DEVICE_CREDENTIAL
)
- authContainer.animateToCredentialUI()
+ container.animateToCredentialUI()
waitForIdleSync()
- assertThat(authContainer.hasCredentialView()).isTrue()
+ assertThat(container.hasCredentialView()).isTrue()
}
@Test
fun testShowBiometricUI() {
- initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+ val container = initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
waitForIdleSync()
- assertThat(authContainer.hasCredentialView()).isFalse()
- assertThat(authContainer.hasBiometricPrompt()).isTrue()
+ assertThat(container.hasCredentialView()).isFalse()
+ assertThat(container.hasBiometricPrompt()).isTrue()
}
@Test
fun testShowCredentialUI() {
- initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
+ val container = initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
waitForIdleSync()
- assertThat(authContainer.hasCredentialView()).isTrue()
- assertThat(authContainer.hasBiometricPrompt()).isFalse()
+ assertThat(container.hasCredentialView()).isTrue()
+ assertThat(container.hasBiometricPrompt()).isFalse()
}
@Test
@@ -201,11 +207,11 @@
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
)
- initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
+ val container = initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
waitForIdleSync()
- assertThat(authContainer.hasCredentialPatternView()).isTrue()
- assertThat(authContainer.hasBiometricPrompt()).isFalse()
+ assertThat(container.hasCredentialPatternView()).isTrue()
+ assertThat(container.hasBiometricPrompt()).isFalse()
}
@Test
@@ -218,20 +224,20 @@
// In the credential view, clicking on the background (to cancel authentication) is not
// valid. Thus, the listener should be null, and it should not be in the accessibility
// hierarchy.
- initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
+ val container = initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
waitForIdleSync()
- assertThat(authContainer.hasCredentialPasswordView()).isTrue()
- assertThat(authContainer.hasBiometricPrompt()).isFalse()
+ assertThat(container.hasCredentialPasswordView()).isTrue()
+ assertThat(container.hasBiometricPrompt()).isFalse()
assertThat(
- authContainer.findViewById<View>(R.id.background)?.isImportantForAccessibility
+ container.findViewById<View>(R.id.background)?.isImportantForAccessibility
).isFalse()
- authContainer.findViewById<View>(R.id.background)?.performClick()
+ container.findViewById<View>(R.id.background)?.performClick()
waitForIdleSync()
- assertThat(authContainer.hasCredentialPasswordView()).isTrue()
- assertThat(authContainer.hasBiometricPrompt()).isFalse()
+ assertThat(container.hasCredentialPasswordView()).isTrue()
+ assertThat(container.hasBiometricPrompt()).isFalse()
}
@Test
@@ -246,7 +252,7 @@
assertThat((layoutParams.fitInsetsTypes and WindowInsets.Type.ime()) == 0).isTrue()
}
- private fun initializeContainer(authenticators: Int) {
+ private fun initializeContainer(authenticators: Int): TestAuthContainerView {
val config = AuthContainerView.Config()
config.mContext = mContext
config.mCallback = callback
@@ -286,6 +292,7 @@
Handler(TestableLooper.get(this).looper)
)
ViewUtils.attachView(authContainer)
+ return authContainer!!
}
private inner class TestAuthContainerView(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index cfac9651..42c3c7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -82,7 +82,6 @@
import com.android.systemui.util.concurrency.FakeExecution;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -100,7 +99,6 @@
import javax.inject.Provider;
-@Ignore
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
index 49eaf823..bbae5dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
@@ -16,6 +16,8 @@
package com.android.systemui.controls.ui
+import android.content.Context
+import android.content.SharedPreferences
import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
@@ -26,13 +28,14 @@
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.controls.ControlsMetricsLogger
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.settings.UserContextProvider
import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.settings.SecureSettings
import com.android.wm.shell.TaskViewFactory
-import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -42,6 +45,7 @@
import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.spy
@@ -74,6 +78,8 @@
private lateinit var secureSettings: SecureSettings
@Mock
private lateinit var mainHandler: Handler
+ @Mock
+ private lateinit var userContextProvider: UserContextProvider
companion object {
fun <T> any(): T = Mockito.any<T>()
@@ -91,6 +97,8 @@
`when`(secureSettings.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS))
.thenReturn(Settings.Secure
.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS))
+ `when`(secureSettings.getInt(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0))
+ .thenReturn(1)
coordinator = spy(ControlActionCoordinatorImpl(
mContext,
@@ -103,15 +111,27 @@
metricsLogger,
vibratorHelper,
secureSettings,
- mainHandler))
+ userContextProvider,
+ mainHandler
+ ))
+
+ val userContext = mock(Context::class.java)
+ val pref = mock(SharedPreferences::class.java)
+ `when`(userContextProvider.userContext).thenReturn(userContext)
+ `when`(userContext.getSharedPreferences(
+ DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, Context.MODE_PRIVATE))
+ .thenReturn(pref)
+ // Just return 2 so we don't test any Dialog logic which requires a launched activity.
+ `when`(pref.getInt(DeviceControlsControllerImpl.PREFS_SETTINGS_DIALOG_ATTEMPTS, 0))
+ .thenReturn(2)
verify(secureSettings).registerContentObserver(any(Uri::class.java),
anyBoolean(), any(ContentObserver::class.java))
`when`(cvh.cws.ci.controlId).thenReturn(ID)
`when`(cvh.cws.control?.isAuthRequired()).thenReturn(true)
- action = spy(coordinator.Action(ID, {}, false))
- doReturn(action).`when`(coordinator).createAction(any(), any(), anyBoolean())
+ action = spy(coordinator.Action(ID, {}, false, true))
+ doReturn(action).`when`(coordinator).createAction(any(), any(), anyBoolean(), anyBoolean())
}
@Test
@@ -119,7 +139,7 @@
`when`(keyguardStateController.isShowing()).thenReturn(false)
coordinator.toggle(cvh, "", true)
- verify(coordinator).bouncerOrRun(action, true /*authRequired */)
+ verify(coordinator).bouncerOrRun(action)
verify(action).invoke()
}
@@ -129,7 +149,7 @@
`when`(keyguardStateController.isUnlocked()).thenReturn(false)
coordinator.toggle(cvh, "", true)
- verify(coordinator).bouncerOrRun(action, true /*authRequired */)
+ verify(coordinator).bouncerOrRun(action)
verify(activityStarter).dismissKeyguardThenExecute(any(), any(), anyBoolean())
verify(action, never()).invoke()
@@ -146,25 +166,41 @@
@Test
fun testToggleRunsWhenLockedAndAuthNotRequired() {
+ action = spy(coordinator.Action(ID, {}, false, false))
+ doReturn(action).`when`(coordinator).createAction(any(), any(), anyBoolean(), anyBoolean())
+
`when`(keyguardStateController.isShowing()).thenReturn(true)
`when`(keyguardStateController.isUnlocked()).thenReturn(false)
- doReturn(false).`when`(coordinator).isAuthRequired(
- any(), anyBoolean())
coordinator.toggle(cvh, "", true)
- verify(coordinator).bouncerOrRun(action, false /* authRequired */)
+ verify(coordinator).bouncerOrRun(action)
verify(action).invoke()
}
@Test
- fun testIsAuthRequired() {
- `when`(cvh.cws.control?.isAuthRequired).thenReturn(true)
- assertThat(coordinator.isAuthRequired(cvh, false)).isTrue()
+ fun testToggleDoesNotRunsWhenLockedAndAuthRequired() {
+ action = spy(coordinator.Action(ID, {}, false, true))
+ doReturn(action).`when`(coordinator).createAction(any(), any(), anyBoolean(), anyBoolean())
- `when`(cvh.cws.control?.isAuthRequired).thenReturn(false)
- assertThat(coordinator.isAuthRequired(cvh, false)).isTrue()
+ `when`(keyguardStateController.isShowing()).thenReturn(true)
+ `when`(keyguardStateController.isUnlocked()).thenReturn(false)
- assertThat(coordinator.isAuthRequired(cvh, true)).isFalse()
+ coordinator.toggle(cvh, "", true)
+
+ verify(coordinator).bouncerOrRun(action)
+ verify(action, never()).invoke()
+ }
+
+ @Test
+ fun testNullControl() {
+ `when`(cvh.cws.control).thenReturn(null)
+
+ `when`(keyguardStateController.isShowing()).thenReturn(true)
+
+ coordinator.toggle(cvh, "", true)
+
+ verify(coordinator).bouncerOrRun(action)
+ verify(action, never()).invoke()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
index 5182210..ca74df0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
@@ -19,19 +19,25 @@
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.DisplayCutout
+import android.view.LayoutInflater
import android.view.Surface
import android.view.View
+import android.view.ViewGroup
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.eq
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.never
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.anyInt
import org.mockito.Mockito.spy
-import org.mockito.Mockito.times
import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
@RunWith(AndroidTestingRunner::class)
@RunWithLooper(setAsMainLooper = true)
@@ -39,88 +45,62 @@
class OverlayWindowTest : SysuiTestCase() {
companion object {
- private val TEST_DECOR_VIEW_ID_1 = R.id.privacy_dot_top_left_container
- private val TEST_DECOR_VIEW_ID_2 = R.id.privacy_dot_bottom_right_container
+ private val TEST_DECOR_VIEW_ID = R.id.privacy_dot_bottom_right_container
+ private val TEST_DECOR_LAYOUT_ID = R.layout.privacy_dot_bottom_right
}
private lateinit var overlay: OverlayWindow
- private lateinit var decorProvider1: DecorProvider
- private lateinit var decorProvider2: DecorProvider
+
+ @Mock private lateinit var layoutInflater: LayoutInflater
+ @Mock private lateinit var decorProvider: DecorProvider
@Before
fun setUp() {
- decorProvider1 = spy(PrivacyDotCornerDecorProviderImpl(
- viewId = TEST_DECOR_VIEW_ID_1,
- alignedBound1 = DisplayCutout.BOUNDS_POSITION_TOP,
- alignedBound2 = DisplayCutout.BOUNDS_POSITION_LEFT,
- layoutId = R.layout.privacy_dot_top_left))
- decorProvider2 = spy(PrivacyDotCornerDecorProviderImpl(
- viewId = TEST_DECOR_VIEW_ID_2,
- alignedBound1 = DisplayCutout.BOUNDS_POSITION_BOTTOM,
- alignedBound2 = DisplayCutout.BOUNDS_POSITION_RIGHT,
- layoutId = R.layout.privacy_dot_bottom_right))
+ MockitoAnnotations.initMocks(this)
- overlay = OverlayWindow(mContext)
+ layoutInflater = spy(LayoutInflater.from(mContext))
+
+ overlay = OverlayWindow(layoutInflater, DisplayCutout.BOUNDS_POSITION_RIGHT)
+
+ whenever(decorProvider.viewId).thenReturn(TEST_DECOR_VIEW_ID)
+ whenever(decorProvider.inflateView(
+ eq(layoutInflater),
+ eq(overlay.rootView),
+ anyInt())
+ ).then {
+ val layoutInflater = it.getArgument<LayoutInflater>(0)
+ val parent = it.getArgument<ViewGroup>(1)
+ layoutInflater.inflate(TEST_DECOR_LAYOUT_ID, parent)
+ return@then parent.getChildAt(parent.childCount - 1)
+ }
+ }
+
+ @Test
+ fun testAnyBoundsPositionShallNoExceptionForConstructor() {
+ OverlayWindow(layoutInflater, DisplayCutout.BOUNDS_POSITION_LEFT)
+ OverlayWindow(layoutInflater, DisplayCutout.BOUNDS_POSITION_TOP)
+ OverlayWindow(layoutInflater, DisplayCutout.BOUNDS_POSITION_RIGHT)
+ OverlayWindow(layoutInflater, DisplayCutout.BOUNDS_POSITION_BOTTOM)
}
@Test
fun testAddProvider() {
@Surface.Rotation val rotation = Surface.ROTATION_270
- overlay.addDecorProvider(decorProvider1, rotation)
- overlay.addDecorProvider(decorProvider2, rotation)
-
- verify(decorProvider1, times(1)).inflateView(
- mContext, overlay.rootView, rotation)
- verify(decorProvider2, times(1)).inflateView(
- mContext, overlay.rootView, rotation)
-
- val view1FoundFromRootView = overlay.rootView.findViewById<View>(TEST_DECOR_VIEW_ID_1)
- Assert.assertNotNull(view1FoundFromRootView)
- Assert.assertEquals(view1FoundFromRootView, overlay.getView(TEST_DECOR_VIEW_ID_1))
- val view2FoundFromRootView = overlay.rootView.findViewById<View>(TEST_DECOR_VIEW_ID_2)
- Assert.assertNotNull(view2FoundFromRootView)
- Assert.assertEquals(view2FoundFromRootView, overlay.getView(TEST_DECOR_VIEW_ID_2))
+ overlay.addDecorProvider(decorProvider, rotation)
+ verify(decorProvider, Mockito.times(1)).inflateView(
+ eq(layoutInflater), eq(overlay.rootView), eq(rotation))
+ val viewFoundFromRootView = overlay.rootView.findViewById<View>(TEST_DECOR_VIEW_ID)
+ Assert.assertNotNull(viewFoundFromRootView)
+ Assert.assertEquals(viewFoundFromRootView, overlay.getView(TEST_DECOR_VIEW_ID))
}
@Test
fun testRemoveView() {
- overlay.addDecorProvider(decorProvider1, Surface.ROTATION_270)
- overlay.addDecorProvider(decorProvider2, Surface.ROTATION_270)
- overlay.removeView(TEST_DECOR_VIEW_ID_1)
-
- val viewFoundFromRootView = overlay.rootView.findViewById<View>(TEST_DECOR_VIEW_ID_1)
+ @Surface.Rotation val rotation = Surface.ROTATION_270
+ overlay.addDecorProvider(decorProvider, rotation)
+ overlay.removeView(TEST_DECOR_VIEW_ID)
+ val viewFoundFromRootView = overlay.rootView.findViewById<View>(TEST_DECOR_VIEW_ID)
Assert.assertNull(viewFoundFromRootView)
- Assert.assertNull(overlay.getView(TEST_DECOR_VIEW_ID_1))
- }
-
- @Test
- fun testOnReloadResAndMeasureWithoutIds() {
- overlay.addDecorProvider(decorProvider1, Surface.ROTATION_0)
- overlay.addDecorProvider(decorProvider2, Surface.ROTATION_0)
-
- overlay.onReloadResAndMeasure(
- reloadToken = 1,
- rotation = Surface.ROTATION_90,
- displayUniqueId = null)
- verify(decorProvider1, times(1)).onReloadResAndMeasure(
- overlay.getView(TEST_DECOR_VIEW_ID_1)!!, 1, Surface.ROTATION_90, null)
- verify(decorProvider2, times(1)).onReloadResAndMeasure(
- overlay.getView(TEST_DECOR_VIEW_ID_2)!!, 1, Surface.ROTATION_90, null)
- }
-
- @Test
- fun testOnReloadResAndMeasureWithIds() {
- overlay.addDecorProvider(decorProvider1, Surface.ROTATION_0)
- overlay.addDecorProvider(decorProvider2, Surface.ROTATION_0)
-
- overlay.onReloadResAndMeasure(
- filterIds = arrayOf(TEST_DECOR_VIEW_ID_2),
- reloadToken = 1,
- rotation = Surface.ROTATION_90,
- displayUniqueId = null)
- verify(decorProvider1, never()).onReloadResAndMeasure(
- overlay.getView(TEST_DECOR_VIEW_ID_1)!!, 1, Surface.ROTATION_90, null)
- verify(decorProvider2, times(1)).onReloadResAndMeasure(
- overlay.getView(TEST_DECOR_VIEW_ID_2)!!, 1, Surface.ROTATION_90, null)
+ Assert.assertNull(overlay.getView(TEST_DECOR_LAYOUT_ID))
}
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
index 171b767..bac0817 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
@@ -18,6 +18,7 @@
import android.content.res.Resources
import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
import android.view.DisplayCutout
import androidx.test.filters.SmallTest
import com.android.systemui.R
@@ -31,6 +32,7 @@
import org.mockito.Mockito.`when` as whenever
@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
@SmallTest
class PrivacyDotDecorProviderFactoryTest : SysuiTestCase() {
private lateinit var mPrivacyDotDecorProviderFactory: PrivacyDotDecorProviderFactory
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
deleted file mode 100644
index 621bcf6..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.decor
-
-import android.testing.AndroidTestingRunner
-import android.util.Size
-import android.view.DisplayCutout
-import androidx.test.filters.SmallTest
-import com.android.systemui.R
-import com.android.systemui.SysuiTestCase
-import org.junit.Assert
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito
-import org.mockito.Mockito.spy
-
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-class RoundedCornerDecorProviderFactoryTest : SysuiTestCase() {
-
- @Mock private lateinit var roundedCornerResDelegate: RoundedCornerResDelegate
- private lateinit var roundedCornerDecorProviderFactory: RoundedCornerDecorProviderFactory
-
- @Before
- fun setUp() {
- roundedCornerResDelegate = spy(RoundedCornerResDelegate(mContext.resources, null))
- }
-
- @Test
- fun testNoRoundedCorners() {
- Mockito.doReturn(Size(0, 0)).`when`(roundedCornerResDelegate).topRoundedSize
- Mockito.doReturn(Size(0, 0)).`when`(roundedCornerResDelegate).bottomRoundedSize
- Mockito.doReturn(false).`when`(roundedCornerResDelegate).isMultipleRadius
-
- roundedCornerDecorProviderFactory =
- RoundedCornerDecorProviderFactory(roundedCornerResDelegate)
-
- Assert.assertEquals(false, roundedCornerDecorProviderFactory.hasProviders)
- Assert.assertEquals(0, roundedCornerDecorProviderFactory.providers.size)
- }
-
- @Test
- fun testHasRoundedCornersIfTopWidthLargerThan0() {
- Mockito.doReturn(Size(1, 0)).`when`(roundedCornerResDelegate).topRoundedSize
- Mockito.doReturn(Size(0, 0)).`when`(roundedCornerResDelegate).bottomRoundedSize
- Mockito.doReturn(false).`when`(roundedCornerResDelegate).isMultipleRadius
-
- roundedCornerDecorProviderFactory =
- RoundedCornerDecorProviderFactory(roundedCornerResDelegate)
-
- Assert.assertEquals(true, roundedCornerDecorProviderFactory.hasProviders)
- roundedCornerDecorProviderFactory.providers.let { providers ->
- Assert.assertEquals(2, providers.size)
- Assert.assertEquals(1, providers.count {
- ((it.viewId == R.id.rounded_corner_top_left)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_TOP)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_LEFT))
- })
- Assert.assertEquals(1, providers.count {
- ((it.viewId == R.id.rounded_corner_top_right)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_TOP)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_RIGHT))
- })
- }
- }
-
- @Test
- fun testHasRoundedCornersIfBottomWidthLargerThan0() {
- Mockito.doReturn(Size(0, 0)).`when`(roundedCornerResDelegate).topRoundedSize
- Mockito.doReturn(Size(1, 1)).`when`(roundedCornerResDelegate).bottomRoundedSize
- Mockito.doReturn(false).`when`(roundedCornerResDelegate).isMultipleRadius
-
- roundedCornerDecorProviderFactory =
- RoundedCornerDecorProviderFactory(roundedCornerResDelegate)
-
- Assert.assertEquals(true, roundedCornerDecorProviderFactory.hasProviders)
- roundedCornerDecorProviderFactory.providers.let { providers ->
- Assert.assertEquals(2, providers.size)
- Assert.assertEquals(1, providers.count {
- ((it.viewId == R.id.rounded_corner_bottom_left)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_BOTTOM)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_LEFT))
- })
- Assert.assertEquals(1, providers.count {
- ((it.viewId == R.id.rounded_corner_bottom_right)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_BOTTOM)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_RIGHT))
- })
- }
- }
-
- @Test
- fun test4CornerDecorProvidersInfo() {
- Mockito.doReturn(Size(10, 10)).`when`(roundedCornerResDelegate).topRoundedSize
- Mockito.doReturn(Size(10, 10)).`when`(roundedCornerResDelegate).bottomRoundedSize
- Mockito.doReturn(true).`when`(roundedCornerResDelegate).isMultipleRadius
-
- roundedCornerDecorProviderFactory =
- RoundedCornerDecorProviderFactory(roundedCornerResDelegate)
-
- Assert.assertEquals(true, roundedCornerDecorProviderFactory.hasProviders)
- roundedCornerDecorProviderFactory.providers.let { providers ->
- Assert.assertEquals(4, providers.size)
- Assert.assertEquals(1, providers.count {
- ((it.viewId == R.id.rounded_corner_top_left)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_TOP)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_LEFT))
- })
- Assert.assertEquals(1, providers.count {
- ((it.viewId == R.id.rounded_corner_top_right)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_TOP)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_RIGHT))
- })
- Assert.assertEquals(1, providers.count {
- ((it.viewId == R.id.rounded_corner_bottom_left)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_BOTTOM)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_LEFT))
- })
- Assert.assertEquals(1, providers.count {
- ((it.viewId == R.id.rounded_corner_bottom_right)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_BOTTOM)
- and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_RIGHT))
- })
- }
- }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
index e89ed30..b536bfd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
@@ -45,7 +45,7 @@
}
@Test
- fun testUpdateDisplayUniqueId() {
+ fun testReloadAllAndDefaultRadius() {
mContext.orCreateTestableResources.addOverrides(
mockTypeArray = mockTypedArray,
radius = 3,
@@ -65,34 +65,7 @@
radiusTop = 6,
radiusBottom = 0)
- roundedCornerResDelegate.updateDisplayUniqueId("test", null)
-
- assertEquals(Size(6, 6), roundedCornerResDelegate.topRoundedSize)
- assertEquals(Size(5, 5), roundedCornerResDelegate.bottomRoundedSize)
- }
-
- @Test
- fun testNotUpdateDisplayUniqueIdButChangeRefreshToken() {
- mContext.orCreateTestableResources.addOverrides(
- mockTypeArray = mockTypedArray,
- radius = 3,
- radiusTop = 0,
- radiusBottom = 4,
- multipleRadius = false)
-
- roundedCornerResDelegate = RoundedCornerResDelegate(mContext.resources, null)
-
- assertEquals(Size(3, 3), roundedCornerResDelegate.topRoundedSize)
- assertEquals(Size(4, 4), roundedCornerResDelegate.bottomRoundedSize)
- assertEquals(false, roundedCornerResDelegate.isMultipleRadius)
-
- mContext.orCreateTestableResources.addOverrides(
- mockTypeArray = mockTypedArray,
- radius = 5,
- radiusTop = 6,
- radiusBottom = 0)
-
- roundedCornerResDelegate.updateDisplayUniqueId(null, 1)
+ roundedCornerResDelegate.reloadAll("test")
assertEquals(Size(6, 6), roundedCornerResDelegate.topRoundedSize)
assertEquals(Size(5, 5), roundedCornerResDelegate.bottomRoundedSize)
@@ -102,24 +75,18 @@
fun testUpdateTuningSizeFactor() {
mContext.orCreateTestableResources.addOverrides(
mockTypeArray = mockTypedArray,
- radius = 1,
radiusTop = 0,
- radiusBottom = 2,
+ radiusBottom = 0,
multipleRadius = false)
roundedCornerResDelegate = RoundedCornerResDelegate(mContext.resources, null)
val factor = 5
- roundedCornerResDelegate.updateTuningSizeFactor(factor, 1)
+ roundedCornerResDelegate.updateTuningSizeFactor(factor)
val length = (factor * mContext.resources.displayMetrics.density).toInt()
assertEquals(Size(length, length), roundedCornerResDelegate.topRoundedSize)
assertEquals(Size(length, length), roundedCornerResDelegate.bottomRoundedSize)
-
- roundedCornerResDelegate.updateTuningSizeFactor(null, 2)
-
- assertEquals(Size(1, 1), roundedCornerResDelegate.topRoundedSize)
- assertEquals(Size(2, 2), roundedCornerResDelegate.bottomRoundedSize)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
index fa6288f..76f6529 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -33,6 +33,7 @@
import androidx.test.filters.SmallTest;
+import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dreams.complication.ComplicationHostViewController;
import com.android.systemui.statusbar.BlurUtils;
@@ -173,10 +174,14 @@
when(mBlurUtils.blurRadiusOfRatio(anyFloat())).thenReturn(blurRadius);
bouncerExpansionCaptor.getValue().onStartingToShow();
- final float bouncerHideAmount = 0.1f;
+
+ final float bouncerHideAmount = 0.05f;
+ final float scaledFraction =
+ BouncerPanelExpansionCalculator.getBackScrimScaledExpansion(bouncerHideAmount);
+
bouncerExpansionCaptor.getValue().onExpansionChanged(bouncerHideAmount);
- verify(mBlurUtils).blurRadiusOfRatio(1 - bouncerHideAmount);
+ verify(mBlurUtils).blurRadiusOfRatio(1 - scaledFraction);
verify(mBlurUtils).applyBlur(mViewRoot, (int) blurRadius, false);
- verify(mDreamOverlayContainerView).setAlpha(bouncerHideAmount);
+ verify(mDreamOverlayContainerView).setAlpha(scaledFraction);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
new file mode 100644
index 0000000..c861221
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class DreamOverlayNotificationCountProviderTest extends SysuiTestCase {
+ @Mock
+ NotificationListener mNotificationListener;
+ @Mock
+ DreamOverlayNotificationCountProvider.Callback mCallback;
+ @Mock
+ StatusBarNotification mNotification1;
+ @Mock
+ StatusBarNotification mNotification2;
+ @Mock
+ NotificationListenerService.RankingMap mRankingMap;
+
+ private DreamOverlayNotificationCountProvider mProvider;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+
+ when(mNotification1.getKey()).thenReturn("key1");
+ when(mNotification2.getKey()).thenReturn("key2");
+
+ final StatusBarNotification[] notifications = {mNotification1};
+ when(mNotificationListener.getActiveNotifications()).thenReturn(notifications);
+ mProvider = new DreamOverlayNotificationCountProvider(mNotificationListener);
+ mProvider.addCallback(mCallback);
+ }
+
+ @Test
+ public void testPostingNotificationCallsCallbackWithNotificationCount() {
+ final ArgumentCaptor<NotificationHandler> handlerArgumentCaptor =
+ ArgumentCaptor.forClass(NotificationHandler.class);
+ verify(mNotificationListener).addNotificationHandler(handlerArgumentCaptor.capture());
+ handlerArgumentCaptor.getValue().onNotificationPosted(mNotification2, mRankingMap);
+ verify(mCallback).onNotificationCountChanged(2);
+ }
+
+ @Test
+ public void testRemovingNotificationCallsCallbackWithZeroNotificationCount() {
+ final ArgumentCaptor<NotificationHandler> handlerArgumentCaptor =
+ ArgumentCaptor.forClass(NotificationHandler.class);
+ verify(mNotificationListener).addNotificationHandler(handlerArgumentCaptor.capture());
+ handlerArgumentCaptor.getValue().onNotificationRemoved(mNotification1, mRankingMap);
+ verify(mCallback).onNotificationCountChanged(0);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
index a6921b4..4915ded 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
@@ -31,15 +31,12 @@
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.provider.Settings;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -84,13 +81,9 @@
@Mock
IndividualSensorPrivacyController mSensorPrivacyController;
@Mock
- StatusBarNotification mStatusBarNotification;
- @Mock
- NotificationListenerService.RankingMap mRankingMap;
- @Mock
- NotificationListener mNotificationListener;
- @Mock
ZenModeController mZenModeController;
+ @Mock
+ DreamOverlayNotificationCountProvider mDreamOverlayNotificationCountProvider;
private final Executor mMainExecutor = Runnable::run;
@@ -113,7 +106,7 @@
mNextAlarmController,
mDateFormatUtil,
mSensorPrivacyController,
- mNotificationListener,
+ mDreamOverlayNotificationCountProvider,
mZenModeController);
}
@@ -123,6 +116,7 @@
verify(mNextAlarmController).addCallback(any());
verify(mSensorPrivacyController).addCallback(any());
verify(mZenModeController).addCallback(any());
+ verify(mDreamOverlayNotificationCountProvider).addCallback(any());
}
@Test
@@ -202,17 +196,26 @@
@Test
public void testOnViewAttachedShowsNotificationsIconWhenNotificationsExist() {
- StatusBarNotification[] notifications = { mStatusBarNotification };
- when(mNotificationListener.getActiveNotifications()).thenReturn(notifications);
mController.onViewAttached();
+
+ final ArgumentCaptor<DreamOverlayNotificationCountProvider.Callback> callbackCapture =
+ ArgumentCaptor.forClass(DreamOverlayNotificationCountProvider.Callback.class);
+ verify(mDreamOverlayNotificationCountProvider).addCallback(callbackCapture.capture());
+ callbackCapture.getValue().onNotificationCountChanged(1);
+
verify(mView).showIcon(
eq(DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS), eq(true), any());
}
@Test
public void testOnViewAttachedHidesNotificationsIconWhenNoNotificationsExist() {
- when(mNotificationListener.getActiveNotifications()).thenReturn(null);
mController.onViewAttached();
+
+ final ArgumentCaptor<DreamOverlayNotificationCountProvider.Callback> callbackCapture =
+ ArgumentCaptor.forClass(DreamOverlayNotificationCountProvider.Callback.class);
+ verify(mDreamOverlayNotificationCountProvider).addCallback(callbackCapture.capture());
+ callbackCapture.getValue().onNotificationCountChanged(0);
+
verify(mView).showIcon(
eq(DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS), eq(false), isNull());
}
@@ -248,6 +251,7 @@
verify(mNextAlarmController).removeCallback(any());
verify(mSensorPrivacyController).removeCallback(any());
verify(mZenModeController).removeCallback(any());
+ verify(mDreamOverlayNotificationCountProvider).removeCallback(any());
}
@Test
@@ -309,13 +313,10 @@
public void testNotificationsIconShownWhenNotificationAdded() {
mController.onViewAttached();
- StatusBarNotification[] notifications = { mStatusBarNotification };
- when(mNotificationListener.getActiveNotifications()).thenReturn(notifications);
-
- final ArgumentCaptor<NotificationListener.NotificationHandler> callbackCapture =
- ArgumentCaptor.forClass(NotificationListener.NotificationHandler.class);
- verify(mNotificationListener).addNotificationHandler(callbackCapture.capture());
- callbackCapture.getValue().onNotificationPosted(mStatusBarNotification, mRankingMap);
+ final ArgumentCaptor<DreamOverlayNotificationCountProvider.Callback> callbackCapture =
+ ArgumentCaptor.forClass(DreamOverlayNotificationCountProvider.Callback.class);
+ verify(mDreamOverlayNotificationCountProvider).addCallback(callbackCapture.capture());
+ callbackCapture.getValue().onNotificationCountChanged(1);
verify(mView).showIcon(
eq(DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS), eq(true), any());
@@ -323,15 +324,12 @@
@Test
public void testNotificationsIconHiddenWhenLastNotificationRemoved() {
- StatusBarNotification[] notifications = { mStatusBarNotification };
- when(mNotificationListener.getActiveNotifications()).thenReturn(notifications)
- .thenReturn(null);
mController.onViewAttached();
- final ArgumentCaptor<NotificationListener.NotificationHandler> callbackCapture =
- ArgumentCaptor.forClass(NotificationListener.NotificationHandler.class);
- verify(mNotificationListener).addNotificationHandler(callbackCapture.capture());
- callbackCapture.getValue().onNotificationPosted(mStatusBarNotification, mRankingMap);
+ final ArgumentCaptor<DreamOverlayNotificationCountProvider.Callback> callbackCapture =
+ ArgumentCaptor.forClass(DreamOverlayNotificationCountProvider.Callback.class);
+ verify(mDreamOverlayNotificationCountProvider).addCallback(callbackCapture.capture());
+ callbackCapture.getValue().onNotificationCountChanged(0);
verify(mView).showIcon(
eq(DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS), eq(false), any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java
index d1d9ec3..35bcfcd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -414,4 +415,37 @@
assertThat(lp.endToEnd == ConstraintLayout.LayoutParams.PARENT_ID).isTrue();
});
}
+
+ /**
+ * Ensures a second removal of a complication is a no-op.
+ */
+ @Test
+ public void testDoubleRemoval() {
+ final ComplicationLayoutEngine engine =
+ new ComplicationLayoutEngine(mLayout, 0, mTouchSession, 0, 0);
+
+ final ViewInfo firstViewInfo = new ViewInfo(
+ new ComplicationLayoutParams(
+ 100,
+ 100,
+ ComplicationLayoutParams.POSITION_TOP
+ | ComplicationLayoutParams.POSITION_END,
+ ComplicationLayoutParams.DIRECTION_DOWN,
+ 0),
+ Complication.CATEGORY_STANDARD,
+ mLayout);
+
+ engine.addComplication(firstViewInfo.id, firstViewInfo.view, firstViewInfo.lp,
+ firstViewInfo.category);
+ verify(mLayout).addView(firstViewInfo.view);
+
+ assertThat(engine.removeComplication(firstViewInfo.id)).isTrue();
+ verify(firstViewInfo.view).getParent();
+ verify(mLayout).removeView(firstViewInfo.view);
+
+ Mockito.clearInvocations(mLayout, firstViewInfo.view);
+ assertThat(engine.removeComplication(firstViewInfo.id)).isFalse();
+ verify(firstViewInfo.view, never()).getParent();
+ verify(mLayout, never()).removeView(firstViewInfo.view);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index b08dd57..629c531 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
@@ -22,6 +22,8 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -37,6 +39,7 @@
import androidx.test.filters.SmallTest;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -89,6 +92,9 @@
@Mock
VelocityTracker mVelocityTracker;
+ @Mock
+ UiEventLogger mUiEventLogger;
+
final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
private static final float TOUCH_REGION = .3f;
@@ -110,11 +116,11 @@
mVelocityTrackerFactory,
mFlingAnimationUtils,
mFlingAnimationUtilsClosing,
- TOUCH_REGION);
+ TOUCH_REGION,
+ mUiEventLogger);
when(mCentralSurfaces.isBouncerShowing()).thenReturn(false);
when(mCentralSurfaces.getDisplayHeight()).thenReturn((float) SCREEN_HEIGHT_PX);
- when(mCentralSurfaces.isBouncerShowing()).thenReturn(false);
when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator);
when(mVelocityTrackerFactory.obtain()).thenReturn(mVelocityTracker);
when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn(Float.MAX_VALUE);
@@ -154,18 +160,22 @@
2)).isTrue();
}
+ private enum Direction {
+ DOWN,
+ UP,
+ }
+
/**
- * Makes sure expansion amount is proportional to scroll.
+ * Makes sure the expansion amount is proportional to (1 - scroll).
*/
@Test
- public void testExpansionAmount_whenBouncerHidden_setsCorrectValue() {
+ public void testSwipeUp_setsCorrectExpansionAmount() {
mTouchHandler.onSessionStart(mTouchSession);
ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());
final OnGestureListener gestureListener = gestureListenerCaptor.getValue();
- when(mCentralSurfaces.isBouncerShowing()).thenReturn(false);
verifyScroll(.3f, Direction.UP, true, gestureListener);
// Ensure that subsequent gestures are treated as expanding even if the bouncer state
@@ -175,17 +185,18 @@
}
/**
- * Makes sure collapse amount is proportional to scroll.
+ * Makes sure the expansion amount is proportional to scroll.
*/
@Test
- public void testCollapseAmount() {
+ public void testSwipeDown_setsCorrectExpansionAmount() {
+ when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
+
mTouchHandler.onSessionStart(mTouchSession);
ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());
final OnGestureListener gestureListener = gestureListenerCaptor.getValue();
- when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
verifyScroll(.3f, Direction.DOWN, false, gestureListener);
// Ensure that subsequent gestures are treated as collapsing even if the bouncer state
@@ -194,11 +205,6 @@
verifyScroll(.7f, Direction.DOWN, false, gestureListener);
}
- private enum Direction {
- DOWN,
- UP,
- }
-
private void verifyScroll(float percent, Direction direction, boolean expanding,
android.view.GestureDetector.OnGestureListener gestureListener) {
@@ -209,48 +215,128 @@
final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
0, direction == Direction.UP ? SCREEN_HEIGHT_PX - distanceY : distanceY, 0);
+ reset(mStatusBarKeyguardViewManager);
assertThat(gestureListener.onScroll(event1, event2, 0, distanceY))
.isTrue();
- // Ensure correct expansion passed in.
- verify(mStatusBarKeyguardViewManager)
- .onPanelExpansionChanged(
- eq(expanding ? 1 - percent : percent), eq(false), eq(true));
- }
-
- /**
- * Makes sure expansion amount is proportional to scroll.
- */
- @Test
- public void testExpansionAmount_whenBouncerShown_setsCorrectValue() {
- when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
-
- mTouchHandler.onSessionStart(mTouchSession);
- ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
- ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
- verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());
-
- final float scrollAmount = .3f;
- final float distanceY = SCREEN_HEIGHT_PX * scrollAmount;
-
- final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
- 0, SCREEN_HEIGHT_PX, 0);
- final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
- 0, SCREEN_HEIGHT_PX - distanceY, 0);
-
- assertThat(gestureListenerCaptor.getValue().onScroll(event1, event2, 0, distanceY))
- .isTrue();
-
// Ensure only called once
verify(mStatusBarKeyguardViewManager)
.onPanelExpansionChanged(anyFloat(), anyBoolean(), anyBoolean());
// Ensure correct expansion passed in.
verify(mStatusBarKeyguardViewManager)
- .onPanelExpansionChanged(eq(scrollAmount), eq(false), eq(true));
+ .onPanelExpansionChanged(
+ eq(expanding ? 1 - percent : percent), eq(false), eq(true));
}
- private void swipeToPosition(float position, float velocityY) {
+ /**
+ * Tests that ending an upward swipe before the set threshold leads to bouncer collapsing down.
+ */
+ @Test
+ public void testSwipeUpPositionBelowThreshold_collapsesBouncer() {
+ final float swipeUpPercentage = .3f;
+ final float expansion = 1 - swipeUpPercentage;
+ // The upward velocity is ignored.
+ final float velocityY = -1;
+ swipeToPosition(swipeUpPercentage, Direction.UP, velocityY);
+
+ verify(mValueAnimatorCreator).create(eq(expansion), eq(KeyguardBouncer.EXPANSION_HIDDEN));
+ verify(mFlingAnimationUtilsClosing).apply(eq(mValueAnimator),
+ eq(SCREEN_HEIGHT_PX * expansion),
+ eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_HIDDEN),
+ eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
+ verify(mValueAnimator).start();
+ verify(mUiEventLogger, never()).log(any());
+ }
+
+ /**
+ * Tests that ending an upward swipe above the set threshold will continue the expansion.
+ */
+ @Test
+ public void testSwipeUpPositionAboveThreshold_expandsBouncer() {
+ final float swipeUpPercentage = .7f;
+ final float expansion = 1 - swipeUpPercentage;
+ // The downward velocity is ignored.
+ final float velocityY = 1;
+ swipeToPosition(swipeUpPercentage, Direction.UP, velocityY);
+
+ verify(mValueAnimatorCreator).create(eq(expansion), eq(KeyguardBouncer.EXPANSION_VISIBLE));
+ verify(mFlingAnimationUtils).apply(eq(mValueAnimator), eq(SCREEN_HEIGHT_PX * expansion),
+ eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_VISIBLE),
+ eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
+ verify(mValueAnimator).start();
+ verify(mUiEventLogger).log(BouncerSwipeTouchHandler.DreamEvent.DREAM_SWIPED);
+ }
+
+ /**
+ * Tests that ending a downward swipe above the set threshold will continue the expansion,
+ * but will not trigger logging of the DREAM_SWIPED event.
+ */
+ @Test
+ public void testSwipeDownPositionAboveThreshold_expandsBouncer_doesNotLog() {
+ when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
+
+ final float swipeDownPercentage = .3f;
+ // The downward velocity is ignored.
+ final float velocityY = 1;
+ swipeToPosition(swipeDownPercentage, Direction.DOWN, velocityY);
+
+ verify(mValueAnimatorCreator).create(eq(swipeDownPercentage),
+ eq(KeyguardBouncer.EXPANSION_VISIBLE));
+ verify(mFlingAnimationUtils).apply(eq(mValueAnimator),
+ eq(SCREEN_HEIGHT_PX * swipeDownPercentage),
+ eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_VISIBLE),
+ eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
+ verify(mValueAnimator).start();
+ verify(mUiEventLogger, never()).log(any());
+ }
+
+ /**
+ * Tests that swiping down with a speed above the set threshold leads to bouncer collapsing
+ * down.
+ */
+ @Test
+ public void testSwipeDownVelocityAboveMin_collapsesBouncer() {
+ when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
+ when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn((float) 0);
+
+ // The ending position above the set threshold is ignored.
+ final float swipeDownPercentage = .3f;
+ final float velocityY = 1;
+ swipeToPosition(swipeDownPercentage, Direction.DOWN, velocityY);
+
+ verify(mValueAnimatorCreator).create(eq(swipeDownPercentage),
+ eq(KeyguardBouncer.EXPANSION_HIDDEN));
+ verify(mFlingAnimationUtilsClosing).apply(eq(mValueAnimator),
+ eq(SCREEN_HEIGHT_PX * swipeDownPercentage),
+ eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_HIDDEN),
+ eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
+ verify(mValueAnimator).start();
+ verify(mUiEventLogger, never()).log(any());
+ }
+
+ /**
+ * Tests that swiping up with a speed above the set threshold will continue the expansion.
+ */
+ @Test
+ public void testSwipeUpVelocityAboveMin_expandsBouncer() {
+ when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn((float) 0);
+
+ // The ending position below the set threshold is ignored.
+ final float swipeUpPercentage = .3f;
+ final float expansion = 1 - swipeUpPercentage;
+ final float velocityY = -1;
+ swipeToPosition(swipeUpPercentage, Direction.UP, velocityY);
+
+ verify(mValueAnimatorCreator).create(eq(expansion), eq(KeyguardBouncer.EXPANSION_VISIBLE));
+ verify(mFlingAnimationUtils).apply(eq(mValueAnimator), eq(SCREEN_HEIGHT_PX * expansion),
+ eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_VISIBLE),
+ eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
+ verify(mValueAnimator).start();
+ verify(mUiEventLogger).log(BouncerSwipeTouchHandler.DreamEvent.DREAM_SWIPED);
+ }
+
+ private void swipeToPosition(float percent, Direction direction, float velocityY) {
mTouchHandler.onSessionStart(mTouchSession);
ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
@@ -261,12 +347,12 @@
when(mVelocityTracker.getYVelocity()).thenReturn(velocityY);
- final float distanceY = SCREEN_HEIGHT_PX * position;
+ final float distanceY = SCREEN_HEIGHT_PX * percent;
final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
- 0, SCREEN_HEIGHT_PX, 0);
+ 0, direction == Direction.UP ? SCREEN_HEIGHT_PX : 0, 0);
final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
- 0, SCREEN_HEIGHT_PX - distanceY, 0);
+ 0, direction == Direction.UP ? SCREEN_HEIGHT_PX - distanceY : distanceY, 0);
assertThat(gestureListenerCaptor.getValue().onScroll(event1, event2, 0, distanceY))
.isTrue();
@@ -276,84 +362,4 @@
inputEventListenerCaptor.getValue().onInputEvent(upEvent);
}
-
- /**
- * Tests that ending a swipe before the set expansion threshold leads to bouncer collapsing
- * down.
- */
- @Test
- public void testSwipeBelowThreshold_collapsesBouncer() {
- final float swipeUpPercentage = .3f;
- final float expansion = 1 - swipeUpPercentage;
- // The upward velocity is ignored.
- final float velocityY = -1;
- swipeToPosition(swipeUpPercentage, velocityY);
-
- verify(mValueAnimatorCreator).create(eq(expansion), eq(KeyguardBouncer.EXPANSION_HIDDEN));
- verify(mFlingAnimationUtilsClosing).apply(eq(mValueAnimator),
- eq(SCREEN_HEIGHT_PX * expansion),
- eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_HIDDEN),
- eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
- verify(mValueAnimator).start();
- }
-
- /**
- * Tests that ending a swipe above the set expansion threshold will continue the expansion.
- */
- @Test
- public void testSwipeAboveThreshold_expandsBouncer() {
- final float swipeUpPercentage = .7f;
- final float expansion = 1 - swipeUpPercentage;
- // The downward velocity is ignored.
- final float velocityY = 1;
- swipeToPosition(swipeUpPercentage, velocityY);
-
- verify(mValueAnimatorCreator).create(eq(expansion), eq(KeyguardBouncer.EXPANSION_VISIBLE));
- verify(mFlingAnimationUtils).apply(eq(mValueAnimator), eq(SCREEN_HEIGHT_PX * expansion),
- eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_VISIBLE),
- eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
- verify(mValueAnimator).start();
- }
-
- /**
- * Tests that swiping down with a speed above the set threshold leads to bouncer collapsing
- * down.
- */
- @Test
- public void testSwipeDownVelocityAboveMin_collapsesBouncer() {
- when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn((float) 0);
-
- // The swipe amount above the set expansion threshold is ignored.
- final float swipeUpPercentage = .7f;
- final float expansion = 1 - swipeUpPercentage;
- final float velocityY = 1;
- swipeToPosition(swipeUpPercentage, velocityY);
-
- verify(mValueAnimatorCreator).create(eq(expansion), eq(KeyguardBouncer.EXPANSION_HIDDEN));
- verify(mFlingAnimationUtilsClosing).apply(eq(mValueAnimator),
- eq(SCREEN_HEIGHT_PX * expansion),
- eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_HIDDEN),
- eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
- verify(mValueAnimator).start();
- }
-
- /**
- * Tests that swiping up with a speed above the set threshold will continue the expansion.
- */
- @Test
- public void testSwipeUpVelocityAboveMin_expandsBouncer() {
- when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn((float) 0);
-
- // The swipe amount below the set expansion threshold is ignored.
- final float swipeUpPercentage = .3f;
- final float expansion = 1 - swipeUpPercentage;
- final float velocityY = -1;
- swipeToPosition(swipeUpPercentage, velocityY);
-
- verify(mValueAnimatorCreator).create(eq(expansion), eq(KeyguardBouncer.EXPANSION_VISIBLE));
- verify(mFlingAnimationUtils).apply(eq(mValueAnimator), eq(SCREEN_HEIGHT_PX * expansion),
- eq(SCREEN_HEIGHT_PX * KeyguardBouncer.EXPANSION_VISIBLE),
- eq(velocityY), eq((float) SCREEN_HEIGHT_PX));
- verify(mValueAnimator).start();
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index 1c7e3a4..63b3a7d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -16,10 +16,12 @@
package com.android.systemui.media
+import org.mockito.Mockito.`when` as whenever
import android.content.Intent
import android.graphics.Color
+import android.graphics.drawable.Animatable2
+import android.graphics.drawable.AnimatedVectorDrawable
import android.graphics.drawable.GradientDrawable
-import android.graphics.drawable.Icon
import android.graphics.drawable.RippleDrawable
import android.media.MediaMetadata
import android.media.session.MediaSession
@@ -35,6 +37,7 @@
import android.widget.ImageView
import android.widget.SeekBar
import android.widget.TextView
+import androidx.constraintlayout.widget.Barrier
import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.LiveData
import androidx.test.filters.SmallTest
@@ -58,12 +61,12 @@
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mock
+import org.mockito.Mockito.any
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
-import org.mockito.Mockito.`when` as whenever
private const val KEY = "TEST_KEY"
private const val APP = "APP"
@@ -120,6 +123,7 @@
private lateinit var actionPlayPause: ImageButton
private lateinit var actionNext: ImageButton
private lateinit var actionPrev: ImageButton
+ private lateinit var actionsTopBarrier: Barrier
@Mock private lateinit var longPressText: TextView
@Mock private lateinit var handler: Handler
private lateinit var settings: ImageButton
@@ -176,6 +180,21 @@
actionPrev = ImageButton(context).also { it.setId(R.id.actionPrev) }
actionNext = ImageButton(context).also { it.setId(R.id.actionNext) }
+ actionsTopBarrier =
+ Barrier(context).also {
+ it.id = R.id.media_action_barrier_top
+ it.referencedIds =
+ intArrayOf(
+ actionPrev.id,
+ seekBar.id,
+ actionNext.id,
+ action0.id,
+ action1.id,
+ action2.id,
+ action3.id,
+ action4.id)
+ }
+
initMediaViewHolderMocks()
// Create media session
@@ -254,6 +273,8 @@
whenever(viewHolder.cancelText).thenReturn(cancelText)
whenever(viewHolder.dismiss).thenReturn(dismiss)
whenever(viewHolder.dismissText).thenReturn(dismissText)
+
+ whenever(viewHolder.actionsTopBarrier).thenReturn(actionsTopBarrier)
}
@After
@@ -271,15 +292,15 @@
@Test
fun bindSemanticActions() {
- val icon = Icon.createWithResource(context, android.R.drawable.ic_media_play)
+ val icon = context.getDrawable(android.R.drawable.ic_media_play)
+ val bg = context.getDrawable(R.drawable.qs_media_round_button_background)
val semanticActions = MediaButton(
- playOrPause = MediaAction(icon, Runnable {}, "play"),
- nextOrCustom = MediaAction(icon, Runnable {}, "next"),
- custom0 = MediaAction(icon, null, "custom 0"),
- custom1 = MediaAction(icon, null, "custom 1")
+ playOrPause = MediaAction(icon, Runnable {}, "play", bg),
+ nextOrCustom = MediaAction(icon, Runnable {}, "next", bg),
+ custom0 = MediaAction(icon, null, "custom 0", bg),
+ custom1 = MediaAction(icon, null, "custom 1", bg)
)
val state = mediaData.copy(semanticActions = semanticActions)
-
player.attachPlayer(viewHolder)
player.bindPlayer(state, PACKAGE)
@@ -316,14 +337,44 @@
}
@Test
+ fun bind_seekBarDisabled_seekBarVisibilityIsSetToInvisible() {
+ whenever(seekBarViewModel.getEnabled()).thenReturn(false)
+
+ val icon = context.getDrawable(android.R.drawable.ic_media_play)
+ val semanticActions = MediaButton(
+ playOrPause = MediaAction(icon, Runnable {}, "play", null),
+ nextOrCustom = MediaAction(icon, Runnable {}, "next", null)
+ )
+ val state = mediaData.copy(semanticActions = semanticActions)
+
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(state, PACKAGE)
+
+ verify(expandedSet).setVisibility(R.id.media_progress_bar, ConstraintSet.INVISIBLE)
+ }
+
+ @Test
+ fun bind_seekBarDisabled_noActions_seekBarVisibilityIsSetToGone() {
+ whenever(seekBarViewModel.getEnabled()).thenReturn(false)
+
+ val state = mediaData.copy(semanticActions = MediaButton())
+
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(state, PACKAGE)
+
+ verify(expandedSet).setVisibility(R.id.media_progress_bar, ConstraintSet.INVISIBLE)
+ }
+
+ @Test
fun bindNotificationActions() {
- val icon = Icon.createWithResource(context, android.R.drawable.ic_media_play)
+ val icon = context.getDrawable(android.R.drawable.ic_media_play)
+ val bg = context.getDrawable(R.drawable.qs_media_round_button_background)
val actions = listOf(
- MediaAction(icon, Runnable {}, "previous"),
- MediaAction(icon, Runnable {}, "play"),
- MediaAction(icon, null, "next"),
- MediaAction(icon, null, "custom 0"),
- MediaAction(icon, Runnable {}, "custom 1")
+ MediaAction(icon, Runnable {}, "previous", bg),
+ MediaAction(icon, Runnable {}, "play", bg),
+ MediaAction(icon, null, "next", bg),
+ MediaAction(icon, null, "custom 0", bg),
+ MediaAction(icon, Runnable {}, "custom 1", bg)
)
val state = mediaData.copy(actions = actions,
actionsToShowInCompact = listOf(1, 2),
@@ -365,6 +416,74 @@
}
@Test
+ fun bindAnimatedSemanticActions() {
+ val mockAvd0 = mock(AnimatedVectorDrawable::class.java)
+ val mockAvd1 = mock(AnimatedVectorDrawable::class.java)
+ val mockAvd2 = mock(AnimatedVectorDrawable::class.java)
+ whenever(mockAvd0.mutate()).thenReturn(mockAvd0)
+ whenever(mockAvd1.mutate()).thenReturn(mockAvd1)
+ whenever(mockAvd2.mutate()).thenReturn(mockAvd2)
+
+ val icon = context.getDrawable(R.drawable.ic_media_play)
+ val bg = context.getDrawable(R.drawable.ic_media_play_container)
+ val semanticActions0 = MediaButton(
+ playOrPause = MediaAction(mockAvd0, Runnable {}, "play", null))
+ val semanticActions1 = MediaButton(
+ playOrPause = MediaAction(mockAvd1, Runnable {}, "pause", null))
+ val semanticActions2 = MediaButton(
+ playOrPause = MediaAction(mockAvd2, Runnable {}, "loading", null))
+ val state0 = mediaData.copy(semanticActions = semanticActions0)
+ val state1 = mediaData.copy(semanticActions = semanticActions1)
+ val state2 = mediaData.copy(semanticActions = semanticActions2)
+
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(state0, PACKAGE)
+
+ // Validate first binding
+ assertThat(actionPlayPause.isEnabled()).isTrue()
+ assertThat(actionPlayPause.contentDescription).isEqualTo("play")
+ assertThat(actionPlayPause.getBackground()).isNull()
+ verify(collapsedSet).setVisibility(R.id.actionPlayPause, ConstraintSet.VISIBLE)
+ assertThat(actionPlayPause.hasOnClickListeners()).isTrue()
+
+ // Trigger animation & update mock
+ actionPlayPause.performClick()
+ verify(mockAvd0, times(1)).start()
+ whenever(mockAvd0.isRunning()).thenReturn(true)
+
+ // Validate states no longer bind
+ player.bindPlayer(state1, PACKAGE)
+ player.bindPlayer(state2, PACKAGE)
+ assertThat(actionPlayPause.contentDescription).isEqualTo("play")
+
+ // Complete animation and run callbacks
+ whenever(mockAvd0.isRunning()).thenReturn(false)
+ val captor = ArgumentCaptor.forClass(Animatable2.AnimationCallback::class.java)
+ verify(mockAvd0, times(1)).registerAnimationCallback(captor.capture())
+ verify(mockAvd1, never())
+ .registerAnimationCallback(any(Animatable2.AnimationCallback::class.java))
+ verify(mockAvd2, never())
+ .registerAnimationCallback(any(Animatable2.AnimationCallback::class.java))
+ captor.getValue().onAnimationEnd(mockAvd0)
+
+ // Validate correct state was bound
+ assertThat(actionPlayPause.contentDescription).isEqualTo("loading")
+ assertThat(actionPlayPause.getBackground()).isNull()
+ verify(mockAvd0, times(1))
+ .registerAnimationCallback(any(Animatable2.AnimationCallback::class.java))
+ verify(mockAvd1, times(1)
+ ).registerAnimationCallback(any(Animatable2.AnimationCallback::class.java))
+ verify(mockAvd2, times(1))
+ .registerAnimationCallback(any(Animatable2.AnimationCallback::class.java))
+ verify(mockAvd0, times(1))
+ .unregisterAnimationCallback(any(Animatable2.AnimationCallback::class.java))
+ verify(mockAvd1, times(1))
+ .unregisterAnimationCallback(any(Animatable2.AnimationCallback::class.java))
+ verify(mockAvd2, never())
+ .unregisterAnimationCallback(any(Animatable2.AnimationCallback::class.java))
+ }
+
+ @Test
fun bindText() {
player.attachPlayer(viewHolder)
player.bindPlayer(mediaData, PACKAGE)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
index 203eb47..d65b6b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.media
+import org.mockito.Mockito.`when` as whenever
import android.graphics.Rect
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
@@ -54,7 +55,6 @@
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
-import org.mockito.Mockito.`when` as whenever
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -283,6 +283,28 @@
.isEqualTo(expectedTranslation)
}
+ @Test
+ fun isCurrentlyInGuidedTransformation_hostsVisible_returnsTrue() {
+ goToLockscreen()
+ enterGuidedTransformation()
+ whenever(lockHost.visible).thenReturn(true)
+ whenever(qsHost.visible).thenReturn(true)
+ whenever(qqsHost.visible).thenReturn(true)
+
+ assertThat(mediaHiearchyManager.isCurrentlyInGuidedTransformation()).isTrue()
+ }
+
+ @Test
+ fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsTrue() {
+ goToLockscreen()
+ enterGuidedTransformation()
+ whenever(lockHost.visible).thenReturn(false)
+ whenever(qsHost.visible).thenReturn(true)
+ whenever(qqsHost.visible).thenReturn(true)
+
+ assertThat(mediaHiearchyManager.isCurrentlyInGuidedTransformation()).isFalse()
+ }
+
private fun enableSplitShade() {
context.getOrCreateTestableResources().addOverride(
R.bool.config_use_split_notification_shade, true
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaViewHolderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaViewHolderTest.kt
new file mode 100644
index 0000000..ee32793
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaViewHolderTest.kt
@@ -0,0 +1,24 @@
+package com.android.systemui.media
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+import android.widget.FrameLayout
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class MediaViewHolderTest : SysuiTestCase() {
+
+ @Test
+ fun create_succeeds() {
+ val inflater = LayoutInflater.from(context)
+ val parent = FrameLayout(context)
+
+ MediaViewHolder.create(inflater, parent)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
index 99901a0..e719e84 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
@@ -53,7 +53,6 @@
@Before
fun setUp() {
-
context.orCreateTestableResources
.addOverride(R.dimen.qs_media_enabled_seekbar_height, enabledHeight)
context.orCreateTestableResources
@@ -72,7 +71,7 @@
fun seekBarGone() {
// WHEN seek bar is disabled
val isEnabled = false
- val data = SeekBarViewModel.Progress(isEnabled, false, false, null, 0)
+ val data = SeekBarViewModel.Progress(isEnabled, false, false, false, null, 0)
observer.onChanged(data)
// THEN seek bar shows just a thin line with no text
assertThat(seekBarView.isEnabled()).isFalse()
@@ -85,7 +84,7 @@
fun seekBarVisible() {
// WHEN seek bar is enabled
val isEnabled = true
- val data = SeekBarViewModel.Progress(isEnabled, true, false, 3000, 12000)
+ val data = SeekBarViewModel.Progress(isEnabled, true, false, false, 3000, 12000)
observer.onChanged(data)
// THEN seek bar is visible and thick
assertThat(seekBarView.getVisibility()).isEqualTo(View.VISIBLE)
@@ -95,7 +94,7 @@
@Test
fun seekBarProgress() {
// WHEN part of the track has been played
- val data = SeekBarViewModel.Progress(true, true, true, 3000, 120000)
+ val data = SeekBarViewModel.Progress(true, true, true, false, 3000, 120000)
observer.onChanged(data)
// THEN seek bar shows the progress
assertThat(seekBarView.progress).isEqualTo(3000)
@@ -109,7 +108,7 @@
fun seekBarDisabledWhenSeekNotAvailable() {
// WHEN seek is not available
val isSeekAvailable = false
- val data = SeekBarViewModel.Progress(true, isSeekAvailable, false, 3000, 120000)
+ val data = SeekBarViewModel.Progress(true, isSeekAvailable, false, false, 3000, 120000)
observer.onChanged(data)
// THEN seek bar is not enabled
assertThat(seekBarView.isEnabled()).isFalse()
@@ -119,27 +118,51 @@
fun seekBarEnabledWhenSeekNotAvailable() {
// WHEN seek is available
val isSeekAvailable = true
- val data = SeekBarViewModel.Progress(true, isSeekAvailable, false, 3000, 120000)
+ val data = SeekBarViewModel.Progress(true, isSeekAvailable, false, false, 3000, 120000)
observer.onChanged(data)
// THEN seek bar is not enabled
assertThat(seekBarView.isEnabled()).isTrue()
}
@Test
- fun seekBarPlaying() {
+ fun seekBarPlayingNotScrubbing() {
// WHEN playing
val isPlaying = true
- val data = SeekBarViewModel.Progress(true, true, isPlaying, 3000, 120000)
+ val isScrubbing = false
+ val data = SeekBarViewModel.Progress(true, true, isPlaying, isScrubbing, 3000, 120000)
observer.onChanged(data)
// THEN progress drawable is animating
verify(mockSquigglyProgress).animate = true
}
@Test
- fun seekBarNotPlaying() {
- // WHEN not playing
+ fun seekBarNotPlayingNotScrubbing() {
+ // WHEN not playing & not scrubbing
val isPlaying = false
- val data = SeekBarViewModel.Progress(true, true, isPlaying, 3000, 120000)
+ val isScrubbing = false
+ val data = SeekBarViewModel.Progress(true, true, isPlaying, isScrubbing, 3000, 120000)
+ observer.onChanged(data)
+ // THEN progress drawable is not animating
+ verify(mockSquigglyProgress).animate = false
+ }
+
+ @Test
+ fun seekBarPlayingScrubbing() {
+ // WHEN playing & scrubbing
+ val isPlaying = true
+ val isScrubbing = true
+ val data = SeekBarViewModel.Progress(true, true, isPlaying, isScrubbing, 3000, 120000)
+ observer.onChanged(data)
+ // THEN progress drawable is not animating
+ verify(mockSquigglyProgress).animate = false
+ }
+
+ @Test
+ fun seekBarNotPlayingScrubbing() {
+ // WHEN playing & scrubbing
+ val isPlaying = false
+ val isScrubbing = true
+ val data = SeekBarViewModel.Progress(true, true, isPlaying, isScrubbing, 3000, 120000)
observer.onChanged(data)
// THEN progress drawable is not animating
verify(mockSquigglyProgress).animate = false
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
index 8ccf559..3f45ff3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -46,6 +46,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHost;
+import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTileView;
import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.logging.QSLogger;
@@ -62,6 +63,7 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collections;
+import java.util.List;
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@@ -89,6 +91,8 @@
@Mock
QSTileImpl mQSTile;
@Mock
+ QSTile mOtherTile;
+ @Mock
QSTileView mQSTileView;
@Mock
PagedTileLayout mPagedTileLayout;
@@ -280,4 +284,17 @@
assertThat(mController.shouldUseHorizontalLayout()).isFalse();
verify(mHorizontalLayoutListener, times(2)).run();
}
+
+ @Test
+ public void testRefreshAllTilesDoesntRefreshListeningTiles() {
+ when(mQSTileHost.getTiles()).thenReturn(List.of(mQSTile, mOtherTile));
+ mController.setTiles();
+
+ when(mQSTile.isListening()).thenReturn(false);
+ when(mOtherTile.isListening()).thenReturn(true);
+
+ mController.refreshAllTiles();
+ verify(mQSTile).refreshState();
+ verify(mOtherTile, never()).refreshState();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
index 1b48a16..e9488e9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -4,13 +4,13 @@
import android.testing.AndroidTestingRunner
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
-import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.media.MediaHost
import com.android.systemui.media.MediaHostState
import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.qs.customize.QSCustomizerController
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.settings.brightness.BrightnessController
@@ -21,11 +21,12 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
+import org.mockito.Mockito
import org.mockito.Mockito.any
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -49,6 +50,8 @@
@Mock private lateinit var falsingManager: FalsingManager
@Mock private lateinit var featureFlags: FeatureFlags
@Mock private lateinit var mediaHost: MediaHost
+ @Mock private lateinit var tile: QSTile
+ @Mock private lateinit var otherTile: QSTile
private lateinit var controller: QSPanelController
@@ -93,8 +96,17 @@
verify(mediaHost).expansion = MediaHostState.EXPANDED
}
- private fun setSplitShadeEnabled(enabled: Boolean) {
- mContext.orCreateTestableResources
- .addOverride(R.bool.config_use_split_notification_shade, enabled)
+ @Test
+ fun testSetListeningDoesntRefreshListeningTiles() {
+ whenever(qsTileHost.getTiles()).thenReturn(listOf(tile, otherTile))
+ controller.setTiles()
+ whenever(tile.isListening()).thenReturn(false)
+ whenever(otherTile.isListening()).thenReturn(true)
+ whenever(qsPanel.isListening).thenReturn(true)
+
+ controller.setListening(true, true)
+
+ verify(tile).refreshState()
+ verify(otherTile, Mockito.never()).refreshState()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
index 30b464b..040af70 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
@@ -373,6 +373,11 @@
}
@Override
+ public boolean isListening() {
+ return mListening;
+ }
+
+ @Override
public CharSequence getTileLabel() {
return mSpec;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
index c5bc68d..c31a971 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
@@ -361,6 +361,24 @@
assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, captor.getValue().getAction());
}
+ @Test
+ public void testIsListening() {
+ Object o = new Object();
+
+ mTile.setListening(o, true);
+ mTestableLooper.processAllMessages();
+ assertTrue(mTile.isListening());
+
+ mTile.setListening(o, false);
+ mTestableLooper.processAllMessages();
+ assertFalse(mTile.isListening());
+
+ mTile.setListening(o, true);
+ mTile.destroy();
+ mTestableLooper.processAllMessages();
+ assertFalse(mTile.isListening());
+ }
+
private void assertEvent(UiEventLogger.UiEventEnum eventType,
UiEventLoggerFake.FakeUiEvent fakeEvent) {
assertEquals(eventType.getId(), fakeEvent.eventId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index 1d2a0ca..e2d6ae0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -44,6 +44,7 @@
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.junit.MockitoJUnit
private fun <T> anyObject(): T {
@@ -75,6 +76,8 @@
@Mock lateinit var expandHelperCallback: ExpandHelper.Callback
@Mock lateinit var mCentralSurfaces: CentralSurfaces
@Mock lateinit var qS: QS
+ @Mock lateinit var singleShadeOverScroller: SingleShadeLockScreenOverScroller
+ @Mock lateinit var splitShadeOverScroller: SplitShadeLockScreenOverScroller
@JvmField @Rule val mockito = MockitoJUnit.rule()
private val configurationController = FakeConfigurationController()
@@ -104,7 +107,9 @@
context = context,
configurationController = configurationController,
falsingManager = falsingManager,
- dumpManager = dumpManager
+ dumpManager = dumpManager,
+ splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
+ singleShadeOverScrollerFactory = { singleShadeOverScroller }
)
whenever(nsslController.view).thenReturn(stackscroller)
whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback)
@@ -229,7 +234,7 @@
fun testDragDownAmountDoesntCallOutInLockedDownShade() {
whenever(nsslController.isInLockedDownShade).thenReturn(true)
transitionController.dragDownAmount = 10f
- verify(nsslController, never()).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
+ verify(nsslController, never()).setTransitionToFullShadeAmount(anyFloat())
verify(mediaHierarchyManager, never()).setTransitionToFullShadeAmount(anyFloat())
verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
verify(notificationPanelController, never()).setTransitionToFullShadeAmount(anyFloat(),
@@ -240,7 +245,7 @@
@Test
fun testDragDownAmountCallsOut() {
transitionController.dragDownAmount = 10f
- verify(nsslController).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
+ verify(nsslController).setTransitionToFullShadeAmount(anyFloat())
verify(mediaHierarchyManager).setTransitionToFullShadeAmount(anyFloat())
verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
verify(notificationPanelController).setTransitionToFullShadeAmount(anyFloat(),
@@ -250,14 +255,25 @@
}
@Test
- fun testDragDownAmount_depthDistanceIsZero_doesNotSetProgress() {
+ fun testDragDownAmount_depthDistanceIsZero_setsProgressToZero() {
context.getOrCreateTestableResources()
.addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 0)
configurationController.notifyConfigurationChanged()
transitionController.dragDownAmount = 10f
- verify(depthController, never()).transitionToFullShadeProgress
+ verify(depthController).transitionToFullShadeProgress = 0f
+ }
+
+ @Test
+ fun testDragDownAmount_depthDistanceNonZero_setsProgressBasedOnDistance() {
+ context.getOrCreateTestableResources()
+ .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
+ configurationController.notifyConfigurationChanged()
+
+ transitionController.dragDownAmount = 10f
+
+ verify(depthController).transitionToFullShadeProgress = 0.1f
}
@Test
@@ -282,8 +298,9 @@
fun setDragAmount_notInSplitShade_setsKeyguardTranslationToZero() {
val mediaTranslationY = 123
disableSplitShade()
+ whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
- .thenReturn(mediaTranslationY)
+ .thenReturn(mediaTranslationY)
transitionController.dragDownAmount = 10f
@@ -294,13 +311,33 @@
fun setDragAmount_inSplitShade_setsKeyguardTranslationBasedOnMediaTranslation() {
val mediaTranslationY = 123
enableSplitShade()
+ whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
- .thenReturn(mediaTranslationY)
+ .thenReturn(mediaTranslationY)
transitionController.dragDownAmount = 10f
verify(notificationPanelController)
- .setKeyguardTransitionProgress(anyFloat(), eq(mediaTranslationY))
+ .setKeyguardTransitionProgress(anyFloat(), eq(mediaTranslationY))
+ }
+
+ @Test
+ fun setDragAmount_inSplitShade_mediaNotShowing_setsKeyguardTranslationBasedOnDistance() {
+ enableSplitShade()
+ whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(false)
+ whenever(mediaHierarchyManager.getGuidedTransformationTranslationY()).thenReturn(123)
+
+ transitionController.dragDownAmount = 10f
+
+ val distance =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_keyguard_transition_distance)
+ val offset =
+ context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_keyguard_transition_vertical_offset)
+ val expectedTranslation = 10f / distance * offset
+ verify(notificationPanelController)
+ .setKeyguardTransitionProgress(anyFloat(), eq(expectedTranslation.toInt()))
}
@Test
@@ -388,6 +425,48 @@
verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
}
+ @Test
+ fun setDragAmount_notInSplitShade_forwardsToSingleShadeOverScroller() {
+ disableSplitShade()
+
+ transitionController.dragDownAmount = 10f
+
+ verify(singleShadeOverScroller).expansionDragDownAmount = 10f
+ verifyZeroInteractions(splitShadeOverScroller)
+ }
+
+ @Test
+ fun setDragAmount_inSplitShade_forwardsToSplitShadeOverScroller() {
+ enableSplitShade()
+
+ transitionController.dragDownAmount = 10f
+
+ verify(splitShadeOverScroller).expansionDragDownAmount = 10f
+ verifyZeroInteractions(singleShadeOverScroller)
+ }
+
+ @Test
+ fun setDragDownAmount_inSplitShade_setsKeyguardStatusBarAlphaBasedOnDistance() {
+ val alphaDistance = context.resources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
+ val dragDownAmount = 10f
+ enableSplitShade()
+
+ transitionController.dragDownAmount = dragDownAmount
+
+ val expectedAlpha = 1 - dragDownAmount / alphaDistance
+ verify(notificationPanelController).setKeyguardStatusBarAlpha(expectedAlpha)
+ }
+
+ @Test
+ fun setDragDownAmount_notInSplitShade_setsKeyguardStatusBarAlphaToMinusOne() {
+ disableSplitShade()
+
+ transitionController.dragDownAmount = 10f
+
+ verify(notificationPanelController).setKeyguardStatusBarAlpha(-1f)
+ }
+
private fun enableSplitShade() {
setSplitShadeEnabled(true)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt
new file mode 100644
index 0000000..2606be5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt
@@ -0,0 +1,56 @@
+package com.android.systemui.statusbar
+
+import org.mockito.Mockito.`when` as whenever
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
+import com.android.systemui.statusbar.policy.FakeConfigurationController
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.intThat
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class SingleShadeLockScreenOverScrollerTest : SysuiTestCase() {
+
+ @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
+ @Mock private lateinit var nsslController: NotificationStackScrollLayoutController
+
+ private lateinit var overScroller: SingleShadeLockScreenOverScroller
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ whenever(nsslController.height).thenReturn(1800)
+ overScroller =
+ SingleShadeLockScreenOverScroller(
+ FakeConfigurationController(),
+ context,
+ statusBarStateController,
+ nsslController
+ )
+ }
+
+ @Test
+ fun setDragDownAmount_onKeyguard_overScrolls() {
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+
+ overScroller.expansionDragDownAmount = 10f
+
+ verify(nsslController).setOverScrollAmount(intThat { it > 0 })
+ }
+
+ @Test
+ fun setDragDownAmount_notOnKeyguard_doesNotOverScroll() {
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
+
+ overScroller.expansionDragDownAmount = 10f
+
+ verify(nsslController).setOverScrollAmount(0)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
new file mode 100644
index 0000000..9d5099c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
@@ -0,0 +1,124 @@
+package com.android.systemui.statusbar
+
+import org.mockito.Mockito.`when` as whenever
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.qs.QS
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
+import com.android.systemui.statusbar.phone.ScrimController
+import com.android.systemui.statusbar.policy.FakeConfigurationController
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.atLeast
+import org.mockito.Mockito.intThat
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+@TestableLooper.RunWithLooper
+class SplitShadeLockScreenOverScrollerTest : SysuiTestCase() {
+
+ private val configurationController = FakeConfigurationController()
+
+ @Mock private lateinit var scrimController: ScrimController
+ @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
+ @Mock private lateinit var qS: QS
+ @Mock private lateinit var nsslController: NotificationStackScrollLayoutController
+
+ private lateinit var overScroller: SplitShadeLockScreenOverScroller
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ whenever(nsslController.height).thenReturn(1800)
+
+ overScroller =
+ SplitShadeLockScreenOverScroller(
+ configurationController,
+ context,
+ scrimController,
+ statusBarStateController,
+ qS,
+ nsslController)
+ }
+
+ @Test
+ fun setDragDownAmount_onKeyguard_appliesOverScroll() {
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+
+ setDragAmount(1000f)
+
+ verifyOverScrollPerformed()
+ }
+
+ @Test
+ fun setDragDownAmount_notOnKeyguard_doesNotApplyOverScroll() {
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
+
+ setDragAmount(1000f)
+
+ verifyZeroInteractions(qS)
+ verifyZeroInteractions(scrimController)
+ verifyZeroInteractions(nsslController)
+ }
+
+ @Test
+ fun setDragAmount_onKeyguard_thenNotOnKeyguard_resetsOverScrollToZero() {
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+ setDragAmount(1000f)
+ verifyOverScrollPerformed()
+ reset(qS, scrimController, nsslController)
+
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
+ setDragAmount(999f)
+ verifyOverScrollResetToZero()
+ }
+
+ @Test
+ fun setDragAmount_onKeyguard_thenNotOnKeyguard_multipleTimes_resetsOverScrollToZeroOnlyOnce() {
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+ setDragAmount(1000f)
+ whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
+ setDragAmount(999f)
+ reset(qS, scrimController, nsslController)
+
+ setDragAmount(998f)
+ setDragAmount(997f)
+ setDragAmount(996f)
+ verifyNoMoreOverScrollChanges()
+ }
+
+ private fun verifyOverScrollPerformed() {
+ verify(qS).setOverScrollAmount(intThat { it > 0 })
+ verify(scrimController).setNotificationsOverScrollAmount(intThat { it > 0 })
+ verify(nsslController).setOverScrollAmount(intThat { it > 0 })
+ }
+
+ private fun verifyOverScrollResetToZero() {
+ // Might be more than once as the animator might have multiple values close to zero that
+ // round down to zero.
+ verify(qS, atLeast(1)).setOverScrollAmount(0)
+ verify(scrimController, atLeast(1)).setNotificationsOverScrollAmount(0)
+ verify(nsslController, atLeast(1)).setOverScrollAmount(0)
+ }
+
+ private fun verifyNoMoreOverScrollChanges() {
+ verifyNoMoreInteractions(qS)
+ verifyNoMoreInteractions(scrimController)
+ verifyNoMoreInteractions(nsslController)
+ }
+
+ private fun setDragAmount(dragDownAmount: Float) {
+ overScroller.expansionDragDownAmount = dragDownAmount
+ overScroller.finishAnimations()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
index f470715..dd0c758 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
@@ -1173,6 +1173,29 @@
}
@Test
+ public void testStabilizeGroupsAlwaysAllowsGroupChangeFromDeletedGroupToRoot() {
+ // GIVEN a group w/ summary and two children
+ addGroupSummary(0, PACKAGE_1, GROUP_1);
+ addGroupChild(1, PACKAGE_1, GROUP_1);
+ addGroupChild(2, PACKAGE_1, GROUP_1);
+ dispatchBuild();
+
+ // GIVEN visual stability manager doesn't allow any group changes
+ mStabilityManager.setAllowGroupChanges(false);
+
+ // WHEN we run the pipeline with the summary and one child removed
+ mEntrySet.remove(2);
+ mEntrySet.remove(0);
+ dispatchBuild();
+
+ // THEN all that remains is the one child at top-level, despite no group change allowed by
+ // visual stability manager.
+ verifyBuiltList(
+ notif(0)
+ );
+ }
+
+ @Test
public void testStabilizeGroupsDoesNotAllowGroupingExistingNotifications() {
// GIVEN one group child without a summary yet
addGroupChild(0, PACKAGE_1, GROUP_1);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
index 32d625c..4e07d59 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
@@ -19,6 +19,7 @@
import static android.app.Notification.VISIBILITY_PUBLIC;
import static android.app.Notification.VISIBILITY_SECRET;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static com.android.systemui.statusbar.notification.collection.EntryUtilKt.modifyEntry;
@@ -209,7 +210,7 @@
Consumer<String> listener = mock(Consumer.class);
mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener);
- mFakeSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
+ mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, true);
verify(listener).accept(anyString());
}
@@ -220,7 +221,7 @@
Consumer<String> listener = mock(Consumer.class);
mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener);
- mFakeSettings.putInt(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1);
+ mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, true);
verify(listener).accept(anyString());
}
@@ -231,7 +232,7 @@
Consumer<String> listener = mock(Consumer.class);
mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener);
- mFakeSettings.putInt(Settings.Global.ZEN_MODE, 1);
+ mFakeSettings.putBool(Settings.Global.ZEN_MODE, true);
verify(listener).accept(anyString());
}
@@ -242,7 +243,7 @@
Consumer<String> listener = mock(Consumer.class);
mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener);
- mFakeSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1);
+ mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, true);
verify(listener).accept(anyString());
}
@@ -338,6 +339,25 @@
}
@Test
+ public void showSilentOnLockscreenSetting() {
+ // GIVEN an 'unfiltered-keyguard-showing' state
+ setupUnfilteredState(mEntry);
+
+ // WHEN the notification is not high priority and not ambient
+ mEntry.setRanking(new RankingBuilder()
+ .setKey(mEntry.getKey())
+ .setImportance(IMPORTANCE_LOW)
+ .build());
+ when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false);
+
+ // WHEN the show silent notifs on lockscreen setting is true
+ mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, true);
+
+ // THEN do not filter out the entry
+ assertFalse(mKeyguardNotificationVisibilityProvider.shouldHideNotification(mEntry));
+ }
+
+ @Test
public void summaryExceedsThresholdToShow() {
// GIVEN the notification doesn't exceed the threshold to show on the lockscreen
// but it's part of a group (has a parent)
@@ -360,6 +380,7 @@
.build());
// WHEN its parent does exceed threshold tot show on the lockscreen
+ mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, false);
when(mHighPriorityProvider.isHighPriority(parent)).thenReturn(true);
// THEN don't filter out the entry
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
index d1848e3..9a4e10c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
@@ -22,12 +22,10 @@
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.StatusBarState.KEYGUARD
import com.android.systemui.statusbar.StatusBarState.SHADE
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.util.mockito.any
@@ -38,17 +36,13 @@
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.mock
-import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
@SmallTest
@RunWith(AndroidTestingRunner::class)
class NotificationStackSizeCalculatorTest : SysuiTestCase() {
- @Mock private lateinit var groupManager: NotificationGroupManagerLegacy
-
- @Mock private lateinit var notificationLockscreenUserManager: NotificationLockscreenUserManager
-
@Mock private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
@Mock private lateinit var stackLayout: NotificationStackScrollLayout
@@ -63,7 +57,6 @@
whenever(stackLayout.calculateGapHeight(nullable(), nullable(), any()))
.thenReturn(GAP_HEIGHT)
- whenever(groupManager.isSummaryOfSuppressedGroup(any())).thenReturn(false)
with(testableResources) {
addOverride(R.integer.keyguard_max_notification_count, -1)
addOverride(R.dimen.notification_divider_height, NOTIFICATION_PADDING.toInt())
@@ -71,15 +64,13 @@
sizeCalculator =
NotificationStackSizeCalculator(
- groupManager = groupManager,
- lockscreenUserManager = notificationLockscreenUserManager,
statusBarStateController = sysuiStatusBarStateController,
testableResources.resources)
}
@Test
fun computeMaxKeyguardNotifications_zeroSpace_returnZero() {
- val rows = listOf(createMockRow(height = ROW_HEIGHT, visibleOnLockscreen = true))
+ val rows = listOf(createMockRow(height = ROW_HEIGHT))
val maxNotifications =
computeMaxKeyguardNotifications(rows, availableSpace = 0f, shelfHeight = 0f)
@@ -106,8 +97,8 @@
val spaceForOne = totalSpaceForEachRow
val rows =
listOf(
- createMockRow(rowHeight, visibleOnLockscreen = true),
- createMockRow(rowHeight, visibleOnLockscreen = true))
+ createMockRow(rowHeight),
+ createMockRow(rowHeight))
val maxNotifications =
computeMaxKeyguardNotifications(
@@ -124,8 +115,8 @@
val spaceForOne = totalSpaceForEachRow
val rows =
listOf(
- createMockRow(rowHeight, visibleOnLockscreen = true),
- createMockRow(rowHeight, visibleOnLockscreen = true))
+ createMockRow(rowHeight),
+ createMockRow(rowHeight))
val maxNotifications =
computeMaxKeyguardNotifications(
@@ -135,24 +126,15 @@
}
@Test
- fun computeMaxKeyguardNotifications_invisibleOnLockscreen_returnsZero() {
- val rows = listOf(createMockRow(visibleOnLockscreen = false))
-
- val maxNotifications = computeMaxKeyguardNotifications(rows, Float.MAX_VALUE)
-
- assertThat(maxNotifications).isEqualTo(0)
- }
-
- @Test
fun computeMaxKeyguardNotifications_spaceForTwo_returnsTwo() {
val rowHeight = ROW_HEIGHT
val totalSpaceForEachRow = GAP_HEIGHT + rowHeight
val spaceForTwo = totalSpaceForEachRow * 2 + NOTIFICATION_PADDING
val rows =
listOf(
- createMockRow(rowHeight, visibleOnLockscreen = true),
- createMockRow(rowHeight, visibleOnLockscreen = true),
- createMockRow(rowHeight, visibleOnLockscreen = true))
+ createMockRow(rowHeight),
+ createMockRow(rowHeight),
+ createMockRow(rowHeight))
val maxNotifications = computeMaxKeyguardNotifications(rows, spaceForTwo, shelfHeight = 0f)
@@ -167,9 +149,9 @@
val availableSpace = totalSpaceForEachRow * 2
val rows =
listOf(
- createMockRow(rowHeight, visibleOnLockscreen = true),
- createMockRow(rowHeight, visibleOnLockscreen = true),
- createMockRow(rowHeight, visibleOnLockscreen = true))
+ createMockRow(rowHeight),
+ createMockRow(rowHeight),
+ createMockRow(rowHeight))
val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight)
assertThat(maxNotifications).isEqualTo(2)
@@ -178,31 +160,6 @@
assertThat(height).isAtMost(availableSpace + SHELF_HEIGHT)
}
- @Test
- fun computeHeight_allInvisibleToLockscreen_NotInLockscreen_returnsHigherThanZero() {
- setOnLockscreen(false)
- val rowHeight = 10f
- setupChildren(listOf(createMockRow(rowHeight, visibleOnLockscreen = false)))
-
- val height =
- sizeCalculator.computeHeight(
- stackLayout, maxNotifications = Int.MAX_VALUE, SHELF_HEIGHT)
-
- assertThat(height).isGreaterThan(rowHeight)
- }
-
- @Test
- fun computeHeight_allInvisibleToLockscreen_onLockscreen_returnsZero() {
- setOnLockscreen(true)
- setupChildren(listOf(createMockRow(visibleOnLockscreen = false)))
-
- val height =
- sizeCalculator.computeHeight(
- stackLayout, maxNotifications = Int.MAX_VALUE, SHELF_HEIGHT)
-
- assertThat(height).isEqualTo(0)
- }
-
private fun computeMaxKeyguardNotifications(
rows: List<ExpandableView>,
availableSpace: Float,
@@ -222,14 +179,12 @@
}
private fun createLockscreenRows(number: Int): List<ExpandableNotificationRow> =
- (1..number).map { createMockRow(visibleOnLockscreen = true) }.toList()
+ (1..number).map { createMockRow() }.toList()
private fun createMockRow(
height: Float = ROW_HEIGHT,
- visibleOnLockscreen: Boolean = true,
isRemoved: Boolean = false,
visibility: Int = VISIBLE,
- summaryOfSuppressed: Boolean = false
): ExpandableNotificationRow {
val row = mock(ExpandableNotificationRow::class.java)
val entry = mock(NotificationEntry::class.java)
@@ -238,24 +193,11 @@
whenever(row.entry).thenReturn(entry)
whenever(row.isRemoved).thenReturn(isRemoved)
whenever(row.visibility).thenReturn(visibility)
- whenever(notificationLockscreenUserManager.shouldShowOnKeyguard(entry))
- .thenReturn(visibleOnLockscreen)
- whenever(groupManager.isSummaryOfSuppressedGroup(sbn)).thenReturn(summaryOfSuppressed)
whenever(row.getMinHeight(any())).thenReturn(height.toInt())
whenever(row.intrinsicHeight).thenReturn(height.toInt())
return row
}
- private fun setOnLockscreen(onLockscreen: Boolean) {
- whenever(sysuiStatusBarStateController.state)
- .thenReturn(
- if (onLockscreen) {
- KEYGUARD
- } else {
- SHADE
- })
- }
-
/** Default dimensions for tests that don't overwrite them. */
companion object {
const val GAP_HEIGHT = 12f
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index 7de3545..39d5a16 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
@@ -343,6 +343,28 @@
assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
}
+ @Test
+ public void setAlpha_explicitAlpha_setsExplicitAlpha() {
+ mController.onViewAttached();
+ updateStateToKeyguard();
+
+ mController.setAlpha(0.5f);
+
+ assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(0.5f);
+ }
+
+ @Test
+ public void setAlpha_explicitAlpha_thenMinusOneAlpha_setsAlphaBasedOnDefaultCriteria() {
+ mController.onViewAttached();
+ updateStateToKeyguard();
+
+ mController.setAlpha(0.5f);
+ mController.setAlpha(-1f);
+
+ assertThat(mKeyguardStatusBarView.getAlpha()).isGreaterThan(0);
+ assertThat(mKeyguardStatusBarView.getAlpha()).isNotEqualTo(0.5f);
+ }
+
// TODO(b/195442899): Add more tests for #updateViewState once CLs are finalized.
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
index 21d03ad..22bf6c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
@@ -930,6 +930,23 @@
verify(mLargeScreenShadeHeaderController).setActive(false);
}
+ @Test
+ public void testUnlockAnimationDoesNotAffectScrim() {
+ mNotificationPanelViewController.onUnlockHintStarted();
+ verify(mScrimController).setExpansionAffectsAlpha(false);
+ mNotificationPanelViewController.onUnlockHintFinished();
+ verify(mScrimController).setExpansionAffectsAlpha(true);
+ }
+
+ @Test
+ public void setKeyguardStatusBarAlpha_setsAlphaOnKeyguardStatusBarController() {
+ float statusBarAlpha = 0.5f;
+
+ mNotificationPanelViewController.setKeyguardStatusBarAlpha(statusBarAlpha);
+
+ verify(mKeyguardStatusBarViewController).setAlpha(statusBarAlpha);
+ }
+
private void triggerPositionClockAndNotifications() {
mNotificationPanelViewController.closeQs();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
index c797bc8..79cbed8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
@@ -155,14 +155,16 @@
}
@Test
- public void attach_scrimHidesWallpaper() {
+ public void attach_scrimDoesntHideWallpaper() {
when(mKeyguardViewMediator.isShowingAndNotOccluded()).thenReturn(true);
mNotificationShadeWindowController.attach();
clearInvocations(mWindowManager);
mNotificationShadeWindowController.setScrimsVisibility(ScrimController.OPAQUE);
- verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
- assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) == 0).isTrue();
+ // The scrim used to remove the wallpaper flag, but this causes a relayout.
+ // Instead, we're not relying on SurfaceControl#setOpaque on
+ // NotificationShadeDepthController.
+ verify(mWindowManager, never()).updateViewLayout(any(), mLayoutParameters.capture());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
index 093f926..7e245fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
@@ -24,11 +24,13 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollectorFake
import com.android.systemui.dock.DockManager
+import com.android.systemui.keyguard.KeyguardUnlockAnimationController
import com.android.systemui.lowlightclock.LowLightClockController
import com.android.systemui.statusbar.LockscreenShadeTransitionController
import com.android.systemui.statusbar.NotificationShadeDepthController
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.notification.stack.AmbientState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.NotificationShadeWindowView.InteractionEventHandler
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
@@ -71,6 +73,10 @@
@Mock
private lateinit var mNotificationShadeWindowController: NotificationShadeWindowController
@Mock
+ private lateinit var mKeyguardUnlockAnimationController: KeyguardUnlockAnimationController
+ @Mock
+ private lateinit var mAmbientState: AmbientState
+ @Mock
private lateinit var stackScrollLayoutController: NotificationStackScrollLayoutController
@Mock
private lateinit var mStatusBarKeyguardViewManager: StatusBarKeyguardViewManager
@@ -109,7 +115,9 @@
mLockIconViewController,
Optional.of(mLowLightClockController),
mCentralSurfaces,
- mNotificationShadeWindowController
+ mNotificationShadeWindowController,
+ mKeyguardUnlockAnimationController,
+ mAmbientState
)
mController.setupExpandedStatusBar()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
index 62a1bcd..1d86fb1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
@@ -37,12 +37,14 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.dock.DockManager;
+import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.lowlightclock.LowLightClockController;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
@@ -83,6 +85,8 @@
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
@Mock private LockIconViewController mLockIconViewController;
@Mock private LowLightClockController mLowLightClockController;
+ @Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
+ @Mock private AmbientState mAmbientState;
@Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
mInteractionEventHandlerCaptor;
@@ -117,7 +121,9 @@
mLockIconViewController,
Optional.of(mLowLightClockController),
mCentralSurfaces,
- mNotificationShadeWindowController);
+ mNotificationShadeWindowController,
+ mKeyguardUnlockAnimationController,
+ mAmbientState);
mController.setupExpandedStatusBar();
mController.setDragDownHelper(mDragDownHelper);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 786a858..5eef1df 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -53,6 +53,7 @@
import com.android.systemui.DejankUtils;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager;
+import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -112,6 +113,8 @@
private ConfigurationController mConfigurationController;
@Mock
private ScreenOffAnimationController mScreenOffAnimationController;
+ @Mock
+ private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
// TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
// event-dispatch-on-registration pattern caused some of these unit tests to fail.)
@Mock
@@ -229,7 +232,8 @@
new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor,
mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
mScreenOffAnimationController,
- mPanelExpansionStateManager);
+ mPanelExpansionStateManager,
+ mKeyguardUnlockAnimationController);
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
mScrimController.setAnimatorListener(mAnimatorListener);
@@ -1074,8 +1078,9 @@
ScrimState.OFF, ScrimState.AOD, ScrimState.PULSING));
HashSet<ScrimState> regularStates = new HashSet<>(Arrays.asList(
ScrimState.UNINITIALIZED, ScrimState.KEYGUARD, ScrimState.BOUNCER,
- ScrimState.BOUNCER_SCRIMMED, ScrimState.BRIGHTNESS_MIRROR, ScrimState.UNLOCKED,
- ScrimState.SHADE_LOCKED, ScrimState.AUTH_SCRIMMED, ScrimState.AUTH_SCRIMMED_SHADE));
+ ScrimState.DREAMING, ScrimState.BOUNCER_SCRIMMED, ScrimState.BRIGHTNESS_MIRROR,
+ ScrimState.UNLOCKED, ScrimState.SHADE_LOCKED, ScrimState.AUTH_SCRIMMED,
+ ScrimState.AUTH_SCRIMMED_SHADE));
for (ScrimState state : ScrimState.values()) {
if (!lowPowerModeStates.contains(state) && !regularStates.contains(state)) {
@@ -1103,6 +1108,7 @@
// GIVEN device has an activity showing ('UNLOCKED' state can occur on the lock screen
// with the camera app occluding the keyguard)
mScrimController.transitionTo(ScrimState.UNLOCKED);
+ mScrimController.setClipsQsScrim(true);
mScrimController.setRawPanelExpansionFraction(1);
// notifications scrim alpha change require calling setQsPosition
mScrimController.setQsPosition(0, 300);
@@ -1116,6 +1122,12 @@
mScrimBehind.getViewAlpha(), 1, 0.0);
assertEquals("Notifications scrim should be opaque",
mNotificationsScrim.getViewAlpha(), 1, 0.0);
+
+ assertScrimTinted(Map.of(
+ mScrimInFront, true,
+ mScrimBehind, true,
+ mNotificationsScrim, false
+ ));
}
@Test
@@ -1224,8 +1236,8 @@
public void testNotificationTransparency_followsPanelExpansionInShadeLockedState() {
mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0.8f, /* expansion */ 0.8f);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0.47f, /* expansion */ 0.2f);
+ assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0f, /* expansion */ 0.8f);
+ assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0f, /* expansion */ 0.2f);
}
@Test
@@ -1238,15 +1250,16 @@
// Verify normal behavior after
mScrimController.setUnocclusionAnimationRunning(false);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0.2f, /* expansion */ 0.4f);
+ assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 1f, /* expansion */ 0.4f);
}
@Test
public void testNotificationTransparency_inKeyguardState() {
mScrimController.transitionTo(ScrimState.KEYGUARD);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0.2f, /* expansion */ 0.4f);
- assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0.52f, /* expansion */ 0.2f);
+ assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 1f, /* expansion */ 0.8f);
+ assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 1f, /* expansion */ 0.4f);
+ assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 1f, /* expansion */ 0.2f);
}
@Test
@@ -1292,6 +1305,52 @@
assertThat(mNotificationsScrim.getViewAlpha()).isEqualTo(notifProgress);
}
+ @Test
+ public void setNotificationsOverScrollAmount_setsTranslationYOnNotificationsScrim() {
+ int overScrollAmount = 10;
+
+ mScrimController.setNotificationsOverScrollAmount(overScrollAmount);
+
+ assertThat(mNotificationsScrim.getTranslationY()).isEqualTo(overScrollAmount);
+ }
+
+ @Test
+ public void setNotificationsOverScrollAmount_doesNotSetTranslationYOnBehindScrim() {
+ int overScrollAmount = 10;
+
+ mScrimController.setNotificationsOverScrollAmount(overScrollAmount);
+
+ assertThat(mScrimBehind.getTranslationY()).isEqualTo(0);
+ }
+
+ @Test
+ public void setNotificationsOverScrollAmount_doesNotSetTranslationYOnFrontScrim() {
+ int overScrollAmount = 10;
+
+ mScrimController.setNotificationsOverScrollAmount(overScrollAmount);
+
+ assertThat(mScrimInFront.getTranslationY()).isEqualTo(0);
+ }
+
+ @Test
+ public void transitionToDreaming() {
+ mScrimController.setRawPanelExpansionFraction(0f);
+ mScrimController.setBouncerHiddenFraction(KeyguardBouncer.EXPANSION_HIDDEN);
+ mScrimController.transitionTo(ScrimState.DREAMING);
+ finishAnimationsImmediately();
+
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT,
+ mScrimBehind, TRANSPARENT));
+
+ assertScrimTinted(Map.of(
+ mScrimInFront, false,
+ mScrimBehind, true,
+ mNotificationsScrim, false
+ ));
+ }
+
private void assertAlphaAfterExpansion(ScrimView scrim, float expectedAlpha, float expansion) {
mScrimController.setRawPanelExpansionFraction(expansion);
finishAnimationsImmediately();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
index 7c05c69..6c83e9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
@@ -57,33 +57,33 @@
@Test
public void testRegisterReceiver() {
- final SystemUIDialog mDialog = new SystemUIDialog(mContext);
+ final SystemUIDialog dialog = new SystemUIDialog(mContext);
final ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
final ArgumentCaptor<IntentFilter> intentFilterCaptor =
ArgumentCaptor.forClass(IntentFilter.class);
- mDialog.show();
+ dialog.show();
verify(mBroadcastDispatcher).registerReceiver(broadcastReceiverCaptor.capture(),
intentFilterCaptor.capture(), eq(null), any());
assertTrue(intentFilterCaptor.getValue().hasAction(Intent.ACTION_SCREEN_OFF));
assertTrue(intentFilterCaptor.getValue().hasAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
- mDialog.dismiss();
+ dialog.dismiss();
verify(mBroadcastDispatcher).unregisterReceiver(eq(broadcastReceiverCaptor.getValue()));
}
@Test
public void testNoRegisterReceiver() {
- final SystemUIDialog mDialog = new SystemUIDialog(mContext, false);
+ final SystemUIDialog dialog = new SystemUIDialog(mContext, false);
- mDialog.show();
+ dialog.show();
verify(mBroadcastDispatcher, never()).registerReceiver(any(), any(), eq(null), any());
- assertTrue(mDialog.isShowing());
+ assertTrue(dialog.isShowing());
- mDialog.dismiss();
+ dialog.dismiss();
verify(mBroadcastDispatcher, never()).unregisterReceiver(any());
- assertFalse(mDialog.isShowing());
+ assertFalse(dialog.isShowing());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerTest.kt
new file mode 100644
index 0000000..37c0f36
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerTest.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone.userswitcher
+
+import android.content.Intent
+import android.os.UserHandle
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.qs.user.UserSwitchDialogController
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+@SmallTest
+class StatusBarUserSwitcherControllerTest : SysuiTestCase() {
+ @Mock
+ private lateinit var tracker: StatusBarUserInfoTracker
+
+ @Mock
+ private lateinit var featureController: StatusBarUserSwitcherFeatureController
+
+ @Mock
+ private lateinit var userSwitcherDialogController: UserSwitchDialogController
+
+ @Mock
+ private lateinit var featureFlags: FeatureFlags
+
+ @Mock
+ private lateinit var activityStarter: ActivityStarter
+
+ @Mock
+ private lateinit var falsingManager: FalsingManager
+
+ private lateinit var statusBarUserSwitcherContainer: StatusBarUserSwitcherContainer
+ private lateinit var controller: StatusBarUserSwitcherControllerImpl
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ statusBarUserSwitcherContainer = StatusBarUserSwitcherContainer(mContext, null)
+ statusBarUserSwitcherContainer
+ controller = StatusBarUserSwitcherControllerImpl(
+ statusBarUserSwitcherContainer,
+ tracker,
+ featureController,
+ userSwitcherDialogController,
+ featureFlags,
+ activityStarter,
+ falsingManager
+ )
+ controller.init()
+ controller.onViewAttached()
+ }
+
+ @Test
+ fun testFalsingManager() {
+ statusBarUserSwitcherContainer.callOnClick()
+ verify(falsingManager).isFalseTap(FalsingManager.LOW_PENALTY)
+ }
+
+ @Test
+ fun testStartActivity() {
+ `when`(featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)).thenReturn(false)
+ statusBarUserSwitcherContainer.callOnClick()
+ verify(userSwitcherDialogController).showDialog(any(View::class.java))
+ `when`(featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)).thenReturn(true)
+ statusBarUserSwitcherContainer.callOnClick()
+ verify(activityStarter).startActivity(any(Intent::class.java),
+ eq(true) /* dismissShade */,
+ eq(null) /* animationController */,
+ eq(true) /* showOverLockscreenWhenLocked */,
+ eq(UserHandle.SYSTEM))
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index f804d83..b8f66fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -39,6 +39,7 @@
import android.content.Intent;
import android.content.om.FabricatedOverlay;
import android.content.om.OverlayIdentifier;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Color;
import android.os.Handler;
@@ -56,6 +57,7 @@
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.monet.ColorScheme;
import com.android.systemui.monet.Style;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -108,6 +110,8 @@
@Mock
private FeatureFlags mFeatureFlags;
@Mock
+ private Resources mResources;
+ @Mock
private WakefulnessLifecycle mWakefulnessLifecycle;
@Captor
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiver;
@@ -129,10 +133,20 @@
when(mFeatureFlags.isEnabled(Flags.MONET)).thenReturn(true);
when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
- mThemeOverlayController = new ThemeOverlayController(null /* context */,
+ when(mResources.getColor(eq(android.R.color.system_accent1_500), any()))
+ .thenReturn(Color.RED);
+ when(mResources.getColor(eq(android.R.color.system_accent2_500), any()))
+ .thenReturn(Color.GREEN);
+ when(mResources.getColor(eq(android.R.color.system_accent3_500), any()))
+ .thenReturn(Color.BLUE);
+ when(mResources.getColor(eq(android.R.color.system_neutral1_500), any()))
+ .thenReturn(Color.YELLOW);
+ when(mResources.getColor(eq(android.R.color.system_neutral2_500), any()))
+ .thenReturn(Color.BLACK);
+ mThemeOverlayController = new ThemeOverlayController(mContext,
mBroadcastDispatcher, mBgHandler, mMainExecutor, mBgExecutor, mThemeOverlayApplier,
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
- mUserTracker, mDumpManager, mFeatureFlags, mWakefulnessLifecycle) {
+ mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
@Nullable
@Override
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
@@ -140,6 +154,7 @@
when(overlay.getIdentifier())
.thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
mCurrentStyle = style;
+ mColorScheme = new ColorScheme(color, false /* nightMode */, style);
return overlay;
}
};
@@ -643,16 +658,17 @@
Executor executor = MoreExecutors.directExecutor();
- mThemeOverlayController = new ThemeOverlayController(null /* context */,
+ mThemeOverlayController = new ThemeOverlayController(mContext,
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
- mUserTracker, mDumpManager, mFeatureFlags, mWakefulnessLifecycle) {
+ mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
@Nullable
@Override
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
FabricatedOverlay overlay = mock(FabricatedOverlay.class);
when(overlay.getIdentifier())
.thenReturn(new OverlayIdentifier("com.thebest.livewallpaperapp.ever"));
+ mColorScheme = new ColorScheme(color, false /* nightMode */, style);
return overlay;
}
@@ -679,16 +695,17 @@
.thenReturn(new WallpaperColors(Color.valueOf(Color.GRAY), null, null));
Executor executor = MoreExecutors.directExecutor();
- mThemeOverlayController = new ThemeOverlayController(null /* context */,
+ mThemeOverlayController = new ThemeOverlayController(mContext,
mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
- mUserTracker, mDumpManager, mFeatureFlags, mWakefulnessLifecycle) {
+ mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
@Nullable
@Override
protected FabricatedOverlay getOverlay(int color, int type, Style style) {
FabricatedOverlay overlay = mock(FabricatedOverlay.class);
when(overlay.getIdentifier())
.thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
+ mColorScheme = new ColorScheme(color, false /* nightMode */, style);
return overlay;
}
};
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
new file mode 100644
index 0000000..5509a6ca
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.unfold.progress
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING
+import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE
+import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN
+import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN
+import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING
+import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED
+import com.android.systemui.unfold.util.TestFoldStateProvider
+import com.android.systemui.util.leak.ReferenceTestUtils.waitForCondition
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class PhysicsBasedUnfoldTransitionProgressProviderTest : SysuiTestCase() {
+
+ private val foldStateProvider: TestFoldStateProvider = TestFoldStateProvider()
+ private val listener = TestUnfoldProgressListener()
+ private lateinit var progressProvider: UnfoldTransitionProgressProvider
+
+ @Before
+ fun setUp() {
+ progressProvider = PhysicsBasedUnfoldTransitionProgressProvider(
+ foldStateProvider
+ )
+ progressProvider.addCallback(listener)
+ }
+
+ @Test
+ fun testUnfold_emitsIncreasingTransitionEvents() {
+ runOnMainThreadWithInterval(
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
+ { foldStateProvider.sendHingeAngleUpdate(10f) },
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) },
+ { foldStateProvider.sendHingeAngleUpdate(90f) },
+ { foldStateProvider.sendHingeAngleUpdate(180f) },
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) },
+ )
+
+ with(listener.ensureTransitionFinished()) {
+ assertIncreasingProgress()
+ assertFinishedWithUnfold()
+ }
+ }
+
+ @Test
+ fun testUnfold_screenAvailableOnlyAfterFullUnfold_emitsIncreasingTransitionEvents() {
+ runOnMainThreadWithInterval(
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
+ { foldStateProvider.sendHingeAngleUpdate(10f) },
+ { foldStateProvider.sendHingeAngleUpdate(90f) },
+ { foldStateProvider.sendHingeAngleUpdate(180f) },
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) },
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) },
+ )
+
+ with(listener.ensureTransitionFinished()) {
+ assertIncreasingProgress()
+ assertFinishedWithUnfold()
+ }
+ }
+
+ @Test
+ fun testFold_emitsDecreasingTransitionEvents() {
+ runOnMainThreadWithInterval(
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_CLOSING) },
+ { foldStateProvider.sendHingeAngleUpdate(170f) },
+ { foldStateProvider.sendHingeAngleUpdate(90f) },
+ { foldStateProvider.sendHingeAngleUpdate(10f) },
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_CLOSED) },
+ )
+
+ with(listener.ensureTransitionFinished()) {
+ assertDecreasingProgress()
+ assertFinishedWithFold()
+ }
+ }
+
+ @Test
+ fun testUnfoldAndStopUnfolding_finishesTheUnfoldTransition() {
+ runOnMainThreadWithInterval(
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) },
+ { foldStateProvider.sendHingeAngleUpdate(10f) },
+ { foldStateProvider.sendHingeAngleUpdate(90f) },
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN) },
+ )
+
+ with(listener.ensureTransitionFinished()) {
+ assertIncreasingProgress()
+ assertFinishedWithUnfold()
+ }
+ }
+
+ @Test
+ fun testFoldImmediatelyAfterUnfold_runsFoldAnimation() {
+ runOnMainThreadWithInterval(
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) },
+ { foldStateProvider.sendHingeAngleUpdate(10f) },
+ { foldStateProvider.sendHingeAngleUpdate(90f) },
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) },
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_CLOSING) },
+ { foldStateProvider.sendHingeAngleUpdate(60f) },
+ { foldStateProvider.sendHingeAngleUpdate(10f) },
+ { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_CLOSED) },
+ )
+
+ with(listener.ensureTransitionFinished()) {
+ assertHasFoldAnimationAtTheEnd()
+ }
+ }
+
+ private class TestUnfoldProgressListener : TransitionProgressListener {
+
+ private val recordings: MutableList<UnfoldTransitionRecording> = arrayListOf()
+ private var currentRecording: UnfoldTransitionRecording? = null
+
+ override fun onTransitionStarted() {
+ assertWithMessage("Trying to start a transition when it is already in progress")
+ .that(currentRecording).isNull()
+
+ currentRecording = UnfoldTransitionRecording()
+ }
+
+ override fun onTransitionProgress(progress: Float) {
+ assertWithMessage("Received transition progress event when it's not started")
+ .that(currentRecording).isNotNull()
+ currentRecording!!.addProgress(progress)
+ }
+
+ override fun onTransitionFinished() {
+ assertWithMessage("Received transition finish event when it's not started")
+ .that(currentRecording).isNotNull()
+ recordings += currentRecording!!
+ currentRecording = null
+ }
+
+ fun ensureTransitionFinished(): UnfoldTransitionRecording {
+ waitForCondition { recordings.size == 1 }
+ return recordings.first()
+ }
+
+ class UnfoldTransitionRecording {
+ private val progressHistory: MutableList<Float> = arrayListOf()
+
+ fun addProgress(progress: Float) {
+ assertThat(progress).isAtMost(1.0f)
+ assertThat(progress).isAtLeast(0.0f)
+
+ progressHistory += progress
+ }
+
+ fun assertIncreasingProgress() {
+ assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS)
+ assertThat(progressHistory).isInOrder()
+ }
+
+ fun assertDecreasingProgress() {
+ assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS)
+ assertThat(progressHistory).isInOrder(Comparator.reverseOrder<Float>())
+ }
+
+ fun assertFinishedWithUnfold() {
+ assertThat(progressHistory).isNotEmpty()
+ assertThat(progressHistory.last()).isEqualTo(1.0f)
+ }
+
+ fun assertFinishedWithFold() {
+ assertThat(progressHistory).isNotEmpty()
+ assertThat(progressHistory.last()).isEqualTo(0.0f)
+ }
+
+ fun assertHasFoldAnimationAtTheEnd() {
+ // Check that there are at least a few decreasing events at the end
+ assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS)
+ assertThat(progressHistory.takeLast(MIN_ANIMATION_EVENTS))
+ .isInOrder(Comparator.reverseOrder<Float>())
+ assertThat(progressHistory.last()).isEqualTo(0.0f)
+ }
+ }
+
+ private companion object {
+ private const val MIN_ANIMATION_EVENTS = 5
+ }
+ }
+
+ private fun runOnMainThreadWithInterval(vararg blocks: () -> Unit, intervalMillis: Long = 60) {
+ blocks.forEach {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ it()
+ }
+ Thread.sleep(intervalMillis)
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
index f43dc6c..7ac2434 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
@@ -16,6 +16,11 @@
package com.android.systemui.unfold.updates
+import android.app.ActivityManager
+import android.app.ActivityManager.RunningTaskInfo
+import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
+import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
+import android.app.WindowConfiguration.ActivityType
import android.hardware.devicestate.DeviceStateManager
import android.hardware.devicestate.DeviceStateManager.FoldStateListener
import android.os.Handler
@@ -30,7 +35,6 @@
import com.android.systemui.unfold.util.FoldableTestUtils
import com.android.systemui.util.mockito.any
import com.google.common.truth.Truth.assertThat
-import java.lang.Exception
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -51,6 +55,8 @@
@Mock private lateinit var deviceStateManager: DeviceStateManager
+ @Mock private lateinit var activityManager: ActivityManager
+
@Mock private lateinit var handler: Handler
@Captor private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
@@ -80,6 +86,7 @@
hingeAngleProvider,
screenStatusProvider,
deviceStateManager,
+ activityManager,
context.mainExecutor,
handler)
@@ -113,6 +120,9 @@
}
null
}
+
+ // By default, we're on launcher.
+ setupForegroundActivityType(ACTIVITY_TYPE_HOME)
}
@Test
@@ -258,6 +268,31 @@
}
}
+ @Test
+ fun startClosingEvent_whileNotOnLauncher_doesNotTriggerBeforeThreshold() {
+ setupForegroundActivityType(ACTIVITY_TYPE_STANDARD)
+ sendHingeAngleEvent(180)
+
+ sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
+
+ assertThat(foldUpdates).isEmpty()
+ }
+
+ @Test
+ fun startClosingEvent_whileNotOnLauncher_triggersAfterThreshold() {
+ setupForegroundActivityType(ACTIVITY_TYPE_STANDARD)
+ sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES)
+
+ sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES - 1)
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+ }
+
+ private fun setupForegroundActivityType(@ActivityType type: Int) {
+ val taskInfo = RunningTaskInfo().apply { topActivityType = type }
+ whenever(activityManager.getRunningTasks(1)).thenReturn(listOf(taskInfo))
+ }
+
private fun simulateTimeout(waitTime: Long = HALF_OPENED_TIMEOUT_MILLIS) {
val runnableDelay = scheduledRunnableDelay ?: throw Exception("No runnable scheduled.")
if (waitTime >= runnableDelay) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
new file mode 100644
index 0000000..dd307b4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.unfold.util
+
+import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN
+import com.android.systemui.unfold.updates.FoldStateProvider
+import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
+import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
+
+class TestFoldStateProvider : FoldStateProvider {
+
+ private val listeners: MutableList<FoldUpdatesListener> = arrayListOf()
+
+ override fun start() {
+ }
+
+ override fun stop() {
+ listeners.clear()
+ }
+
+ private var _isFullyOpened: Boolean = false
+
+ override val isFullyOpened: Boolean
+ get() = _isFullyOpened
+
+ override fun addCallback(listener: FoldUpdatesListener) {
+ listeners += listener
+ }
+
+ override fun removeCallback(listener: FoldUpdatesListener) {
+ listeners -= listener
+ }
+
+ fun sendFoldUpdate(@FoldUpdate update: Int) {
+ if (update == FOLD_UPDATE_FINISH_FULL_OPEN) {
+ _isFullyOpened = true
+ }
+ listeners.forEach { it.onFoldUpdate(update) }
+ }
+
+ fun sendHingeAngleUpdate(angle: Float) {
+ listeners.forEach { it.onHingeAngleUpdate(angle) }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
index d8aef66..6802745 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
@@ -100,6 +100,7 @@
mContext,
MoreExecutors.directExecutor(),
MoreExecutors.directExecutor(),
+ MoreExecutors.directExecutor(),
mSecureSettings,
mQuickAccessWalletClient,
mClock);
diff --git a/packages/VpnDialogs/res/values-or/strings.xml b/packages/VpnDialogs/res/values-or/strings.xml
index 0604b47..4c5c259 100644
--- a/packages/VpnDialogs/res/values-or/strings.xml
+++ b/packages/VpnDialogs/res/values-or/strings.xml
@@ -29,7 +29,7 @@
<string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> ସବୁ ସମୟରେ କନେକ୍ଟ ହୋଇ ରହିବା ପାଇଁ ସେଟଅପ୍ କରାଯାଇଛି। ଆପଣଙ୍କ ଫୋନ୍, <xliff:g id="VPN_APP_1">%1$s</xliff:g> ସହ କନେକ୍ଟ ନହେବା ପର୍ଯ୍ୟନ୍ତ ଏକ ପବ୍ଲିକ୍ ନେଟ୍ୱର୍କ ବ୍ୟବହାର କରିବ।"</string>
<string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g> ସବୁ ସମୟରେ କନେକ୍ଟ ହୋଇରହିବାକୁ ସେଟଅପ୍ କରାଯାଇଛି, କିନ୍ତୁ ଏହା ବର୍ତ୍ତମାନ କନେକ୍ଟ କରିପାରୁ ନାହିଁ। VPN ପୁଣି କନେକ୍ଟ ନହେବା ପର୍ଯ୍ୟନ୍ତ ଆପଣଙ୍କର କୌଣସି କନେକ୍ସନ୍ ରହିବନାହିଁ।"</string>
<string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
- <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN ସେଟିଂସ୍ ବଦଳାନ୍ତୁ"</string>
+ <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN ସେଟିଂସ ବଦଳାନ୍ତୁ"</string>
<string name="configure" msgid="4905518375574791375">"କନଫିଗର୍ କରନ୍ତୁ"</string>
<string name="disconnect" msgid="971412338304200056">"ବିଚ୍ଛିନ୍ନ କରନ୍ତୁ"</string>
<string name="open_app" msgid="3717639178595958667">"ଆପ୍ ଖୋଲନ୍ତୁ"</string>
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 61e3da8..22c77e9 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -4290,11 +4290,15 @@
}
private void onDoubleTapInternal(int displayId) {
+ AccessibilityInputFilter inputFilter = null;
synchronized (mLock) {
if (mHasInputFilter && mInputFilter != null) {
- mInputFilter.onDoubleTap(displayId);
+ inputFilter = mInputFilter;
}
}
+ if (inputFilter != null) {
+ inputFilter.onDoubleTap(displayId);
+ }
}
@Override
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityTraceManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityTraceManager.java
index 51e01ea..6114213 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityTraceManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityTraceManager.java
@@ -50,7 +50,7 @@
private final AccessibilityManagerService mService;
private final Object mA11yMSLock;
- private long mEnabledLoggingFlags;
+ private volatile long mEnabledLoggingFlags;
private static AccessibilityTraceManager sInstance = null;
@@ -77,34 +77,28 @@
@Override
public boolean isA11yTracingEnabled() {
- synchronized (mA11yMSLock) {
- return mEnabledLoggingFlags != FLAGS_LOGGING_NONE;
- }
+ return mEnabledLoggingFlags != FLAGS_LOGGING_NONE;
}
@Override
public boolean isA11yTracingEnabledForTypes(long typeIdFlags) {
- synchronized (mA11yMSLock) {
- return ((typeIdFlags & mEnabledLoggingFlags) != FLAGS_LOGGING_NONE);
- }
+ return ((typeIdFlags & mEnabledLoggingFlags) != FLAGS_LOGGING_NONE);
}
@Override
public int getTraceStateForAccessibilityManagerClientState() {
int state = 0x0;
- synchronized (mA11yMSLock) {
- if (isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION)) {
- state |= STATE_FLAG_TRACE_A11Y_INTERACTION_CONNECTION_ENABLED;
- }
- if (isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION_CALLBACK)) {
- state |= STATE_FLAG_TRACE_A11Y_INTERACTION_CONNECTION_CB_ENABLED;
- }
- if (isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_INTERACTION_CLIENT)) {
- state |= STATE_FLAG_TRACE_A11Y_INTERACTION_CLIENT_ENABLED;
- }
- if (isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_SERVICE)) {
- state |= STATE_FLAG_TRACE_A11Y_SERVICE_ENABLED;
- }
+ if (isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION)) {
+ state |= STATE_FLAG_TRACE_A11Y_INTERACTION_CONNECTION_ENABLED;
+ }
+ if (isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION_CALLBACK)) {
+ state |= STATE_FLAG_TRACE_A11Y_INTERACTION_CONNECTION_CB_ENABLED;
+ }
+ if (isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_INTERACTION_CLIENT)) {
+ state |= STATE_FLAG_TRACE_A11Y_INTERACTION_CLIENT_ENABLED;
+ }
+ if (isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_SERVICE)) {
+ state |= STATE_FLAG_TRACE_A11Y_SERVICE_ENABLED;
}
return state;
}
@@ -116,11 +110,11 @@
return;
}
- synchronized (mA11yMSLock) {
- long oldEnabled = mEnabledLoggingFlags;
- mEnabledLoggingFlags = loggingTypes;
+ long oldEnabled = mEnabledLoggingFlags;
+ mEnabledLoggingFlags = loggingTypes;
- if (needToNotifyClients(oldEnabled)) {
+ if (needToNotifyClients(oldEnabled)) {
+ synchronized (mA11yMSLock) {
mService.scheduleUpdateClientsIfNeededLocked(mService.getCurrentUserState());
}
}
@@ -130,14 +124,14 @@
@Override
public void stopTrace() {
- boolean stop = false;
- synchronized (mA11yMSLock) {
- stop = isA11yTracingEnabled();
+ boolean stop;
+ stop = isA11yTracingEnabled();
- long oldEnabled = mEnabledLoggingFlags;
- mEnabledLoggingFlags = FLAGS_LOGGING_NONE;
+ long oldEnabled = mEnabledLoggingFlags;
+ mEnabledLoggingFlags = FLAGS_LOGGING_NONE;
- if (needToNotifyClients(oldEnabled)) {
+ if (needToNotifyClients(oldEnabled)) {
+ synchronized (mA11yMSLock) {
mService.scheduleUpdateClientsIfNeededLocked(mService.getCurrentUserState());
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
index 51b49ed..55dc196 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
@@ -37,6 +37,7 @@
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.RemoteCallbackList;
import android.provider.Settings;
@@ -123,8 +124,8 @@
private int mInteractiveUiTimeout = 0;
private int mLastSentClientState = -1;
- /** {@code true} if the device config supports magnification area. */
- private final boolean mSupportMagnificationArea;
+ /** {@code true} if the device config supports window magnification. */
+ private final boolean mSupportWindowMagnification;
// The magnification modes on displays.
private final SparseIntArray mMagnificationModes = new SparseIntArray();
// The magnification capabilities used to know magnification mode could be switched.
@@ -148,7 +149,7 @@
boolean isValidMagnificationModeLocked(int displayId) {
final int mode = getMagnificationModeLocked(displayId);
- if (!mSupportMagnificationArea
+ if (!mSupportWindowMagnification
&& mode == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
return false;
}
@@ -170,8 +171,9 @@
R.color.accessibility_focus_highlight_color);
mFocusStrokeWidth = mFocusStrokeWidthDefaultValue;
mFocusColor = mFocusColorDefaultValue;
- mSupportMagnificationArea = mContext.getResources().getBoolean(
- R.bool.config_magnification_area);
+ mSupportWindowMagnification = mContext.getResources().getBoolean(
+ R.bool.config_magnification_area) && mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WINDOW_MAGNIFICATION);
}
boolean isHandlingAccessibilityEventsLocked() {
diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index 3a26c46..f4c24a8 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -165,7 +165,10 @@
@Override
public void onTopActivityChanged(ComponentName topActivity, int uid) {
- if (mActivityListener != null) {
+ // Don't send onTopActivityChanged() callback when topActivity is null because it's defined
+ // as @NonNull in ActivityListener interface. Sends onDisplayEmpty() callback instead when
+ // there is no activity running on virtual display.
+ if (mActivityListener != null && topActivity != null) {
// Post callback on the main thread so it doesn't block activity launching
mHandler.post(() ->
mActivityListener.onTopActivityChanged(Display.INVALID_DISPLAY, topActivity));
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index b05a7db..06fd5c0 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -173,6 +173,11 @@
return flags;
}
+ /** Returns the device display name. */
+ CharSequence getDisplayName() {
+ return mAssociationInfo.getDisplayName();
+ }
+
@Override // Binder call
public int getAssociationId() {
return mAssociationInfo.getId();
@@ -523,8 +528,7 @@
}
PowerManager powerManager = mContext.getSystemService(PowerManager.class);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
- PowerManager.SCREEN_BRIGHT_WAKE_LOCK
- | PowerManager.ACQUIRE_CAUSES_WAKEUP,
+ PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
TAG + ":" + displayId, displayId);
wakeLock.acquire();
mPerDisplayWakelocks.put(displayId, wakeLock);
@@ -596,6 +600,13 @@
* Shows a toast on virtual displays owned by this device which have a given uid running.
*/
void showToastWhereUidIsRunning(int uid, @StringRes int resId, @Toast.Duration int duration) {
+ showToastWhereUidIsRunning(uid, mContext.getString(resId), duration);
+ }
+
+ /**
+ * Shows a toast on virtual displays owned by this device which have a given uid running.
+ */
+ void showToastWhereUidIsRunning(int uid, String text, @Toast.Duration int duration) {
synchronized (mVirtualDeviceLock) {
DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
final int size = mWindowPolicyControllers.size();
@@ -604,7 +615,7 @@
int displayId = mWindowPolicyControllers.keyAt(i);
Display display = displayManager.getDisplay(displayId);
if (display != null && display.isValid()) {
- Toast.makeText(mContext.createDisplayContext(display), resId,
+ Toast.makeText(mContext.createDisplayContext(display), text,
duration).show();
}
}
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index 9f252d7..96400c1 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -193,8 +193,12 @@
synchronized (mVirtualDeviceManagerLock) {
int size = mVirtualDevices.size();
for (int i = 0; i < size; i++) {
+ CharSequence deviceName = mVirtualDevices.valueAt(i).getDisplayName();
mVirtualDevices.valueAt(i).showToastWhereUidIsRunning(appUid,
- com.android.internal.R.string.vdm_camera_access_denied, Toast.LENGTH_LONG);
+ getContext().getString(
+ com.android.internal.R.string.vdm_camera_access_denied,
+ deviceName),
+ Toast.LENGTH_LONG);
}
}
}
diff --git a/services/core/java/com/android/server/DiskStatsService.java b/services/core/java/com/android/server/DiskStatsService.java
index 1095ba3..5fed6d3 100644
--- a/services/core/java/com/android/server/DiskStatsService.java
+++ b/services/core/java/com/android/server/DiskStatsService.java
@@ -129,14 +129,10 @@
DiskStatsFreeSpaceProto.FOLDER_METADATA);
boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
- boolean blockBased = fileBased ? false : StorageManager.isBlockEncrypted();
if (protoFormat) {
if (fileBased) {
proto.write(DiskStatsServiceDumpProto.ENCRYPTION,
DiskStatsServiceDumpProto.ENCRYPTION_FILE_BASED);
- } else if (blockBased) {
- proto.write(DiskStatsServiceDumpProto.ENCRYPTION,
- DiskStatsServiceDumpProto.ENCRYPTION_FULL_DISK);
} else {
proto.write(DiskStatsServiceDumpProto.ENCRYPTION,
DiskStatsServiceDumpProto.ENCRYPTION_NONE);
diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java
index a2a232d..1d457aa 100644
--- a/services/core/java/com/android/server/DropBoxManagerService.java
+++ b/services/core/java/com/android/server/DropBoxManagerService.java
@@ -60,6 +60,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.IDropBoxManagerService;
import com.android.internal.util.DumpUtils;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.ObjectUtils;
import com.android.server.DropBoxManagerInternal.EntrySource;
@@ -501,12 +502,20 @@
}
} catch (IOException e) {
Slog.e(TAG, "Can't write: " + tag, e);
+ logDropboxDropped(
+ FrameworkStatsLog.DROPBOX_ENTRY_DROPPED__DROP_REASON__WRITE_FAILURE,
+ tag,
+ 0);
} finally {
IoUtils.closeQuietly(entry);
if (temp != null) temp.delete();
}
}
+ private void logDropboxDropped(int reason, String tag, long entryAge) {
+ FrameworkStatsLog.write(FrameworkStatsLog.DROPBOX_ENTRY_DROPPED, reason, tag, entryAge);
+ }
+
public boolean isTagEnabled(String tag) {
final long token = Binder.clearCallingIdentity();
try {
@@ -1119,13 +1128,19 @@
Settings.Global.DROPBOX_MAX_FILES,
(ActivityManager.isLowRamDeviceStatic()
? DEFAULT_MAX_FILES_LOWRAM : DEFAULT_MAX_FILES));
- long cutoffMillis = System.currentTimeMillis() - ageSeconds * 1000;
+ long curTimeMillis = System.currentTimeMillis();
+ long cutoffMillis = curTimeMillis - ageSeconds * 1000;
while (!mAllFiles.contents.isEmpty()) {
EntryFile entry = mAllFiles.contents.first();
if (entry.timestampMillis > cutoffMillis && mAllFiles.contents.size() < mMaxFiles) {
break;
}
+ logDropboxDropped(
+ FrameworkStatsLog.DROPBOX_ENTRY_DROPPED__DROP_REASON__AGED,
+ entry.tag,
+ curTimeMillis - entry.timestampMillis);
+
FileList tag = mFilesByTag.get(entry.tag);
if (tag != null && tag.contents.remove(entry)) tag.blocks -= entry.blocks;
if (mAllFiles.contents.remove(entry)) mAllFiles.blocks -= entry.blocks;
@@ -1194,6 +1209,11 @@
if (mAllFiles.blocks < mCachedQuotaBlocks) break;
while (tag.blocks > tagQuota && !tag.contents.isEmpty()) {
EntryFile entry = tag.contents.first();
+ logDropboxDropped(
+ FrameworkStatsLog.DROPBOX_ENTRY_DROPPED__DROP_REASON__CLEARING_DATA,
+ entry.tag,
+ curTimeMillis - entry.timestampMillis);
+
if (tag.contents.remove(entry)) tag.blocks -= entry.blocks;
if (mAllFiles.contents.remove(entry)) mAllFiles.blocks -= entry.blocks;
diff --git a/services/core/java/com/android/server/FactoryResetter.java b/services/core/java/com/android/server/FactoryResetter.java
new file mode 100644
index 0000000..30314a3
--- /dev/null
+++ b/services/core/java/com/android/server/FactoryResetter.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * TODO(b/225012970): add javadoc from {@code com.android.server.devicepolicy.FactoryResetter}
+ */
+public final class FactoryResetter {
+
+ private static final AtomicBoolean sFactoryResetting = new AtomicBoolean(false);
+
+ /**
+ * Checks whether a factory reset is in progress.
+ */
+ public static boolean isFactoryResetting() {
+ return sFactoryResetting.get();
+ }
+
+ /**
+ * @deprecated called by {@code com.android.server.devicepolicy.FactoryResetter}, won't be
+ * needed once that class logic is moved into this.
+ */
+ @Deprecated
+ public static void setFactoryResetting(Context context) {
+ Preconditions.checkCallAuthorization(context.checkCallingOrSelfPermission(
+ android.Manifest.permission.MASTER_CLEAR) == PackageManager.PERMISSION_GRANTED);
+ sFactoryResetting.set(true);
+ }
+
+ private FactoryResetter() {
+ throw new UnsupportedOperationException("Provides only static methods");
+ }
+}
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index 593c406..59db686 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -129,15 +129,15 @@
@Override
public void sendMessage(int subId, String callingPkg, Uri contentUri, String locationUrl,
- Bundle configOverrides, PendingIntent sentIntent, long messageId)
- throws RemoteException {
+ Bundle configOverrides, PendingIntent sentIntent, long messageId,
+ String attributionTag) throws RemoteException {
returnPendingIntentWithError(sentIntent);
}
@Override
public void downloadMessage(int subId, String callingPkg, String locationUrl,
Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent,
- long messageId)
+ long messageId, String attributionTag)
throws RemoteException {
returnPendingIntentWithError(downloadedIntent);
}
@@ -333,12 +333,12 @@
@Override
public void sendMessage(int subId, String callingPkg, Uri contentUri,
String locationUrl, Bundle configOverrides, PendingIntent sentIntent,
- long messageId)
+ long messageId, String attributionTag)
throws RemoteException {
Slog.d(TAG, "sendMessage() by " + callingPkg);
mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send MMS message");
if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, attributionTag, null) != AppOpsManager.MODE_ALLOWED) {
Slog.e(TAG, callingPkg + " is not allowed to call sendMessage()");
return;
}
@@ -347,18 +347,18 @@
Intent.FLAG_GRANT_READ_URI_PERMISSION,
subId);
getServiceGuarded().sendMessage(subId, callingPkg, contentUri, locationUrl,
- configOverrides, sentIntent, messageId);
+ configOverrides, sentIntent, messageId, attributionTag);
}
@Override
public void downloadMessage(int subId, String callingPkg, String locationUrl,
- Uri contentUri, Bundle configOverrides,
- PendingIntent downloadedIntent, long messageId) throws RemoteException {
+ Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent,
+ long messageId, String attributionTag) throws RemoteException {
Slog.d(TAG, "downloadMessage() by " + callingPkg);
mContext.enforceCallingPermission(Manifest.permission.RECEIVE_MMS,
"Download MMS message");
if (getAppOpsManager().noteOp(AppOpsManager.OP_RECEIVE_MMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, attributionTag, null) != AppOpsManager.MODE_ALLOWED) {
Slog.e(TAG, callingPkg + " is not allowed to call downloadMessage()");
return;
}
@@ -368,14 +368,14 @@
subId);
getServiceGuarded().downloadMessage(subId, callingPkg, locationUrl, contentUri,
- configOverrides, downloadedIntent, messageId);
+ configOverrides, downloadedIntent, messageId, attributionTag);
}
@Override
public Uri importTextMessage(String callingPkg, String address, int type, String text,
long timestampMillis, boolean seen, boolean read) throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
// Silently fail AppOps failure due to not being the default SMS app
// while writing the TelephonyProvider
return FAKE_SMS_SENT_URI;
@@ -389,7 +389,7 @@
String messageId, long timestampSecs, boolean seen, boolean read)
throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
// Silently fail AppOps failure due to not being the default SMS app
// while writing the TelephonyProvider
return FAKE_MMS_SENT_URI;
@@ -402,7 +402,7 @@
public boolean deleteStoredMessage(String callingPkg, Uri messageUri)
throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
return false;
}
return getServiceGuarded().deleteStoredMessage(callingPkg, messageUri);
@@ -412,7 +412,7 @@
public boolean deleteStoredConversation(String callingPkg, long conversationId)
throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
return false;
}
return getServiceGuarded().deleteStoredConversation(callingPkg, conversationId);
@@ -422,7 +422,7 @@
public boolean updateStoredMessageStatus(String callingPkg, Uri messageUri,
ContentValues statusValues) throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
return false;
}
return getServiceGuarded()
@@ -433,7 +433,7 @@
public boolean archiveStoredConversation(String callingPkg, long conversationId,
boolean archived) throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
return false;
}
return getServiceGuarded()
@@ -444,7 +444,7 @@
public Uri addTextMessageDraft(String callingPkg, String address, String text)
throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
// Silently fail AppOps failure due to not being the default SMS app
// while writing the TelephonyProvider
return FAKE_SMS_DRAFT_URI;
@@ -456,7 +456,7 @@
public Uri addMultimediaMessageDraft(String callingPkg, Uri contentUri)
throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
// Silently fail AppOps failure due to not being the default SMS app
// while writing the TelephonyProvider
return FAKE_MMS_DRAFT_URI;
@@ -468,7 +468,7 @@
public void sendStoredMessage(int subId, String callingPkg, Uri messageUri,
Bundle configOverrides, PendingIntent sentIntent) throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
return;
}
getServiceGuarded().sendStoredMessage(subId, callingPkg, messageUri, configOverrides,
@@ -478,7 +478,7 @@
@Override
public void setAutoPersisting(String callingPkg, boolean enabled) throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
- callingPkg) != AppOpsManager.MODE_ALLOWED) {
+ callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
return;
}
getServiceGuarded().setAutoPersisting(callingPkg, enabled);
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 1a39ffa..73d9cc7 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1528,7 +1528,7 @@
if (updateFirewallUidRuleLocked(chain, uid, rule)) {
final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
try {
- cm.updateFirewallRule(chain, uid, isFirewallRuleAllow(chain, rule));
+ cm.setUidFirewallRule(chain, uid, rule);
} catch (RuntimeException e) {
throw new IllegalStateException(e);
}
@@ -1601,14 +1601,6 @@
}
}
- // There are only two type of firewall rule: FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY.
- private boolean isFirewallRuleAllow(int chain, int rule) {
- if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
- return getFirewallType(chain) == FIREWALL_DENYLIST;
- }
- return rule == INetd.FIREWALL_RULE_ALLOW;
- }
-
private void enforceSystemUid() {
final int uid = mDeps.getCallingUid();
if (uid != Process.SYSTEM_UID) {
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index b6b3618..24e5de9 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -1,9 +1,6 @@
{
"presubmit": [
{
- "name": "CtsLocationFineTestCases"
- },
- {
"name": "CtsLocationCoarseTestCases"
},
{
@@ -64,5 +61,10 @@
],
"file_patterns": ["ClipboardService\\.java"]
}
+ ],
+ "postsubmit": [
+ {
+ "name": "CtsLocationFineTestCases"
+ }
]
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index b0ab53907..2c0514d 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -203,10 +203,6 @@
// How long we wait for a service to finish executing.
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
- // How long the startForegroundService() grace period is to get around to
- // calling startForeground() before we ANR + stop it.
- static final int SERVICE_START_FOREGROUND_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
-
// Foreground service types that always get immediate notification display,
// expressed in the same bitmask format that ServiceRecord.foregroundServiceType
// uses.
@@ -2789,6 +2785,11 @@
+ ") set BIND_ALLOW_INSTANT when binding service " + service);
}
+ if ((flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0 && !isCallerSystem) {
+ throw new SecurityException("Non-system caller (pid=" + callingPid
+ + ") set BIND_ALMOST_PERCEPTIBLE when binding service " + service);
+ }
+
if ((flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
mAm.enforceCallingPermission(
android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
@@ -2893,6 +2894,12 @@
s.isNotAppComponentUsage = true;
}
+ if (s.app != null && s.app.mState != null
+ && s.app.mState.getCurProcState() <= PROCESS_STATE_TOP
+ && (flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0) {
+ s.lastTopAlmostPerceptibleBindRequestUptimeMs = SystemClock.uptimeMillis();
+ }
+
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app.mServices, c, true);
}
@@ -4235,7 +4242,7 @@
+ " for fg-service launch");
}
mAm.tempAllowlistUidLocked(r.appInfo.uid,
- SERVICE_START_FOREGROUND_TIMEOUT, REASON_SERVICE_LAUNCH,
+ mAm.mConstants.mServiceStartForegroundTimeoutMs, REASON_SERVICE_LAUNCH,
"fg-service-launch",
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
r.mRecentCallingUid);
@@ -4797,6 +4804,10 @@
if ((c.flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
s.updateIsAllowedBgActivityStartsByBinding();
}
+ // And for almost perceptible exceptions.
+ if ((c.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0) {
+ psr.updateHasTopStartedAlmostPerceptibleServices();
+ }
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app.mServices, c, true);
}
@@ -5708,12 +5719,23 @@
}
if (app != null) {
- mAm.mAnrHelper.appNotResponding(app,
- "Context.startForegroundService() did not then call Service.startForeground(): "
- + r);
+ final String annotation = "Context.startForegroundService() did not then call "
+ + "Service.startForeground(): " + r;
+ Message msg = mAm.mHandler.obtainMessage(
+ ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_ANR_MSG);
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = app;
+ args.arg2 = annotation;
+ msg.obj = args;
+ mAm.mHandler.sendMessageDelayed(msg,
+ mAm.mConstants.mServiceStartForegroundAnrDelayMs);
}
}
+ void serviceForegroundTimeoutANR(ProcessRecord app, String annotation) {
+ mAm.mAnrHelper.appNotResponding(app, annotation);
+ }
+
public void updateServiceApplicationInfoLocked(ApplicationInfo applicationInfo) {
final int userId = UserHandle.getUserId(applicationInfo.uid);
ServiceMap serviceMap = mServiceMap.get(userId);
@@ -5734,7 +5756,7 @@
ComponentName service) {
mAm.crashApplicationWithTypeWithExtras(
app.uid, app.getPid(), app.info.packageName, app.userId,
- "Context.startForegroundService() did not then call Service.startForeground(): "
+ "Context.startForegroundService() did not then call " + "Service.startForeground(): "
+ serviceRecord, false /*force*/,
ForegroundServiceDidNotStartInTimeException.TYPE_ID,
ForegroundServiceDidNotStartInTimeException.createExtrasForService(service));
@@ -5759,7 +5781,7 @@
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG);
msg.obj = r;
r.fgWaiting = true;
- mAm.mHandler.sendMessageDelayed(msg, SERVICE_START_FOREGROUND_TIMEOUT);
+ mAm.mHandler.sendMessageDelayed(msg, mAm.mConstants.mServiceStartForegroundTimeoutMs);
}
final class ServiceDumper {
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index cc8c6fb..af9e410 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -108,6 +108,8 @@
static final String KEY_PROCESS_START_ASYNC = "process_start_async";
static final String KEY_MEMORY_INFO_THROTTLE_TIME = "memory_info_throttle_time";
static final String KEY_TOP_TO_FGS_GRACE_DURATION = "top_to_fgs_grace_duration";
+ static final String KEY_TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION =
+ "top_to_almost_perceptible_grace_duration";
static final String KEY_PENDINGINTENT_WARNING_THRESHOLD = "pendingintent_warning_threshold";
static final String KEY_MIN_CRASH_INTERVAL = "min_crash_interval";
static final String KEY_PROCESS_CRASH_COUNT_RESET_INTERVAL =
@@ -170,6 +172,7 @@
private static final boolean DEFAULT_PROCESS_START_ASYNC = true;
private static final long DEFAULT_MEMORY_INFO_THROTTLE_TIME = 5*60*1000;
private static final long DEFAULT_TOP_TO_FGS_GRACE_DURATION = 15 * 1000;
+ private static final long DEFAULT_TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION = 15 * 1000;
private static final int DEFAULT_PENDINGINTENT_WARNING_THRESHOLD = 2000;
private static final int DEFAULT_MIN_CRASH_INTERVAL = 2 * 60 * 1000;
private static final int DEFAULT_MAX_PHANTOM_PROCESSES = 32;
@@ -216,8 +219,14 @@
private static final String DEFAULT_COMPONENT_ALIAS_OVERRIDES = "";
private static final int DEFAULT_DEFER_BOOT_COMPLETED_BROADCAST =
- DEFER_BOOT_COMPLETED_BROADCAST_BACKGROUND_RESTRICTED_ONLY
- | DEFER_BOOT_COMPLETED_BROADCAST_TARGET_T_ONLY;
+ DEFER_BOOT_COMPLETED_BROADCAST_BACKGROUND_RESTRICTED_ONLY
+ | DEFER_BOOT_COMPLETED_BROADCAST_TARGET_T_ONLY;
+
+ private static final int DEFAULT_SERVICE_START_FOREGROUND_TIMEOUT_MS = 30 * 1000;
+
+ private static final int DEFAULT_SERVICE_START_FOREGROUND_ANR_DELAY_MS = 10 * 1000;
+
+ private static final long DEFAULT_SERVICE_BIND_ALMOST_PERCEPTIBLE_TIMEOUT_MS = 15 * 1000;
// Flag stored in the DeviceConfig API.
/**
@@ -311,6 +320,15 @@
private static final String KEY_DEFER_BOOT_COMPLETED_BROADCAST =
"defer_boot_completed_broadcast";
+ private static final String KEY_SERVICE_START_FOREGROUND_TIMEOUT_MS =
+ "service_start_foreground_timeout_ms";
+
+ private static final String KEY_SERVICE_START_FOREGROUND_ANR_DELAY_MS =
+ "service_start_foreground_anr_delay_ms";
+
+ private static final String KEY_SERVICE_BIND_ALMOST_PERCEPTIBLE_TIMEOUT_MS =
+ "service_bind_almost_perceptible_timeout_ms";
+
// Maximum number of cached processes we will allow.
public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
@@ -454,6 +472,13 @@
public long TOP_TO_FGS_GRACE_DURATION = DEFAULT_TOP_TO_FGS_GRACE_DURATION;
/**
+ * Allow app just leaving TOP with an already running ALMOST_PERCEPTIBLE service to stay in
+ * a higher adj value for this long.
+ */
+ public long TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION =
+ DEFAULT_TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION;
+
+ /**
* The minimum time we allow between crashes, for us to consider this
* application to be bad and stop its services and reject broadcasts.
* A reasonable interval here would be anything between 1-3 minutes.
@@ -631,6 +656,26 @@
DEFAULT_DEFER_BOOT_COMPLETED_BROADCAST;
/**
+ * How long the Context.startForegroundService() grace period is to get around to
+ * calling Service.startForeground() before we generate ANR.
+ */
+ volatile int mServiceStartForegroundTimeoutMs = DEFAULT_SERVICE_START_FOREGROUND_TIMEOUT_MS;
+
+ /**
+ * How long from Service.startForeground() timed-out to when we generate ANR of the user app.
+ * This delay is after the timeout {@link #mServiceStartForegroundTimeoutMs}.
+ */
+ volatile int mServiceStartForegroundAnrDelayMs =
+ DEFAULT_SERVICE_START_FOREGROUND_ANR_DELAY_MS;
+
+ /**
+ * How long the grace period is from starting an almost perceptible service to a successful
+ * binding before we stop considering it an almost perceptible service.
+ */
+ volatile long mServiceBindAlmostPerceptibleTimeoutMs =
+ DEFAULT_SERVICE_BIND_ALMOST_PERCEPTIBLE_TIMEOUT_MS;
+
+ /**
* Defines component aliases. Format
* ComponentName ":" ComponentName ( "," ComponentName ":" ComponentName )*
*/
@@ -913,6 +958,15 @@
case KEY_DEFER_BOOT_COMPLETED_BROADCAST:
updateDeferBootCompletedBroadcast();
break;
+ case KEY_SERVICE_START_FOREGROUND_TIMEOUT_MS:
+ updateServiceStartForegroundTimeoutMs();
+ break;
+ case KEY_SERVICE_START_FOREGROUND_ANR_DELAY_MS:
+ updateServiceStartForegroundAnrDealyMs();
+ break;
+ case KEY_SERVICE_BIND_ALMOST_PERCEPTIBLE_TIMEOUT_MS:
+ updateServiceBindAlmostPerceptibleTimeoutMs();
+ break;
case KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED:
updateNoKillCachedProcessesUntilBootCompleted();
break;
@@ -1141,6 +1195,9 @@
DEFAULT_MEMORY_INFO_THROTTLE_TIME);
TOP_TO_FGS_GRACE_DURATION = mParser.getDurationMillis(KEY_TOP_TO_FGS_GRACE_DURATION,
DEFAULT_TOP_TO_FGS_GRACE_DURATION);
+ TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION = mParser.getDurationMillis(
+ KEY_TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION,
+ DEFAULT_TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION);
MIN_CRASH_INTERVAL = mParser.getInt(KEY_MIN_CRASH_INTERVAL,
DEFAULT_MIN_CRASH_INTERVAL);
PENDINGINTENT_WARNING_THRESHOLD = mParser.getInt(KEY_PENDINGINTENT_WARNING_THRESHOLD,
@@ -1389,6 +1446,28 @@
DEFAULT_MAX_EMPTY_TIME_MILLIS);
}
+ private void updateServiceStartForegroundTimeoutMs() {
+ mServiceStartForegroundTimeoutMs = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_SERVICE_START_FOREGROUND_TIMEOUT_MS,
+ DEFAULT_SERVICE_START_FOREGROUND_TIMEOUT_MS);
+ }
+
+ private void updateServiceStartForegroundAnrDealyMs() {
+ mServiceStartForegroundAnrDelayMs = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_SERVICE_START_FOREGROUND_ANR_DELAY_MS,
+ DEFAULT_SERVICE_START_FOREGROUND_ANR_DELAY_MS);
+ }
+
+ private void updateServiceBindAlmostPerceptibleTimeoutMs() {
+ mServiceBindAlmostPerceptibleTimeoutMs = DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_SERVICE_BIND_ALMOST_PERCEPTIBLE_TIMEOUT_MS,
+ DEFAULT_SERVICE_BIND_ALMOST_PERCEPTIBLE_TIMEOUT_MS);
+ }
+
+
private long[] parseLongArray(@NonNull String key, @NonNull long[] def) {
final String val = DeviceConfig.getString(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
key, null);
@@ -1604,6 +1683,8 @@
pw.println(MEMORY_INFO_THROTTLE_TIME);
pw.print(" "); pw.print(KEY_TOP_TO_FGS_GRACE_DURATION); pw.print("=");
pw.println(TOP_TO_FGS_GRACE_DURATION);
+ pw.print(" "); pw.print(KEY_TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION); pw.print("=");
+ pw.println(TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION);
pw.print(" "); pw.print(KEY_MIN_CRASH_INTERVAL); pw.print("=");
pw.println(MIN_CRASH_INTERVAL);
pw.print(" "); pw.print(KEY_PROCESS_CRASH_COUNT_RESET_INTERVAL); pw.print("=");
@@ -1669,6 +1750,12 @@
pw.print("="); pw.println(mNoKillCachedProcessesPostBootCompletedDurationMillis);
pw.print(" "); pw.print(KEY_MAX_EMPTY_TIME_MILLIS);
pw.print("="); pw.println(mMaxEmptyTimeMillis);
+ pw.print(" "); pw.print(KEY_SERVICE_START_FOREGROUND_TIMEOUT_MS);
+ pw.print("="); pw.println(mServiceStartForegroundTimeoutMs);
+ pw.print(" "); pw.print(KEY_SERVICE_START_FOREGROUND_ANR_DELAY_MS);
+ pw.print("="); pw.println(mServiceStartForegroundAnrDelayMs);
+ pw.print(" "); pw.print(KEY_SERVICE_BIND_ALMOST_PERCEPTIBLE_TIMEOUT_MS);
+ pw.print("="); pw.println(mServiceBindAlmostPerceptibleTimeoutMs);
pw.println();
if (mOverrideMaxCachedProcesses >= 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c40f65f..450cfbb 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1536,6 +1536,7 @@
static final int IDLE_UIDS_MSG = 58;
static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
+ static final int SERVICE_FOREGROUND_TIMEOUT_ANR_MSG = 67;
static final int PUSH_TEMP_ALLOWLIST_UI_MSG = 68;
static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
@@ -1724,6 +1725,12 @@
case SERVICE_FOREGROUND_TIMEOUT_MSG: {
mServices.serviceForegroundTimeout((ServiceRecord) msg.obj);
} break;
+ case SERVICE_FOREGROUND_TIMEOUT_ANR_MSG: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ mServices.serviceForegroundTimeoutANR((ProcessRecord) args.arg1,
+ (String) args.arg2);
+ args.recycle();
+ } break;
case SERVICE_FOREGROUND_CRASH_MSG: {
SomeArgs args = (SomeArgs) msg.obj;
mServices.serviceForegroundCrash(
@@ -2942,6 +2949,27 @@
}
}
+ /**
+ * If the caller is an {@link Process#isSdkSandboxUid(int) SDK sandbox uid}, enforces that the
+ * SDK sandbox has permission to start or bind to a given service.
+ *
+ * @param intent the intent used to start or bind to the service.
+ * @throws IllegalStateException if {@link SdkSandboxManagerLocal} cannot be resolved.
+ * @throws SecurityException if the SDK sandbox is not allowed to bind to this service.
+ */
+ private void enforceAllowedToStartOrBindServiceIfSdkSandbox(Intent intent) {
+ if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
+ SdkSandboxManagerLocal sdkSandboxManagerLocal =
+ LocalManagerRegistry.getManager(SdkSandboxManagerLocal.class);
+ if (sdkSandboxManagerLocal != null) {
+ sdkSandboxManagerLocal.enforceAllowedToStartOrBindService(intent);
+ } else {
+ throw new IllegalStateException("SdkSandboxManagerLocal not found when checking"
+ + " whether SDK sandbox uid may start or bind to a service.");
+ }
+ }
+ }
+
@Override
public void setPackageScreenCompatMode(String packageName, int mode) {
mActivityTaskManager.setPackageScreenCompatMode(packageName, mode);
@@ -12356,6 +12384,7 @@
String callingFeatureId, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
+ enforceAllowedToStartOrBindServiceIfSdkSandbox(service);
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -12516,6 +12545,7 @@
String sdkSandboxClientAppPackage, String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("bindService");
+ enforceAllowedToStartOrBindServiceIfSdkSandbox(service);
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
@@ -12938,7 +12968,12 @@
public Intent registerReceiverWithFeature(IApplicationThread caller, String callerPackage,
String callerFeatureId, String receiverId, IIntentReceiver receiver,
IntentFilter filter, String permission, int userId, int flags) {
- enforceNotIsolatedOrSdkSandboxCaller("registerReceiver");
+ // Allow Sandbox process to register only unexported receivers.
+ if ((flags & Context.RECEIVER_NOT_EXPORTED) != 0) {
+ enforceNotIsolatedCaller("registerReceiver");
+ } else {
+ enforceNotIsolatedOrSdkSandboxCaller("registerReceiver");
+ }
ArrayList<Intent> stickyIntents = null;
ProcessRecord callerApp = null;
final boolean visibleToInstantApps
@@ -13636,6 +13671,16 @@
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
}
+ if (Process.isSdkSandboxUid(realCallingUid)) {
+ SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
+ SdkSandboxManagerLocal.class);
+ if (sdkSandboxManagerLocal == null) {
+ throw new IllegalStateException("SdkSandboxManagerLocal not found when sending"
+ + " a broadcast from an SDK sandbox uid.");
+ }
+ sdkSandboxManagerLocal.enforceAllowedToSendBroadcast(intent);
+ }
+
switch (action) {
case Intent.ACTION_MEDIA_SCANNER_SCAN_FILE:
UserManagerInternal umInternal = LocalServices.getService(
@@ -17258,8 +17303,8 @@
}
@Override
- public void deletePendingTopUid(int uid) {
- mPendingStartActivityUids.delete(uid);
+ public void deletePendingTopUid(int uid, long nowElapsed) {
+ mPendingStartActivityUids.delete(uid, nowElapsed);
}
@Override
@@ -17362,6 +17407,11 @@
}
@Override
+ public int getServiceStartForegroundTimeout() {
+ return mConstants.mServiceStartForegroundTimeoutMs;
+ }
+
+ @Override
public int getUidCapability(int uid) {
synchronized (ActivityManagerService.this) {
UidRecord uidRecord = mProcessList.getUidRecordLOSP(uid);
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 2b61e7f..5024a4a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -183,6 +183,7 @@
private boolean mAsync;
private BroadcastOptions mBroadcastOptions;
private boolean mShowSplashScreen;
+ private boolean mDismissKeyguardIfInsecure;
final boolean mDumping;
@@ -439,6 +440,8 @@
mAsync = true;
} else if (opt.equals("--splashscreen-show-icon")) {
mShowSplashScreen = true;
+ } else if (opt.equals("--dismiss-keyguard-if-insecure")) {
+ mDismissKeyguardIfInsecure = true;
} else {
return false;
}
@@ -583,6 +586,12 @@
}
options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
}
+ if (mDismissKeyguardIfInsecure) {
+ if (options == null) {
+ options = ActivityOptions.makeBasic();
+ }
+ options.setDismissKeyguardIfInsecure();
+ }
if (mWaitOption) {
result = mInternal.startActivityAndWait(null, SHELL_PACKAGE_NAME, null, intent,
mimeType, null, null, 0, mStartFlags, profilerInfo,
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 41ff083..b8fb9e8 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -1086,6 +1086,12 @@
}
final @RestrictionLevel int level = calcAppRestrictionLevel(
userId, uid, info.mPackageName, info.mStandbyBucket, false, false);
+ if (DEBUG_BG_RESTRICTION_CONTROLLER) {
+ Slog.i(TAG, "Proposed restriction level of " + info.mPackageName + "/"
+ + UserHandle.formatUid(uid) + ": "
+ + ActivityManager.restrictionLevelToName(level)
+ + " " + info.mStandbyBucket);
+ }
applyRestrictionLevel(info.mPackageName, uid, level,
info.mStandbyBucket, true, reason, subReason);
}
@@ -1185,6 +1191,25 @@
return level;
}
+ private static @RestrictionLevel int standbyBucketToRestrictionLevel(
+ @UsageStatsManager.StandbyBuckets int standbyBucket) {
+ switch (standbyBucket) {
+ case STANDBY_BUCKET_EXEMPTED:
+ return RESTRICTION_LEVEL_EXEMPTED;
+ case STANDBY_BUCKET_NEVER:
+ return RESTRICTION_LEVEL_BACKGROUND_RESTRICTED;
+ case STANDBY_BUCKET_ACTIVE:
+ case STANDBY_BUCKET_WORKING_SET:
+ case STANDBY_BUCKET_FREQUENT:
+ case STANDBY_BUCKET_RARE:
+ return RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
+ case STANDBY_BUCKET_RESTRICTED:
+ return RESTRICTION_LEVEL_RESTRICTED_BUCKET;
+ default:
+ return RESTRICTION_LEVEL_UNKNOWN;
+ }
+ }
+
/**
* Get the restriction level of the given UID, if it hosts multiple packages,
* return least restricted one (or if any of them is exempted).
@@ -1380,12 +1405,23 @@
int curBucket, boolean allowUpdateBucket, int reason, int subReason) {
int curLevel;
int prevReason;
+ final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal();
synchronized (mSettingsLock) {
curLevel = getRestrictionLevel(uid, pkgName);
if (curLevel == level) {
// Nothing to do.
return;
}
+ final int levelOfBucket = standbyBucketToRestrictionLevel(curBucket);
+ if (levelOfBucket == level) {
+ // If the standby bucket yield the same level, use the reason from standby bucket.
+ final int bucketReason = appStandbyInternal.getAppStandbyBucketReason(
+ pkgName, UserHandle.getUserId(uid), SystemClock.elapsedRealtime());
+ if (bucketReason != 0) {
+ reason = bucketReason & REASON_MAIN_MASK;
+ subReason = bucketReason & REASON_SUB_MASK;
+ }
+ }
if (DEBUG_BG_RESTRICTION_CONTROLLER) {
Slog.i(TAG, "Updating the restriction level of " + pkgName + "/"
+ UserHandle.formatUid(uid) + " from "
@@ -1393,7 +1429,6 @@
+ ActivityManager.restrictionLevelToName(level)
+ " reason=" + reason + ", subReason=" + subReason);
}
-
prevReason = mRestrictionSettings.getReason(pkgName, uid);
mRestrictionSettings.update(pkgName, uid, level, reason, subReason);
}
@@ -1401,7 +1436,6 @@
if (!allowUpdateBucket || curBucket == STANDBY_BUCKET_EXEMPTED) {
return;
}
- final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal();
if (level >= RESTRICTION_LEVEL_RESTRICTED_BUCKET
&& curLevel < RESTRICTION_LEVEL_RESTRICTED_BUCKET) {
if (!mConstantsObserver.mRestrictedBucketEnabled) {
@@ -1422,8 +1456,10 @@
final int index = mActiveUids.indexOfKey(uid, pkgName);
if (index >= 0) {
// It's currently active, enqueue it.
+ final int localReason = reason;
+ final int localSubReason = subReason;
mActiveUids.add(uid, pkgName, () -> appStandbyInternal.restrictApp(
- pkgName, UserHandle.getUserId(uid), reason, subReason));
+ pkgName, UserHandle.getUserId(uid), localReason, localSubReason));
doIt = false;
}
}
@@ -1841,9 +1877,6 @@
}
void handleUidInactive(int uid, boolean disabled) {
- if (!mConstantsObserver.mBgAutoRestrictedBucket) {
- return;
- }
final ArrayList<Runnable> pendingTasks = mTmpRunnables;
synchronized (mSettingsLock) {
final int index = mActiveUids.indexOfKey(uid);
@@ -1866,14 +1899,12 @@
}
void handleUidActive(int uid) {
- if (!mConstantsObserver.mBgAutoRestrictedBucket) {
- return;
- }
synchronized (mSettingsLock) {
final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal();
final int userId = UserHandle.getUserId(uid);
mRestrictionSettings.forEachPackageInUidLocked(uid, (pkgName, level, reason) -> {
- if (level == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) {
+ if (mConstantsObserver.mBgAutoRestrictedBucket
+ && level == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) {
mActiveUids.add(uid, pkgName, () -> appStandbyInternal.restrictApp(pkgName,
userId, reason & REASON_MAIN_MASK, reason & REASON_SUB_MASK));
} else {
diff --git a/services/core/java/com/android/server/am/BaseAppStateTracker.java b/services/core/java/com/android/server/am/BaseAppStateTracker.java
index 2f76e24..cb21a4b 100644
--- a/services/core/java/com/android/server/am/BaseAppStateTracker.java
+++ b/services/core/java/com/android/server/am/BaseAppStateTracker.java
@@ -16,7 +16,6 @@
package com.android.server.am;
-import static com.android.server.am.ActiveServices.SERVICE_START_FOREGROUND_TIMEOUT;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -362,7 +361,7 @@
}
long getServiceStartForegroundTimeout() {
- return SERVICE_START_FOREGROUND_TIMEOUT;
+ return mActivityManagerInternal.getServiceStartForegroundTimeout();
}
RoleManager getRoleManager() {
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index df792ee2..24e815e 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -112,6 +112,13 @@
ContentProviderHolder getContentProvider(IApplicationThread caller, String callingPackage,
String name, int userId, boolean stable) {
mService.enforceNotIsolatedCaller("getContentProvider");
+ if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
+ // TODO(b/226318628): for sdk sandbox processes only allow accessing CPs registered by
+ // the WebView apk.
+ Slog.w(TAG, "Sdk sandbox process " + Binder.getCallingUid()
+ + " is accessing content provider " + name
+ + ". This access will most likely be blocked in the future");
+ }
if (caller == null) {
String msg = "null IApplicationThread when getting content provider " + name;
Slog.w(TAG, msg);
@@ -630,7 +637,7 @@
return;
}
- mService.enforceNotIsolatedCaller("publishContentProviders");
+ mService.enforceNotIsolatedOrSdkSandboxCaller("publishContentProviders");
synchronized (mService) {
final ProcessRecord r = mService.getRecordForAppLOSP(caller);
if (DEBUG_MU) {
@@ -717,7 +724,7 @@
* Drop a content provider from a ProcessRecord's bookkeeping
*/
void removeContentProvider(IBinder connection, boolean stable) {
- mService.enforceNotIsolatedCaller("removeContentProvider");
+ mService.enforceNotIsolatedOrSdkSandboxCaller("removeContentProvider");
final long ident = Binder.clearCallingIdentity();
try {
ContentProviderConnection conn;
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 9626bbe..02206ff 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1254,7 +1254,7 @@
mService.mServices.foregroundServiceProcStateChangedLocked(uidRec);
}
}
- mService.mInternal.deletePendingTopUid(uidRec.getUid());
+ mService.mInternal.deletePendingTopUid(uidRec.getUid(), nowElapsed);
}
if (mLocalPowerManager != null) {
mLocalPowerManager.finishUidChanges();
@@ -1674,6 +1674,24 @@
}
}
+ // If the app was recently in the foreground and has expedited jobs running,
+ // allow it to get a higher rank in memory for some time, compared to other EJS and even
+ // foreground services so that it can finish performing any persistence/processing of
+ // in-memory state.
+ if (psr.hasTopStartedAlmostPerceptibleServices()
+ && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
+ && (state.getLastTopTime()
+ + mConstants.TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION > now
+ || state.getSetProcState() <= PROCESS_STATE_TOP)) {
+ adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
+ // This shall henceforth be called the "EJ" exemption, despite utilizing the
+ // ALMOST_PERCEPTIBLE flag to work.
+ state.setAdjType("top-ej-act");
+ if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
+ reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg for EJ: " + app);
+ }
+ }
+
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
|| procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
if (state.getForcingToImportant() != null) {
@@ -2854,8 +2872,7 @@
// To avoid some abuse patterns, we are going to be careful about what we consider
// to be an app interaction. Being the top activity doesn't count while the display
// is sleeping, nor do short foreground services.
- if (state.getCurProcState() <= PROCESS_STATE_TOP
- || state.getCurProcState() == PROCESS_STATE_BOUND_TOP) {
+ if (ActivityManager.isProcStateConsideredInteraction(state.getCurProcState())) {
isInteraction = true;
state.setFgInteractionTime(0);
} else if (state.getCurProcState() <= PROCESS_STATE_FOREGROUND_SERVICE) {
diff --git a/services/core/java/com/android/server/am/PendingStartActivityUids.java b/services/core/java/com/android/server/am/PendingStartActivityUids.java
index 455c75b..bd60057 100644
--- a/services/core/java/com/android/server/am/PendingStartActivityUids.java
+++ b/services/core/java/com/android/server/am/PendingStartActivityUids.java
@@ -55,9 +55,15 @@
return false;
}
- synchronized void delete(int uid) {
+ synchronized void delete(int uid, long nowElapsed) {
final Pair<Integer, Long> pendingPid = mPendingUids.get(uid);
if (pendingPid != null) {
+ if (nowElapsed < pendingPid.second) {
+ Slog.i(TAG,
+ "updateOomAdj start time is before than pendingPid added,"
+ + " don't delete it");
+ return;
+ }
final long delay = SystemClock.elapsedRealtime() - pendingPid.second;
if (delay >= 1000 /*ms*/) {
Slog.i(TAG,
@@ -87,4 +93,4 @@
synchronized boolean isPendingTopUid(int uid) {
return mPendingUids.get(uid) != null;
}
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/am/ProcessServiceRecord.java b/services/core/java/com/android/server/am/ProcessServiceRecord.java
index 8f77b87..6b748193 100644
--- a/services/core/java/com/android/server/am/ProcessServiceRecord.java
+++ b/services/core/java/com/android/server/am/ProcessServiceRecord.java
@@ -19,6 +19,7 @@
import android.app.ActivityManager;
import android.content.Context;
import android.os.IBinder;
+import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -42,6 +43,18 @@
private boolean mHasForegroundServices;
/**
+ * Running any services that are almost perceptible (started with
+ * {@link Context#BIND_ALMOST_PERCEPTIBLE} while the app was on TOP)?
+ */
+ private boolean mHasTopStartedAlmostPerceptibleServices;
+
+ /**
+ * The latest value of {@link ServiceRecord#lastTopAlmostPerceptibleBindRequestUptimeMs} among
+ * the currently running services.
+ */
+ private long mLastTopStartedAlmostPerceptibleBindRequestUptimeMs;
+
+ /**
* Service that applied current connectionGroup/Importance.
*/
private ServiceRecord mConnectionService;
@@ -146,6 +159,46 @@
mRepFgServiceTypes = foregroundServiceTypes;
}
+ void updateHasTopStartedAlmostPerceptibleServices() {
+ mHasTopStartedAlmostPerceptibleServices = false;
+ mLastTopStartedAlmostPerceptibleBindRequestUptimeMs = 0;
+ for (int s = mServices.size() - 1; s >= 0; --s) {
+ final ServiceRecord sr = mServices.valueAt(s);
+ mLastTopStartedAlmostPerceptibleBindRequestUptimeMs = Math.max(
+ mLastTopStartedAlmostPerceptibleBindRequestUptimeMs,
+ sr.lastTopAlmostPerceptibleBindRequestUptimeMs);
+ if (!mHasTopStartedAlmostPerceptibleServices && isAlmostPerceptible(sr)) {
+ mHasTopStartedAlmostPerceptibleServices = true;
+ }
+ }
+ }
+
+ private boolean isAlmostPerceptible(ServiceRecord record) {
+ if (record.lastTopAlmostPerceptibleBindRequestUptimeMs <= 0) {
+ return false;
+ }
+ final ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections =
+ record.getConnections();
+ for (int m = serviceConnections.size() - 1; m >= 0; --m) {
+ final ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(m);
+
+ for (int c = clist.size() - 1; c >= 0; --c) {
+ final ConnectionRecord cr = clist.get(c);
+ if ((cr.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ boolean hasTopStartedAlmostPerceptibleServices() {
+ return mHasTopStartedAlmostPerceptibleServices
+ || (mLastTopStartedAlmostPerceptibleBindRequestUptimeMs > 0
+ && SystemClock.uptimeMillis() - mLastTopStartedAlmostPerceptibleBindRequestUptimeMs
+ < mService.mConstants.mServiceBindAlmostPerceptibleTimeoutMs);
+ }
+
ServiceRecord getConnectionService() {
return mConnectionService;
}
@@ -243,6 +296,14 @@
if (added && record.serviceInfo != null) {
mApp.getWindowProcessController().onServiceStarted(record.serviceInfo);
}
+ if (record.lastTopAlmostPerceptibleBindRequestUptimeMs > 0) {
+ mLastTopStartedAlmostPerceptibleBindRequestUptimeMs = Math.max(
+ mLastTopStartedAlmostPerceptibleBindRequestUptimeMs,
+ record.lastTopAlmostPerceptibleBindRequestUptimeMs);
+ if (!mHasTopStartedAlmostPerceptibleServices) {
+ mHasTopStartedAlmostPerceptibleServices = isAlmostPerceptible(record);
+ }
+ }
return added;
}
@@ -253,7 +314,11 @@
* @return true if the service was removed, false otherwise.
*/
boolean stopService(ServiceRecord record) {
- return mServices.remove(record);
+ final boolean removed = mServices.remove(record);
+ if (record.lastTopAlmostPerceptibleBindRequestUptimeMs > 0) {
+ updateHasTopStartedAlmostPerceptibleServices();
+ }
+ return removed;
}
/**
@@ -261,6 +326,7 @@
*/
void stopAllServices() {
mServices.clear();
+ updateHasTopStartedAlmostPerceptibleServices();
}
/**
@@ -408,6 +474,13 @@
pw.print(prefix); pw.print("mHasForegroundServices="); pw.print(mHasForegroundServices);
pw.print(" forcingToImportant="); pw.println(mApp.mState.getForcingToImportant());
}
+ if (mHasTopStartedAlmostPerceptibleServices
+ || mLastTopStartedAlmostPerceptibleBindRequestUptimeMs > 0) {
+ pw.print(prefix); pw.print("mHasTopStartedAlmostPerceptibleServices=");
+ pw.print(mHasTopStartedAlmostPerceptibleServices);
+ pw.print(" mLastTopStartedAlmostPerceptibleBindRequestUptimeMs=");
+ pw.println(mLastTopStartedAlmostPerceptibleBindRequestUptimeMs);
+ }
if (mHasClientActivities || mHasAboveClient || mTreatLikeActivity) {
pw.print(prefix); pw.print("hasClientActivities="); pw.print(mHasClientActivities);
pw.print(" hasAboveClient="); pw.print(mHasAboveClient);
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 795311f..639f56c 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -24,6 +24,7 @@
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.IApplicationThread;
import android.app.Notification;
@@ -141,6 +142,12 @@
int pendingConnectionGroup; // To be filled in to ProcessRecord once it connects
int pendingConnectionImportance; // To be filled in to ProcessRecord once it connects
+ /**
+ * The last time (in uptime timebase) a bind request was made with BIND_ALMOST_PERCEPTIBLE for
+ * this service while on TOP.
+ */
+ long lastTopAlmostPerceptibleBindRequestUptimeMs;
+
// any current binding to this service has BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS flag?
private boolean mIsAllowedBgActivityStartsByBinding;
// is this service currently allowed to start activities from background by providing
@@ -713,6 +720,7 @@
}
}
+ @NonNull
ArrayMap<IBinder, ArrayList<ConnectionRecord>> getConnections() {
return connections;
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 8795347..b886196 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -107,6 +107,7 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.widget.LockPatternUtils;
+import com.android.server.FactoryResetter;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService.UserCompletedEventType;
@@ -1797,6 +1798,10 @@
Slogf.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
return false;
}
+ if (FactoryResetter.isFactoryResetting()) {
+ Slogf.w(TAG, "Cannot switch to User #" + targetUserId + ": factory reset in progress");
+ return false;
+ }
boolean userSwitchUiEnabled;
synchronized (mLock) {
if (!mInitialized) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 270a61b..1a482e4 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -252,8 +252,8 @@
return;
}
}
- setCommunicationRouteForClient(
- cb, pid, device, BtHelper.SCO_MODE_UNDEFINED, eventSource);
+ postSetCommunicationRouteForClient(new CommunicationClientInfo(
+ cb, pid, device, BtHelper.SCO_MODE_UNDEFINED, eventSource));
}
}
}
@@ -283,8 +283,8 @@
return false;
}
}
- setCommunicationRouteForClient(
- cb, pid, deviceAttr, BtHelper.SCO_MODE_UNDEFINED, eventSource);
+ postSetCommunicationRouteForClient(new CommunicationClientInfo(
+ cb, pid, deviceAttr, BtHelper.SCO_MODE_UNDEFINED, eventSource));
}
}
return true;
@@ -348,26 +348,35 @@
}
/**
- * Returns the device currently requested for communication use case.
- * If the current audio mode owner is in the communication route client list,
- * use this preference.
- * Otherwise use first client's preference (first client corresponds to latest request).
- * null is returned if no client is in the list.
- * @return AudioDeviceAttributes the requested device for communication.
+ * Returns the communication client with the highest priority:
+ * - 1) the client which is currently also controlling the audio mode
+ * - 2) the first client in the stack if there is no audio mode owner
+ * - 3) no client otherwise
+ * @return CommunicationRouteClient the client driving the communication use case routing.
*/
-
@GuardedBy("mDeviceStateLock")
- private AudioDeviceAttributes requestedCommunicationDevice() {
- AudioDeviceAttributes device = null;
- for (CommunicationRouteClient cl : mCommunicationRouteClients) {
- if (cl.getPid() == mModeOwnerPid) {
- device = cl.getDevice();
+ private CommunicationRouteClient topCommunicationRouteClient() {
+ for (CommunicationRouteClient crc : mCommunicationRouteClients) {
+ if (crc.getPid() == mModeOwnerPid) {
+ return crc;
}
}
if (!mCommunicationRouteClients.isEmpty() && mModeOwnerPid == 0) {
- device = mCommunicationRouteClients.get(0).getDevice();
+ return mCommunicationRouteClients.get(0);
}
+ return null;
+ }
+ /**
+ * Returns the device currently requested for communication use case.
+ * Use the device requested by the communication route client selected by
+ * {@link #topCommunicationRouteClient()} if any or none otherwise.
+ * @return AudioDeviceAttributes the requested device for communication.
+ */
+ @GuardedBy("mDeviceStateLock")
+ private AudioDeviceAttributes requestedCommunicationDevice() {
+ CommunicationRouteClient crc = topCommunicationRouteClient();
+ AudioDeviceAttributes device = crc != null ? crc.getDevice() : null;
if (AudioService.DEBUG_COMM_RTE) {
Log.v(TAG, "requestedCommunicationDevice, device: "
+ device + " mode owner pid: " + mModeOwnerPid);
@@ -710,7 +719,7 @@
}
synchronized (mDeviceStateLock) {
mBluetoothScoOn = on;
- sendLMsgNoDelay(MSG_L_UPDATE_COMMUNICATION_ROUTE, SENDMSG_QUEUE, eventSource);
+ postUpdateCommunicationRouteClient(eventSource);
}
}
@@ -770,7 +779,9 @@
synchronized (mDeviceStateLock) {
AudioDeviceAttributes device =
new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, "");
- setCommunicationRouteForClient(cb, pid, device, scoAudioMode, eventSource);
+
+ postSetCommunicationRouteForClient(new CommunicationClientInfo(
+ cb, pid, device, scoAudioMode, eventSource));
}
}
}
@@ -788,8 +799,8 @@
if (client == null || !client.requestsBluetoothSco()) {
return;
}
- setCommunicationRouteForClient(
- cb, pid, null, BtHelper.SCO_MODE_UNDEFINED, eventSource);
+ postSetCommunicationRouteForClient(new CommunicationClientInfo(
+ cb, pid, null, BtHelper.SCO_MODE_UNDEFINED, eventSource));
}
}
}
@@ -990,6 +1001,61 @@
MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET, SENDMSG_QUEUE, capturePreset);
}
+ /*package*/ void postUpdateCommunicationRouteClient(String eventSource) {
+ sendLMsgNoDelay(MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT, SENDMSG_QUEUE, eventSource);
+ }
+
+ /*package*/ void postSetCommunicationRouteForClient(CommunicationClientInfo info) {
+ sendLMsgNoDelay(MSG_L_SET_COMMUNICATION_ROUTE_FOR_CLIENT, SENDMSG_QUEUE, info);
+ }
+
+ /*package*/ void postScoAudioStateChanged(int state) {
+ sendIMsgNoDelay(MSG_I_SCO_AUDIO_STATE_CHANGED, SENDMSG_QUEUE, state);
+ }
+
+ /*package*/ static final class CommunicationClientInfo {
+ final @NonNull IBinder mCb;
+ final int mPid;
+ final @NonNull AudioDeviceAttributes mDevice;
+ final int mScoAudioMode;
+ final @NonNull String mEventSource;
+
+ CommunicationClientInfo(@NonNull IBinder cb, int pid, @NonNull AudioDeviceAttributes device,
+ int scoAudioMode, @NonNull String eventSource) {
+ mCb = cb;
+ mPid = pid;
+ mDevice = device;
+ mScoAudioMode = scoAudioMode;
+ mEventSource = eventSource;
+ }
+
+ // redefine equality op so we can match messages intended for this client
+ @Override
+ public boolean equals(Object o) {
+ if (o == null) {
+ return false;
+ }
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof CommunicationClientInfo)) {
+ return false;
+ }
+
+ return mCb.equals(((CommunicationClientInfo) o).mCb)
+ && mPid == ((CommunicationClientInfo) o).mPid;
+ }
+
+ @Override
+ public String toString() {
+ return "CommunicationClientInfo mCb=" + mCb.toString()
+ +"mPid=" + mPid
+ +"mDevice=" + mDevice.toString()
+ +"mScoAudioMode=" + mScoAudioMode
+ +"mEventSource=" + mEventSource;
+ }
+ }
+
//---------------------------------------------------------------------
// Method forwarding between the helper classes (BtHelper, AudioDeviceInventory)
// only call from a "handle"* method or "on"* method
@@ -1265,18 +1331,30 @@
synchronized (mDeviceStateLock) {
mModeOwnerPid = msg.arg1;
if (msg.arg2 != AudioSystem.MODE_RINGTONE) {
- onUpdateCommunicationRoute("setNewModeOwner");
+ onUpdateCommunicationRouteClient("setNewModeOwner");
}
}
}
break;
- case MSG_L_COMMUNICATION_ROUTE_CLIENT_DIED:
+
+ case MSG_L_SET_COMMUNICATION_ROUTE_FOR_CLIENT:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
- onCommunicationRouteClientDied((CommunicationRouteClient) msg.obj);
+ CommunicationClientInfo info = (CommunicationClientInfo) msg.obj;
+ setCommunicationRouteForClient(info.mCb, info.mPid, info.mDevice,
+ info.mScoAudioMode, info.mEventSource);
}
}
break;
+
+ case MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT:
+ synchronized (mSetModeLock) {
+ synchronized (mDeviceStateLock) {
+ onUpdateCommunicationRouteClient((String) msg.obj);
+ }
+ }
+ break;
+
case MSG_L_UPDATE_COMMUNICATION_ROUTE:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
@@ -1284,6 +1362,23 @@
}
}
break;
+
+ case MSG_L_COMMUNICATION_ROUTE_CLIENT_DIED:
+ synchronized (mSetModeLock) {
+ synchronized (mDeviceStateLock) {
+ onCommunicationRouteClientDied((CommunicationRouteClient) msg.obj);
+ }
+ }
+ break;
+
+ case MSG_I_SCO_AUDIO_STATE_CHANGED:
+ synchronized (mSetModeLock) {
+ synchronized (mDeviceStateLock) {
+ mBtHelper.onScoAudioStateChanged(msg.arg1);
+ }
+ }
+ break;
+
case MSG_TOGGLE_HDMI:
synchronized (mDeviceStateLock) {
mDeviceInventory.onToggleHdmi();
@@ -1437,6 +1532,9 @@
private static final int MSG_L_UPDATE_COMMUNICATION_ROUTE = 39;
private static final int MSG_IL_SET_PREF_DEVICES_FOR_STRATEGY = 40;
private static final int MSG_I_REMOVE_PREF_DEVICES_FOR_STRATEGY = 41;
+ private static final int MSG_L_SET_COMMUNICATION_ROUTE_FOR_CLIENT = 42;
+ private static final int MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT = 43;
+ private static final int MSG_I_SCO_AUDIO_STATE_CHANGED = 44;
private static final int MSG_L_BT_ACTIVE_DEVICE_CHANGE_EXT = 45;
//
@@ -1679,9 +1777,8 @@
return;
}
Log.w(TAG, "Communication client died");
- setCommunicationRouteForClient(
- client.getBinder(), client.getPid(), null, BtHelper.SCO_MODE_UNDEFINED,
- "onCommunicationRouteClientDied");
+ removeCommunicationRouteClient(client.getBinder(), true);
+ onUpdateCommunicationRouteClient("onCommunicationRouteClientDied");
}
/**
@@ -1735,11 +1832,31 @@
AudioSystem.setParameters("BT_SCO=on");
}
if (preferredCommunicationDevice == null) {
- postRemovePreferredDevicesForStrategy(mCommunicationStrategyId);
+ removePreferredDevicesForStrategySync(mCommunicationStrategyId);
} else {
- postSetPreferredDevicesForStrategy(
+ setPreferredDevicesForStrategySync(
mCommunicationStrategyId, Arrays.asList(preferredCommunicationDevice));
}
+ onUpdatePhoneStrategyDevice(preferredCommunicationDevice);
+ }
+
+ /**
+ * Select new communication device from communication route client at the top of the stack
+ * and restore communication route including restarting SCO audio if needed.
+ */
+ // @GuardedBy("mSetModeLock")
+ @GuardedBy("mDeviceStateLock")
+ private void onUpdateCommunicationRouteClient(String eventSource) {
+ onUpdateCommunicationRoute(eventSource);
+ CommunicationRouteClient crc = topCommunicationRouteClient();
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG, "onUpdateCommunicationRouteClient, crc: "
+ + crc + " eventSource: " + eventSource);
+ }
+ if (crc != null) {
+ setCommunicationRouteForClient(crc.getBinder(), crc.getPid(), crc.getDevice(),
+ BtHelper.SCO_MODE_UNDEFINED, eventSource);
+ }
}
private void onUpdatePhoneStrategyDevice(AudioDeviceAttributes device) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 0e29041..69b75e6 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1154,6 +1154,7 @@
mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address),
new DeviceInfo(device, name, address, AudioSystem.AUDIO_FORMAT_DEFAULT));
mDeviceBroker.postAccessoryPlugMediaUnmute(device);
+ setCurrentAudioRouteNameIfPossible(name, /*fromA2dp=*/false);
}
if (streamType == AudioSystem.STREAM_DEFAULT) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index a68fc05..d775581 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -78,6 +78,7 @@
import android.media.AudioAttributes.AttributeSystemUsage;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
+import android.media.AudioDeviceVolumeManager;
import android.media.AudioFocusInfo;
import android.media.AudioFocusRequest;
import android.media.AudioFormat;
@@ -154,6 +155,7 @@
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.AndroidRuntimeException;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IntArray;
import android.util.Log;
@@ -627,6 +629,47 @@
AudioSystem.DEVICE_OUT_HDMI_ARC,
AudioSystem.DEVICE_OUT_HDMI_EARC
));
+
+ // Devices where the framework sends a full scale audio signal, and controls the volume of
+ // the external audio system separately.
+ Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>();
+
+ /**
+ * Stores information about a device using absolute volume behavior.
+ */
+ private static final class AbsoluteVolumeDeviceInfo {
+ private final AudioDeviceAttributes mDevice;
+ private final List<VolumeInfo> mVolumeInfos;
+ private final IAudioDeviceVolumeDispatcher mCallback;
+ private final boolean mHandlesVolumeAdjustment;
+
+ private AbsoluteVolumeDeviceInfo(AudioDeviceAttributes device, List<VolumeInfo> volumeInfos,
+ IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment) {
+ this.mDevice = device;
+ this.mVolumeInfos = volumeInfos;
+ this.mCallback = callback;
+ this.mHandlesVolumeAdjustment = handlesVolumeAdjustment;
+ }
+
+ /**
+ * Given a stream type, returns a matching VolumeInfo.
+ */
+ @Nullable
+ private VolumeInfo getMatchingVolumeInfoForStream(int streamType) {
+ for (VolumeInfo volumeInfo : mVolumeInfos) {
+ boolean streamTypeMatches = volumeInfo.hasStreamType()
+ && volumeInfo.getStreamType() == streamType;
+ boolean volumeGroupMatches = volumeInfo.hasVolumeGroup()
+ && Arrays.stream(volumeInfo.getVolumeGroup().getLegacyStreamTypes())
+ .anyMatch(s -> s == streamType);
+ if (streamTypeMatches || volumeGroupMatches) {
+ return volumeInfo;
+ }
+ }
+ return null;
+ }
+ }
+
// Devices for the which use the "absolute volume" concept (framework sends audio signal
// full scale, and volume control separately) and can be used for multiple use cases reflected
// by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
@@ -1325,14 +1368,18 @@
mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
if (mRm != null) {
mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
- updateAssistantUId(true);
+ synchronized (mSettingsLock) {
+ updateAssistantUIdLocked(/* forceUpdate= */ true);
+ }
}
}
@Override
public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
if (RoleManager.ROLE_ASSISTANT.equals(roleName)) {
- updateAssistantUId(false);
+ synchronized (mSettingsLock) {
+ updateAssistantUIdLocked(/* forceUpdate= */ false);
+ }
}
}
@@ -1431,7 +1478,7 @@
sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
sendEnabledSurroundFormats(mContentResolver, true);
AudioSystem.setRttEnabled(mRttEnabled);
- updateAssistantServicesUidsLocked();
+ resetAssistantServicesUidsLocked();
}
synchronized (mAccessibilityServiceUidsLock) {
@@ -1560,6 +1607,12 @@
}
@GuardedBy("mSettingsLock")
+ private void resetAssistantServicesUidsLocked() {
+ mAssistantUids.clear();
+ updateAssistantUIdLocked(/* forceUpdate= */ true);
+ }
+
+ @GuardedBy("mSettingsLock")
private void updateAssistantServicesUidsLocked() {
int[] assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
AudioSystem.setAssistantServicesUids(assistantUids);
@@ -2343,7 +2396,7 @@
}
@GuardedBy("mSettingsLock")
- private void updateAssistantUId(boolean forceUpdate) {
+ private void updateAssistantUIdLocked(boolean forceUpdate) {
int assistantUid = INVALID_UID;
// Consider assistants in the following order of priority:
// 1) apk in assistant role
@@ -2441,7 +2494,7 @@
readDockAudioSettings(cr);
sendEncodedSurroundMode(cr, "readPersistedSettings");
sendEnabledSurroundFormats(cr, true);
- updateAssistantUId(true);
+ updateAssistantUIdLocked(/* forceUpdate= */ true);
resetActiveAssistantUidsLocked();
AudioSystem.setRttEnabled(mRttEnabled);
}
@@ -2509,17 +2562,44 @@
return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex());
}
- private int rescaleIndex(int index, int srcStream, int dstStream) {
- int srcRange = getIndexRange(srcStream);
- int dstRange = getIndexRange(dstStream);
- if (srcRange == 0) {
- Log.e(TAG, "rescaleIndex : index range should not be zero");
+ private int rescaleIndex(VolumeInfo volumeInfo, int dstStream) {
+ if (volumeInfo.getVolumeIndex() == VolumeInfo.INDEX_NOT_SET
+ || volumeInfo.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
+ || volumeInfo.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
+ Log.e(TAG, "rescaleIndex: volumeInfo has invalid index or range");
return mStreamStates[dstStream].getMinIndex();
}
+ return rescaleIndex(volumeInfo.getVolumeIndex(),
+ volumeInfo.getMinVolumeIndex(), volumeInfo.getMaxVolumeIndex(),
+ mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex());
+ }
- return mStreamStates[dstStream].getMinIndex()
- + ((index - mStreamStates[srcStream].getMinIndex()) * dstRange + srcRange / 2)
- / srcRange;
+ private int rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo) {
+ int dstMin = dstVolumeInfo.getMinVolumeIndex();
+ int dstMax = dstVolumeInfo.getMaxVolumeIndex();
+ // Don't rescale index if the VolumeInfo is missing a min or max index
+ if (dstMin == VolumeInfo.INDEX_NOT_SET || dstMax == VolumeInfo.INDEX_NOT_SET) {
+ return index;
+ }
+ return rescaleIndex(index,
+ mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(),
+ dstMin, dstMax);
+ }
+
+ private int rescaleIndex(int index, int srcStream, int dstStream) {
+ return rescaleIndex(index,
+ mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(),
+ mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex());
+ }
+
+ private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) {
+ int srcRange = srcMax - srcMin;
+ int dstRange = dstMax - dstMin;
+ if (srcRange == 0) {
+ Log.e(TAG, "rescaleIndex : index range should not be zero");
+ return dstMin;
+ }
+ return dstMin + ((index - srcMin) * dstRange + srcRange / 2) / srcRange;
}
private int rescaleStep(int step, int srcStream, int dstStream) {
@@ -2752,26 +2832,19 @@
return mAudioSystem.getDevicesForAttributes(attributes, forVolume);
}
- /** Indicates no special treatment in the handling of the volume adjustement */
- private static final int VOL_ADJUST_NORMAL = 0;
- /** Indicates the start of a volume adjustement */
- private static final int VOL_ADJUST_START = 1;
- /** Indicates the end of a volume adjustment */
- private static final int VOL_ADJUST_END = 2;
-
// pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP,
// KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE
public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv,
@NonNull String callingPackage, @NonNull String caller) {
- int keyEventMode = VOL_ADJUST_NORMAL;
+ int keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_NORMAL;
if (isOnTv) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
- keyEventMode = VOL_ADJUST_START;
+ keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_START;
} else { // may catch more than ACTION_UP, but will end vol adjustement
// the vol key is either released (ACTION_UP), or multiple keys are pressed
// (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end
// the repeated volume adjustement
- keyEventMode = VOL_ADJUST_END;
+ keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_END;
}
} else if (event.getAction() != KeyEvent.ACTION_DOWN) {
return;
@@ -2796,7 +2869,7 @@
adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE,
AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
Binder.getCallingUid(), Binder.getCallingPid(),
- true, VOL_ADJUST_NORMAL);
+ true, AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
}
break;
default:
@@ -2941,7 +3014,7 @@
direction/*val1*/, flags/*val2*/, callingPackage));
adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
Binder.getCallingUid(), Binder.getCallingPid(), attributionTag,
- callingHasAudioSettingsPermission(), VOL_ADJUST_NORMAL);
+ callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
}
protected void adjustStreamVolume(int streamType, int direction, int flags,
@@ -3074,8 +3147,19 @@
}
int oldIndex = mStreamStates[streamType].getIndex(device);
- if (adjustVolume
- && (direction != AudioManager.ADJUST_SAME) && (keyEventMode != VOL_ADJUST_END)) {
+ // Check if the volume adjustment should be handled by an absolute volume controller instead
+ if (isAbsoluteVolumeDevice(device)
+ && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
+ AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
+ if (info.mHandlesVolumeAdjustment) {
+ dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction,
+ keyEventMode);
+ return;
+ }
+ }
+
+ if (adjustVolume && (direction != AudioManager.ADJUST_SAME)
+ && (keyEventMode != AudioDeviceVolumeManager.ADJUST_MODE_END)) {
mAudioHandler.removeMessages(MSG_UNMUTE_STREAM);
if (isMuteAdjust && !mFullVolumeDevices.contains(device)) {
@@ -3136,6 +3220,10 @@
+ newIndex + "stream=" + streamType);
}
mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
+ } else if (isAbsoluteVolumeDevice(device)
+ && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
+ AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
+ dispatchAbsoluteVolumeChanged(streamType, info, newIndex);
}
if (device == AudioSystem.DEVICE_OUT_BLE_HEADSET
@@ -3201,14 +3289,14 @@
final long ident = Binder.clearCallingIdentity();
try {
switch (keyEventMode) {
- case VOL_ADJUST_NORMAL:
+ case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL:
fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true);
fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false);
break;
- case VOL_ADJUST_START:
+ case AudioDeviceVolumeManager.ADJUST_MODE_START:
fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true);
break;
- case VOL_ADJUST_END:
+ case AudioDeviceVolumeManager.ADJUST_MODE_END:
fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false);
break;
default:
@@ -3794,6 +3882,11 @@
+ "stream=" + streamType);
}
mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
+ } else if (isAbsoluteVolumeDevice(device)
+ && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) {
+ AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
+
+ dispatchAbsoluteVolumeChanged(streamType, info, index);
}
if (device == AudioSystem.DEVICE_OUT_BLE_HEADSET
@@ -3872,6 +3965,38 @@
return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
}
+ private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo,
+ int index) {
+ VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
+ if (volumeInfo != null) {
+ try {
+ deviceInfo.mCallback.dispatchDeviceVolumeChanged(deviceInfo.mDevice,
+ new VolumeInfo.Builder(volumeInfo)
+ .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
+ .build());
+ } catch (RemoteException e) {
+ Log.w(TAG, "Couldn't dispatch absolute volume behavior volume change");
+ }
+ }
+ }
+
+ private void dispatchAbsoluteVolumeAdjusted(int streamType,
+ AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode) {
+ VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
+ if (volumeInfo != null) {
+ try {
+ deviceInfo.mCallback.dispatchDeviceVolumeAdjusted(deviceInfo.mDevice,
+ new VolumeInfo.Builder(volumeInfo)
+ .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
+ .build(),
+ direction,
+ mode);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Couldn't dispatch absolute volume behavior volume adjustment");
+ }
+ }
+ }
+
// No ringer or zen muted stream volumes can be changed unless it'll exit dnd
private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
@@ -4007,6 +4132,14 @@
if (streamType == AudioSystem.STREAM_MUSIC) {
flags = updateFlagsForTvPlatform(flags);
+ synchronized (mHdmiClientLock) {
+ // Don't display volume UI on a TV Playback device when using absolute volume
+ if (mHdmiCecVolumeControlEnabled && mHdmiPlaybackClient != null
+ && (isAbsoluteVolumeDevice(device)
+ || isA2dpAbsoluteVolumeDevice(device))) {
+ flags &= ~AudioManager.FLAG_SHOW_UI;
+ }
+ }
if (isFullVolumeDevice(device)) {
flags &= ~AudioManager.FLAG_SHOW_UI;
}
@@ -5183,7 +5316,8 @@
// direction and stream type swap here because the public
// adjustSuggested has a different order than the other methods.
adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName,
- uid, pid, hasAudioSettingsPermission(uid, pid), VOL_ADJUST_NORMAL);
+ uid, pid, hasAudioSettingsPermission(uid, pid),
+ AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
}
/** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */
@@ -5203,7 +5337,8 @@
}
adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid,
- null, hasAudioSettingsPermission(uid, pid), VOL_ADJUST_NORMAL);
+ null, hasAudioSettingsPermission(uid, pid),
+ AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
}
/** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */
@@ -6423,15 +6558,16 @@
/**
* @see AudioDeviceVolumeManager#setDeviceAbsoluteMultiVolumeBehavior
- * @param cb
- * @param attr
- * @param volumes
+ *
+ * @param register Whether the listener is to be registered or unregistered. If false, the
+ * device adopts variable volume behavior.
*/
@RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING,
android.Manifest.permission.BLUETOOTH_PRIVILEGED })
public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register,
IAudioDeviceVolumeDispatcher cb, String packageName,
- AudioDeviceAttributes device, List<VolumeInfo> volumes) {
+ AudioDeviceAttributes device, List<VolumeInfo> volumes,
+ boolean handlesVolumeAdjustment) {
// verify permissions
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
!= PackageManager.PERMISSION_GRANTED
@@ -6444,12 +6580,44 @@
Objects.requireNonNull(device);
Objects.requireNonNull(volumes);
- // current implementation maps this call to existing abs volume API of AudioManager
- // TODO implement the volume/device listener through IAudioDeviceVolumeDispatcher
- final int volumeBehavior = volumes.size() == 1
- ? AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE
- : AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE;
- setDeviceVolumeBehavior(device, volumeBehavior, packageName);
+ int deviceOut = device.getInternalType();
+ if (register) {
+ AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo(
+ device, volumes, cb, handlesVolumeAdjustment);
+ boolean volumeBehaviorChanged =
+ removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut)
+ | removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut)
+ | (addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info) == null);
+ if (volumeBehaviorChanged) {
+ dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+ }
+ // Update stream volumes to the given device, if specified in a VolumeInfo.
+ // Mute state is not updated because it is stream-wide - the only way to mute a
+ // stream's output to a particular device is to set the volume index to zero.
+ for (VolumeInfo volumeInfo : volumes) {
+ if (volumeInfo.getVolumeIndex() != VolumeInfo.INDEX_NOT_SET
+ && volumeInfo.getMinVolumeIndex() != VolumeInfo.INDEX_NOT_SET
+ && volumeInfo.getMaxVolumeIndex() != VolumeInfo.INDEX_NOT_SET) {
+ if (volumeInfo.hasStreamType()) {
+ setStreamVolumeInt(volumeInfo.getStreamType(),
+ rescaleIndex(volumeInfo, volumeInfo.getStreamType()),
+ deviceOut, false /*force*/, packageName,
+ true /*hasModifyAudioSettings*/);
+ } else {
+ for (int streamType : volumeInfo.getVolumeGroup().getLegacyStreamTypes()) {
+ setStreamVolumeInt(streamType, rescaleIndex(volumeInfo, streamType),
+ deviceOut, false /*force*/, packageName,
+ true /*hasModifyAudioSettings*/);
+ }
+ }
+ }
+ }
+ } else {
+ boolean wasAbsVol = removeAudioSystemDeviceOutFromAbsVolumeDevices(deviceOut) != null;
+ if (wasAbsVol) {
+ dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE);
+ }
+ }
}
/**
@@ -6486,17 +6654,23 @@
case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
volumeBehaviorChanged |=
removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
- | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut);
+ | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
+ | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
+ != null);
break;
case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED:
volumeBehaviorChanged |=
removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
- | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut);
+ | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut)
+ | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
+ != null);
break;
case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL:
volumeBehaviorChanged |=
addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut)
- | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut);
+ | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
+ | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
+ != null);
break;
case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
@@ -6545,17 +6719,17 @@
// setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the
// current volume behavior.
- if ((mFullVolumeDevices.contains(audioSystemDeviceOut))) {
+ if (mFullVolumeDevices.contains(audioSystemDeviceOut)) {
return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL;
}
- if ((mFixedVolumeDevices.contains(audioSystemDeviceOut))) {
+ if (mFixedVolumeDevices.contains(audioSystemDeviceOut)) {
return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED;
}
- if ((mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut))) {
+ if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) {
return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE;
}
- if (audioSystemDeviceOut == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP
- && mAvrcpAbsVolSupported) {
+ if (isAbsoluteVolumeDevice(audioSystemDeviceOut)
+ || isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut)) {
return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
}
return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE;
@@ -7320,8 +7494,7 @@
int index;
if (isFullyMuted()) {
index = 0;
- } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
- && mAvrcpAbsVolSupported) {
+ } else if (isAbsoluteVolumeDevice(device) || isA2dpAbsoluteVolumeDevice(device)) {
index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
} else if (isFullVolumeDevice(device)) {
index = (mIndexMax + 5)/10;
@@ -7342,8 +7515,8 @@
if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
if (isFullyMuted()) {
index = 0;
- } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
- && mAvrcpAbsVolSupported) {
+ } else if (isAbsoluteVolumeDevice(device)
+ || isA2dpAbsoluteVolumeDevice(device)) {
index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
} else if (isFullVolumeDevice(device)) {
index = (mIndexMax + 5)/10;
@@ -7762,8 +7935,9 @@
// Make sure volume is also maxed out on A2DP device for aliased stream
// that may have a different device selected
int streamDevice = getDeviceForStream(streamType);
- if ((device != streamDevice) && mAvrcpAbsVolSupported
- && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)) {
+ if ((device != streamDevice)
+ && (isAbsoluteVolumeDevice(device)
+ || isA2dpAbsoluteVolumeDevice(device))) {
mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
}
mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
@@ -8153,7 +8327,7 @@
updateMasterBalance(mContentResolver);
updateEncodedSurroundOutput();
sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
- updateAssistantUId(false);
+ updateAssistantUIdLocked(/* forceUpdate= */ false);
}
}
@@ -9688,6 +9862,8 @@
pw.print(" mUseFixedVolume="); pw.println(mUseFixedVolume);
pw.print(" mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
pw.print(" mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices));
+ pw.print(" mAbsoluteVolumeDevices.keySet()="); pw.println(dumpDeviceTypes(
+ mAbsoluteVolumeDeviceInfoMap.keySet()));
pw.print(" mExtVolumeController="); pw.println(mExtVolumeController);
pw.print(" mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient);
pw.print(" mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient);
@@ -11489,6 +11665,23 @@
return mFullVolumeDevices.contains(deviceType);
}
+ /**
+ * Returns whether the input device uses absolute volume behavior. This is distinct
+ * from Bluetooth A2DP absolute volume behavior ({@link #isA2dpAbsoluteVolumeDevice}).
+ */
+ private boolean isAbsoluteVolumeDevice(int deviceType) {
+ return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType);
+ }
+
+ /**
+ * Returns whether the input device is a Bluetooth A2dp device that uses absolute volume
+ * behavior. This is distinct from the general implementation of absolute volume behavior
+ * ({@link #isAbsoluteVolumeDevice}).
+ */
+ private boolean isA2dpAbsoluteVolumeDevice(int deviceType) {
+ return mAvrcpAbsVolSupported && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType);
+ }
+
//====================
// Helper functions for {set,get}DeviceVolumeBehavior
//====================
@@ -11581,6 +11774,24 @@
return mFullVolumeDevices.remove(audioSystemDeviceOut);
}
+ private AbsoluteVolumeDeviceInfo addAudioSystemDeviceOutToAbsVolumeDevices(
+ int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
+ + " from mAbsoluteVolumeDeviceInfoMap");
+ }
+ return mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info);
+ }
+
+ private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices(
+ int audioSystemDeviceOut) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
+ + " from mAbsoluteVolumeDeviceInfoMap");
+ }
+ return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut);
+ }
+
//====================
// Helper functions for app ops
//====================
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 49a935e..d10ed55 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -104,7 +104,7 @@
// SCO audio mode is virtual voice call (BluetoothHeadset.startScoUsingVirtualVoiceCall())
/*package*/ static final int SCO_MODE_VIRTUAL_CALL = 0;
// SCO audio mode is Voice Recognition (BluetoothHeadset.startVoiceRecognition())
- private static final int SCO_MODE_VR = 2;
+ private static final int SCO_MODE_VR = 2;
// max valid SCO audio mode values
private static final int SCO_MODE_MAX = 2;
@@ -305,69 +305,77 @@
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
setBtScoActiveDevice(btDevice);
} else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
- boolean broadcast = false;
- int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR;
int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
- Log.i(TAG, "receiveBtEvent ACTION_AUDIO_STATE_CHANGED: " + btState);
- switch (btState) {
- case BluetoothHeadset.STATE_AUDIO_CONNECTED:
- scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
- if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
- && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
- mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
- } else if (mDeviceBroker.isBluetoothScoRequested()) {
- // broadcast intent if the connection was initated by AudioService
- broadcast = true;
- }
- mDeviceBroker.setBluetoothScoOn(true, "BtHelper.receiveBtEvent");
- break;
- case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
- mDeviceBroker.setBluetoothScoOn(false, "BtHelper.receiveBtEvent");
- scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
- // There are two cases where we want to immediately reconnect audio:
- // 1) If a new start request was received while disconnecting: this was
- // notified by requestScoState() setting state to SCO_STATE_ACTIVATE_REQ.
- // 2) If audio was connected then disconnected via Bluetooth APIs and
- // we still have pending activation requests by apps: this is indicated by
- // state SCO_STATE_ACTIVE_EXTERNAL and BT SCO is requested.
- if (mScoAudioState == SCO_STATE_ACTIVATE_REQ
- || (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL
- && mDeviceBroker.isBluetoothScoRequested())) {
- if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null
- && connectBluetoothScoAudioHelper(mBluetoothHeadset,
- mBluetoothHeadsetDevice, mScoAudioMode)) {
- mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
- scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTING;
- broadcast = true;
- break;
- }
- }
- if (mScoAudioState != SCO_STATE_ACTIVE_EXTERNAL) {
- broadcast = true;
- }
- mScoAudioState = SCO_STATE_INACTIVE;
- break;
- case BluetoothHeadset.STATE_AUDIO_CONNECTING:
- if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
- && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
- mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
- }
- break;
- default:
- break;
- }
- if (broadcast) {
- broadcastScoConnectionState(scoAudioState);
- //FIXME: this is to maintain compatibility with deprecated intent
- // AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate.
- Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED);
- newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, scoAudioState);
- sendStickyBroadcastToAll(newIntent);
- }
+ Log.i(TAG,"receiveBtEvent ACTION_AUDIO_STATE_CHANGED: "+btState);
+ mDeviceBroker.postScoAudioStateChanged(btState);
}
}
/**
+ * Exclusively called from AudioDeviceBroker when handling MSG_I_SCO_AUDIO_STATE_CHANGED
+ * as part of the serialization of the communication route selection
+ */
+ // @GuardedBy("AudioDeviceBroker.mSetModeLock")
+ @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
+ void onScoAudioStateChanged(int state) {
+ boolean broadcast = false;
+ int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR;
+ switch (state) {
+ case BluetoothHeadset.STATE_AUDIO_CONNECTED:
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
+ if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
+ && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
+ mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+ } else if (mDeviceBroker.isBluetoothScoRequested()) {
+ // broadcast intent if the connection was initated by AudioService
+ broadcast = true;
+ }
+ mDeviceBroker.setBluetoothScoOn(true, "BtHelper.receiveBtEvent");
+ break;
+ case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
+ mDeviceBroker.setBluetoothScoOn(false, "BtHelper.receiveBtEvent");
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
+ // There are two cases where we want to immediately reconnect audio:
+ // 1) If a new start request was received while disconnecting: this was
+ // notified by requestScoState() setting state to SCO_STATE_ACTIVATE_REQ.
+ // 2) If audio was connected then disconnected via Bluetooth APIs and
+ // we still have pending activation requests by apps: this is indicated by
+ // state SCO_STATE_ACTIVE_EXTERNAL and BT SCO is requested.
+ if (mScoAudioState == SCO_STATE_ACTIVATE_REQ) {
+ if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null
+ && connectBluetoothScoAudioHelper(mBluetoothHeadset,
+ mBluetoothHeadsetDevice, mScoAudioMode)) {
+ mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTING;
+ broadcast = true;
+ break;
+ }
+ }
+ if (mScoAudioState != SCO_STATE_ACTIVE_EXTERNAL) {
+ broadcast = true;
+ }
+ mScoAudioState = SCO_STATE_INACTIVE;
+ break;
+ case BluetoothHeadset.STATE_AUDIO_CONNECTING:
+ if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
+ && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
+ mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+ }
+ break;
+ default:
+ break;
+ }
+ if(broadcast) {
+ broadcastScoConnectionState(scoAudioState);
+ //FIXME: this is to maintain compatibility with deprecated intent
+ // AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate.
+ Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED);
+ newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, scoAudioState);
+ sendStickyBroadcastToAll(newIntent);
+ }
+
+ }
+ /**
*
* @return false if SCO isn't connected
*/
@@ -756,6 +764,15 @@
case SCO_STATE_ACTIVE_INTERNAL:
Log.w(TAG, "requestScoState: already in ACTIVE mode, simply return");
break;
+ case SCO_STATE_ACTIVE_EXTERNAL:
+ /* Confirm SCO Audio connection to requesting app as it is already connected
+ * externally (i.e. through SCO APIs by Telecom service).
+ * Once SCO Audio is disconnected by the external owner, we will reconnect it
+ * automatically on behalf of the requesting app and the state will move to
+ * SCO_STATE_ACTIVE_INTERNAL.
+ */
+ broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTED);
+ break;
default:
Log.w(TAG, "requestScoState: failed to connect in state "
+ mScoAudioState + ", scoAudioMode=" + scoAudioMode);
diff --git a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
index 0f0032b..1d90954 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
@@ -198,7 +198,7 @@
protected final void vibrateSuccess() {
Vibrator vibrator = getContext().getSystemService(Vibrator.class);
- if (vibrator != null) {
+ if (vibrator != null && mShouldVibrate) {
vibrator.vibrate(Process.myUid(),
getContext().getOpPackageName(),
SUCCESS_VIBRATION_EFFECT,
@@ -209,7 +209,7 @@
protected final void vibrateError() {
Vibrator vibrator = getContext().getSystemService(Vibrator.class);
- if (vibrator != null) {
+ if (vibrator != null && mShouldVibrate) {
vibrator.vibrate(Process.myUid(),
getContext().getOpPackageName(),
ERROR_VIBRATION_EFFECT,
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index bb1fed0..f23659c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -34,6 +34,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
+import android.view.accessibility.AccessibilityManager;
import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.log.BiometricContext;
@@ -66,6 +67,13 @@
private final int mMaxTemplatesPerUser;
private boolean mIsPointerDown;
+ private static boolean shouldVibrateFor(Context context,
+ FingerprintSensorPropertiesInternal sensorProps) {
+ final AccessibilityManager am = context.getSystemService(AccessibilityManager.class);
+ final boolean isAccessbilityEnabled = am.isTouchExplorationEnabled();
+ return !sensorProps.isAnyUdfpsType() || isAccessbilityEnabled;
+ }
+
FingerprintEnrollClient(@NonNull Context context,
@NonNull Supplier<AidlSession> lazyDaemon, @NonNull IBinder token, long requestId,
@NonNull ClientMonitorCallbackConverter listener, int userId,
@@ -78,8 +86,8 @@
int maxTemplatesPerUser, @FingerprintManager.EnrollReason int enrollReason) {
// UDFPS haptics occur when an image is acquired (instead of when the result is known)
super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils,
- 0 /* timeoutSec */, sensorId,
- !sensorProps.isAnyUdfpsType() /* shouldVibrate */, logger, biometricContext);
+ 0 /* timeoutSec */, sensorId, shouldVibrateFor(context, sensorProps), logger,
+ biometricContext);
setRequestId(requestId);
mSensorProps = sensorProps;
mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController);
@@ -119,7 +127,7 @@
// For UDFPS, notify SysUI that the illumination can be turned off.
// See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE
if (mSensorProps.isAnyUdfpsType()) {
- if (acquiredGood) {
+ if (acquiredGood && mShouldVibrate) {
vibrateSuccess();
}
mSensorOverlays.ifUdfps(
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 311fa7c..76d71e2 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -131,7 +131,7 @@
* Only used for mirroring started from MediaProjection.
*/
@Nullable
- public Point getDisplaySurfaceDefaultSize() {
+ public Point getDisplaySurfaceDefaultSizeLocked() {
return null;
}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 064e307..d12c621 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -30,9 +30,8 @@
import android.util.Spline;
import android.view.DisplayAddress;
-import com.android.internal.annotations.VisibleForTesting;
-
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.config.BrightnessThresholds;
import com.android.server.display.config.BrightnessThrottlingMap;
@@ -296,9 +295,9 @@
* @return A configuration instance for the specified display.
*/
public static DisplayDeviceConfig create(Context context, long physicalDisplayId,
- boolean isDefaultDisplay) {
+ boolean isFirstDisplay) {
final DisplayDeviceConfig config = createWithoutDefaultValues(context, physicalDisplayId,
- isDefaultDisplay);
+ isFirstDisplay);
config.copyUninitializedValuesFromSecondaryConfig(loadDefaultConfigurationXml(context));
return config;
@@ -323,7 +322,7 @@
}
private static DisplayDeviceConfig createWithoutDefaultValues(Context context,
- long physicalDisplayId, boolean isDefaultDisplay) {
+ long physicalDisplayId, boolean isFirstDisplay) {
DisplayDeviceConfig config;
config = loadConfigFromDirectory(context, Environment.getProductDirectory(),
@@ -341,7 +340,7 @@
// If no config can be loaded from any ddc xml at all,
// prepare a whole config using the global config.xml.
// Guaranteed not null
- return create(context, isDefaultDisplay);
+ return create(context, isFirstDisplay);
}
private static DisplayConfiguration loadDefaultConfigurationXml(Context context) {
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index a311ba1..edaa18a 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -39,7 +39,7 @@
* Flag: Indicates that this display device should be considered the default display
* device of the system.
*/
- public static final int FLAG_DEFAULT_DISPLAY = 1 << 0;
+ public static final int FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY = 1 << 0;
/**
* Flag: Indicates that the orientation of this display device is coupled to the
@@ -538,8 +538,8 @@
private static String flagsToString(int flags) {
StringBuilder msg = new StringBuilder();
- if ((flags & FLAG_DEFAULT_DISPLAY) != 0) {
- msg.append(", FLAG_DEFAULT_DISPLAY");
+ if ((flags & FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0) {
+ msg.append(", FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY");
}
if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) {
msg.append(", FLAG_ROTATES_WITH_CONTENT");
diff --git a/services/core/java/com/android/server/display/DisplayDeviceRepository.java b/services/core/java/com/android/server/display/DisplayDeviceRepository.java
index 2b52350..4ac7990 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceRepository.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceRepository.java
@@ -17,6 +17,7 @@
package com.android.server.display;
import android.annotation.NonNull;
+import android.os.Trace;
import android.util.Slog;
import android.view.Display;
import android.view.DisplayAddress;
@@ -38,6 +39,7 @@
*/
class DisplayDeviceRepository implements DisplayAdapter.Listener {
private static final String TAG = "DisplayDeviceRepository";
+ private static final Boolean DEBUG = false;
public static final int DISPLAY_DEVICE_EVENT_ADDED = 1;
public static final int DISPLAY_DEVICE_EVENT_CHANGED = 2;
@@ -75,6 +77,11 @@
@Override
public void onDisplayDeviceEvent(DisplayDevice device, int event) {
+ String tag = null;
+ if (DEBUG) {
+ tag = "DisplayDeviceRepository#onDisplayDeviceEvent (event=" + event + ")";
+ Trace.beginAsyncSection(tag, 0);
+ }
switch (event) {
case DISPLAY_DEVICE_EVENT_ADDED:
handleDisplayDeviceAdded(device);
@@ -88,6 +95,9 @@
handleDisplayDeviceRemoved(device);
break;
}
+ if (DEBUG) {
+ Trace.endAsyncSection(tag, 0);
+ }
}
@Override
@@ -156,7 +166,9 @@
Slog.w(TAG, "Attempted to change non-existent display device: " + info);
return;
}
-
+ if (DEBUG) {
+ Trace.beginSection("handleDisplayDeviceChanged");
+ }
int diff = device.mDebugLastLoggedDeviceInfo.diff(info);
if (diff == DisplayDeviceInfo.DIFF_STATE) {
Slog.i(TAG, "Display device changed state: \"" + info.name
@@ -176,6 +188,9 @@
device.applyPendingDisplayDeviceInfoChangesLocked();
sendEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);
+ if (DEBUG) {
+ Trace.endSection();
+ }
}
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index e21edc9..932717a 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -397,8 +397,7 @@
private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>();
// The default color mode for default displays. Overrides the usual
- // Display.Display.COLOR_MODE_DEFAULT for displays with the
- // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set.
+ // Display.Display.COLOR_MODE_DEFAULT for local displays.
private final int mDefaultDisplayDefaultColorMode;
// Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs.
@@ -1682,8 +1681,7 @@
if (display.getPrimaryDisplayDeviceLocked() == device) {
int colorMode = mPersistentDataStore.getColorMode(device);
if (colorMode == Display.COLOR_MODE_INVALID) {
- if ((device.getDisplayDeviceInfoLocked().flags
- & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
+ if (display.getDisplayIdLocked() == Display.DEFAULT_DISPLAY) {
colorMode = mDefaultDisplayDefaultColorMode;
} else {
colorMode = Display.COLOR_MODE_DEFAULT;
@@ -3880,8 +3878,8 @@
if (device == null) {
return null;
}
+ return device.getDisplaySurfaceDefaultSizeLocked();
}
- return device.getDisplaySurfaceDefaultSize();
}
@Override
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index f819e56..82e1efd 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -782,7 +782,13 @@
mDisplayStatsId = mUniqueDisplayId.hashCode();
mDisplayDeviceConfig = config;
loadFromDisplayDeviceConfig(token, info);
+ if (DEBUG) {
+ Trace.beginAsyncSection("DisplayPowerController#updatePowerState", 0);
+ }
updatePowerState();
+ if (DEBUG) {
+ Trace.endAsyncSection("DisplayPowerController#updatePowerState", 0);
+ }
}
});
}
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 540ae81..633cb24 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -16,6 +16,7 @@
package com.android.server.display;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.Mode.INVALID_MODE_ID;
import android.app.ActivityThread;
@@ -141,9 +142,9 @@
LocalDisplayDevice device = mDevices.get(physicalDisplayId);
if (device == null) {
// Display was added.
- final boolean isDefaultDisplay = mDevices.size() == 0;
+ final boolean isFirstDisplay = mDevices.size() == 0;
device = new LocalDisplayDevice(displayToken, physicalDisplayId, staticInfo,
- dynamicInfo, modeSpecs, isDefaultDisplay);
+ dynamicInfo, modeSpecs, isFirstDisplay);
mDevices.put(physicalDisplayId, device);
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
} else if (device.updateDisplayPropertiesLocked(staticInfo, dynamicInfo,
@@ -187,7 +188,7 @@
private final ArrayList<Integer> mSupportedColorModes = new ArrayList<>();
private final DisplayModeDirector.DesiredDisplayModeSpecs mDisplayModeSpecs =
new DisplayModeDirector.DesiredDisplayModeSpecs();
- private final boolean mIsDefaultDisplay;
+ private final boolean mIsFirstDisplay;
private final BacklightAdapter mBacklightAdapter;
private final SidekickInternal mSidekickInternal;
@@ -226,14 +227,14 @@
LocalDisplayDevice(IBinder displayToken, long physicalDisplayId,
SurfaceControl.StaticDisplayInfo staticDisplayInfo,
SurfaceControl.DynamicDisplayInfo dynamicInfo,
- SurfaceControl.DesiredDisplayModeSpecs modeSpecs, boolean isDefaultDisplay) {
+ SurfaceControl.DesiredDisplayModeSpecs modeSpecs, boolean isFirstDisplay) {
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId,
getContext());
mPhysicalDisplayId = physicalDisplayId;
- mIsDefaultDisplay = isDefaultDisplay;
+ mIsFirstDisplay = isFirstDisplay;
updateDisplayPropertiesLocked(staticDisplayInfo, dynamicInfo, modeSpecs);
mSidekickInternal = LocalServices.getService(SidekickInternal.class);
- mBacklightAdapter = new BacklightAdapter(displayToken, isDefaultDisplay,
+ mBacklightAdapter = new BacklightAdapter(displayToken, isFirstDisplay,
mSurfaceControlProxy);
mActiveDisplayModeAtStartId = dynamicInfo.activeDisplayModeId;
}
@@ -480,7 +481,7 @@
// Load display device config
final Context context = getOverlayContext();
mDisplayDeviceConfig = DisplayDeviceConfig.create(context, mPhysicalDisplayId,
- mIsDefaultDisplay);
+ mIsFirstDisplay);
// Load brightness HWC quirk
mBacklightAdapter.setForceSurfaceControl(mDisplayDeviceConfig.hasQuirk(
@@ -652,9 +653,9 @@
final Resources res = getOverlayContext().getResources();
- if (mIsDefaultDisplay) {
- mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY;
+ mInfo.flags |= DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY;
+ if (mIsFirstDisplay) {
if (res.getBoolean(com.android.internal.R.bool.config_mainBuiltInDisplayIsRound)
|| (Build.IS_EMULATOR
&& SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
@@ -1393,7 +1394,12 @@
}
public boolean getBootDisplayModeSupport() {
- return SurfaceControl.getBootDisplayModeSupport();
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "getBootDisplayModeSupport");
+ try {
+ return SurfaceControl.getBootDisplayModeSupport();
+ } finally {
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ }
}
public void setBootDisplayMode(IBinder displayToken, int modeId) {
@@ -1438,9 +1444,9 @@
/**
* @param displayToken Token for display associated with this backlight.
- * @param isDefaultDisplay {@code true} if it is the default display.
+ * @param isFirstDisplay {@code true} if it is the first display.
*/
- BacklightAdapter(IBinder displayToken, boolean isDefaultDisplay,
+ BacklightAdapter(IBinder displayToken, boolean isFirstDisplay,
SurfaceControlProxy surfaceControlProxy) {
mDisplayToken = displayToken;
mSurfaceControlProxy = surfaceControlProxy;
@@ -1448,7 +1454,7 @@
mUseSurfaceControlBrightness = mSurfaceControlProxy
.getDisplayBrightnessSupport(mDisplayToken);
- if (!mUseSurfaceControlBrightness && isDefaultDisplay) {
+ if (!mUseSurfaceControlBrightness && isFirstDisplay) {
LightsManager lights = LocalServices.getService(LightsManager.class);
mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
} else {
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index add0a9f..70c9e23 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -16,6 +16,8 @@
package com.android.server.display;
+import static android.view.Display.DEFAULT_DISPLAY;
+
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.devicestate.DeviceStateManager;
@@ -204,6 +206,7 @@
if (DEBUG) {
Slog.d(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
}
+ handleDisplayDeviceRemovedLocked(device);
updateLogicalDisplaysLocked();
break;
}
@@ -529,12 +532,12 @@
private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
- // Internal Displays need to have additional initialization.
- // This initializes a default dynamic display layout for INTERNAL
- // devices, which is used as a fallback in case no static layout definitions
+ // The default Display needs to have additional initialization.
+ // This initializes a default dynamic display layout for the default
+ // device, which is used as a fallback in case no static layout definitions
// exist or cannot be loaded.
- if (deviceInfo.type == Display.TYPE_INTERNAL) {
- initializeInternalDisplayDeviceLocked(device);
+ if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0) {
+ initializeDefaultDisplayDeviceLocked(device);
}
// Create a logical display for the new display device
@@ -545,6 +548,38 @@
updateLogicalDisplaysLocked();
}
+ private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
+ final Layout layout = mDeviceStateToLayoutMap.get(DeviceStateToLayoutMap.STATE_DEFAULT);
+ Layout.Display layoutDisplay = layout.getById(DEFAULT_DISPLAY);
+ if (layoutDisplay == null) {
+ return;
+ }
+ DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
+
+ if (layoutDisplay.getAddress().equals(deviceInfo.address)) {
+ layout.removeDisplayLocked(DEFAULT_DISPLAY);
+
+ // Need to find another local display and make it default
+ for (int i = 0; i < mLogicalDisplays.size(); i++) {
+ LogicalDisplay nextDisplay = mLogicalDisplays.valueAt(i);
+ DisplayDevice nextDevice = nextDisplay.getPrimaryDisplayDeviceLocked();
+ if (nextDevice == null) {
+ continue;
+ }
+ DisplayDeviceInfo nextDeviceInfo = nextDevice.getDisplayDeviceInfoLocked();
+
+ if ((nextDeviceInfo.flags
+ & DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0
+ && !nextDeviceInfo.address.equals(deviceInfo.address)) {
+ layout.createDisplayLocked(nextDeviceInfo.address,
+ /* isDefault= */ true, /* isEnabled= */ true);
+ applyLayoutLocked();
+ return;
+ }
+ }
+ }
+ }
+
/**
* Updates the rest of the display system once all the changes are applied for display
* devices and logical displays. The includes releasing invalid/empty LogicalDisplays,
@@ -900,16 +935,18 @@
return isOwnDisplayGroup ? mNextNonDefaultGroupId++ : Display.DEFAULT_DISPLAY_GROUP;
}
- private void initializeInternalDisplayDeviceLocked(DisplayDevice device) {
+ private void initializeDefaultDisplayDeviceLocked(DisplayDevice device) {
// We always want to make sure that our default layout creates a logical
- // display for every internal display device that is found.
- // To that end, when we are notified of a new internal display, we add it to
+ // display for the default display device that is found.
+ // To that end, when we are notified of a new default display, we add it to
// the default layout definition if it is not already there.
final Layout layout = mDeviceStateToLayoutMap.get(DeviceStateToLayoutMap.STATE_DEFAULT);
+ if (layout.getById(DEFAULT_DISPLAY) != null) {
+ // The layout should only have one default display
+ return;
+ }
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
- final boolean isDefault = (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
- final boolean isEnabled = isDefault || mSupportsConcurrentInternalDisplays;
- layout.createDisplayLocked(info.address, isDefault, isEnabled);
+ layout.createDisplayLocked(info.address, /* isDefault= */ true, /* isEnabled= */ true);
}
private int assignLayerStackLocked(int displayId) {
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index ea31374..dde8831 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -302,7 +302,7 @@
}
@Override
- public Point getDisplaySurfaceDefaultSize() {
+ public Point getDisplaySurfaceDefaultSizeLocked() {
if (mSurface == null) {
return null;
}
diff --git a/services/core/java/com/android/server/display/layout/Layout.java b/services/core/java/com/android/server/display/layout/Layout.java
index e53aec1..7e16ea8 100644
--- a/services/core/java/com/android/server/display/layout/Layout.java
+++ b/services/core/java/com/android/server/display/layout/Layout.java
@@ -67,7 +67,7 @@
// See if we're dealing with the "default" display
if (isDefault && getById(DEFAULT_DISPLAY) != null) {
Slog.w(TAG, "Ignoring attempt to add a second default display: " + address);
- isDefault = false;
+ return null;
}
// Assign a logical display ID and create the new display.
@@ -75,10 +75,20 @@
// different layouts, a logical display can be destroyed and later recreated with the
// same logical display ID.
final int logicalDisplayId = assignDisplayIdLocked(isDefault);
- final Display layout = new Display(address, logicalDisplayId, isEnabled);
+ final Display display = new Display(address, logicalDisplayId, isEnabled);
- mDisplays.add(layout);
- return layout;
+ mDisplays.add(display);
+ return display;
+ }
+
+ /**
+ * @param id The ID of the display to remove.
+ */
+ public void removeDisplayLocked(int id) {
+ Display display = getById(id);
+ if (display != null) {
+ mDisplays.remove(display);
+ }
}
/**
diff --git a/services/core/java/com/android/server/hdmi/GiveFeaturesAction.java b/services/core/java/com/android/server/hdmi/GiveFeaturesAction.java
deleted file mode 100644
index 4542565..0000000
--- a/services/core/java/com/android/server/hdmi/GiveFeaturesAction.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.hdmi;
-
-import android.hardware.hdmi.HdmiControlManager;
-import android.hardware.hdmi.IHdmiControlCallback;
-import android.hardware.tv.cec.V1_0.SendMessageResult;
-
-/**
- * Sends <Give Features> to a target device. This action succeeds if the device responds with
- * <Report Features> within {@link HdmiConfig.TIMEOUT_MS}.
- *
- * This action does not update the CEC network directly; an incoming <Report Features> message
- * should be handled separately by {@link HdmiCecNetwork}.
- */
-public class GiveFeaturesAction extends HdmiCecFeatureAction {
- private static final String TAG = "GiveFeaturesAction";
-
- private static final int STATE_WAITING_FOR_REPORT_FEATURES = 1;
-
- private final int mTargetAddress;
-
- public GiveFeaturesAction(HdmiCecLocalDevice source, int targetAddress,
- IHdmiControlCallback callback) {
- super(source, callback);
-
- mTargetAddress = targetAddress;
- }
-
- boolean start() {
- sendCommand(HdmiCecMessageBuilder.buildGiveFeatures(getSourceAddress(), mTargetAddress),
- result -> {
- if (result == SendMessageResult.SUCCESS) {
- mState = STATE_WAITING_FOR_REPORT_FEATURES;
- addTimer(STATE_WAITING_FOR_REPORT_FEATURES, HdmiConfig.TIMEOUT_MS);
- } else {
- finishWithCallback(HdmiControlManager.RESULT_COMMUNICATION_FAILED);
- }
- });
- return true;
- }
-
- boolean processCommand(HdmiCecMessage cmd) {
- if (mState != STATE_WAITING_FOR_REPORT_FEATURES) {
- return false;
- }
- if (cmd instanceof ReportFeaturesMessage) {
- return handleReportFeatures((ReportFeaturesMessage) cmd);
- }
- return false;
- }
-
- private boolean handleReportFeatures(ReportFeaturesMessage cmd) {
- if (cmd.getSource() == mTargetAddress) {
- // No need to update the network, since it should already have processed this message.
- finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
- return true;
- }
- return false;
- }
-
- void handleTimerEvent(int state) {
- finishWithCallback(HdmiControlManager.RESULT_COMMUNICATION_FAILED);
- }
-}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
index 6497174..185eaa9 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
@@ -19,6 +19,7 @@
import static com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
import android.annotation.Nullable;
+import android.hardware.hdmi.DeviceFeatures;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiPortInfo;
@@ -512,6 +513,9 @@
}
switch (message.getOpcode()) {
+ case Constants.MESSAGE_FEATURE_ABORT:
+ handleFeatureAbort(message);
+ break;
case Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS:
handleReportPhysicalAddress(message);
break;
@@ -544,6 +548,38 @@
}
@ServiceThreadOnly
+ private void handleFeatureAbort(HdmiCecMessage message) {
+ assertRunOnServiceThread();
+
+ if (message.getParams().length < 2) {
+ return;
+ }
+
+ int originalOpcode = message.getParams()[0] & 0xFF;
+ int reason = message.getParams()[1] & 0xFF;
+
+ // Check if we received <Feature Abort> in response to <Set Audio Volume Level>.
+ // This provides information on whether the source supports the message.
+ if (originalOpcode == Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL) {
+
+ @DeviceFeatures.FeatureSupportStatus int featureSupport =
+ reason == Constants.ABORT_UNRECOGNIZED_OPCODE
+ ? DeviceFeatures.FEATURE_NOT_SUPPORTED
+ : DeviceFeatures.FEATURE_SUPPORT_UNKNOWN;
+
+ HdmiDeviceInfo currentDeviceInfo = getCecDeviceInfo(message.getSource());
+ HdmiDeviceInfo newDeviceInfo = currentDeviceInfo.toBuilder()
+ .updateDeviceFeatures(
+ currentDeviceInfo.getDeviceFeatures().toBuilder()
+ .setSetAudioVolumeLevelSupport(featureSupport)
+ .build()
+ )
+ .build();
+ updateCecDevice(newDeviceInfo);
+ }
+ }
+
+ @ServiceThreadOnly
private void handleCecVersion(HdmiCecMessage message) {
assertRunOnServiceThread();
diff --git a/services/core/java/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryAction.java b/services/core/java/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryAction.java
index 5154669..96fd003 100644
--- a/services/core/java/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryAction.java
+++ b/services/core/java/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryAction.java
@@ -16,7 +16,6 @@
package com.android.server.hdmi;
-import static android.hardware.hdmi.DeviceFeatures.FEATURE_NOT_SUPPORTED;
import static android.hardware.hdmi.DeviceFeatures.FEATURE_SUPPORTED;
import static com.android.server.hdmi.Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL;
@@ -78,13 +77,13 @@
}
private boolean handleFeatureAbort(HdmiCecMessage cmd) {
+ if (cmd.getParams().length < 2) {
+ return false;
+ }
int originalOpcode = cmd.getParams()[0] & 0xFF;
if (originalOpcode == MESSAGE_SET_AUDIO_VOLUME_LEVEL && cmd.getSource() == mTargetAddress) {
- if (updateAvcSupport(FEATURE_NOT_SUPPORTED)) {
- finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
- } else {
- finishWithCallback(HdmiControlManager.RESULT_EXCEPTION);
- }
+ // No need to update the network, since it should already have processed this message.
+ finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
return true;
}
return false;
@@ -107,7 +106,7 @@
*/
private boolean updateAvcSupport(
@DeviceFeatures.FeatureSupportStatus int setAudioVolumeLevelSupport) {
- HdmiCecNetwork network = source().mService.getHdmiCecNetwork();
+ HdmiCecNetwork network = localDevice().mService.getHdmiCecNetwork();
HdmiDeviceInfo currentDeviceInfo = network.getCecDeviceInfo(mTargetAddress);
if (currentDeviceInfo == null) {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 135af2d..b923890 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -2473,7 +2473,7 @@
private void removeUser(int userId, boolean unknownUser) {
Slog.i(TAG, "RemoveUser: " + userId);
removeBiometricsForUser(userId);
- mSpManager.removeUser(userId);
+ mSpManager.removeUser(getGateKeeperService(), userId);
mStrongAuth.removeUser(userId);
AndroidKeyStoreMaintenance.onUserRemoved(userId);
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index 2da4431..24bd42e 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -565,11 +565,18 @@
return response[0];
}
- public void removeUser(int userId) {
+ public void removeUser(IGateKeeperService gatekeeper, int userId) {
for (long handle : mStorage.listSyntheticPasswordHandlesForUser(SP_BLOB_NAME, userId)) {
destroyWeaverSlot(handle, userId);
destroySPBlobKey(getKeyName(handle));
}
+ // Remove potential persistent state (in RPMB), to prevent them from accumulating and
+ // causing problems.
+ try {
+ gatekeeper.clearSecureUserId(fakeUid(userId));
+ } catch (RemoteException ignore) {
+ Slog.w(TAG, "Failed to clear SID from gatekeeper");
+ }
}
int getCredentialType(long handle, int userId) {
diff --git a/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java b/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java
index 1ae7ac0..df612e6 100644
--- a/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java
+++ b/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.MediaMetrics;
+import android.media.metrics.BundleSession;
import android.media.metrics.IMediaMetricsManager;
import android.media.metrics.NetworkEvent;
import android.media.metrics.PlaybackErrorEvent;
@@ -187,11 +188,33 @@
return;
}
- int atomid = metrics.getInt("KEY_STATSD_ATOM_NUMBER");
+ int atomid = metrics.getInt(BundleSession.KEY_STATSD_ATOM);
switch (atomid) {
default:
return;
// to be extended as we define statsd atoms
+ case 322: // MediaPlaybackStateEvent
+ // pattern for the keys:
+ // <statsd event> - <fieldname>
+ // match types to what stats will want
+ String _sessionId = metrics.getString("playbackstateevent-sessionid");
+ int _state = metrics.getInt("playbackstateevent-state", -1);
+ long _lifetime = metrics.getLong("playbackstateevent-lifetime", -1);
+ if (_sessionId == null || _state < 0 || _lifetime < 0) {
+ Slog.d(TAG, "dropping incomplete data for atom 322: _sessionId: "
+ + _sessionId + " _state: " + _state
+ + " _lifetime: " + _lifetime);
+ return;
+ }
+ StatsEvent statsEvent = StatsEvent.newBuilder()
+ .setAtomId(322)
+ .writeString(_sessionId)
+ .writeInt(_state)
+ .writeLong(_lifetime)
+ .usePooledBuffer()
+ .build();
+ StatsLog.write(statsEvent);
+ return;
}
}
@@ -227,6 +250,13 @@
}
@Override
+ public void releaseSessionId(String sessionId, int userId) {
+ // De-authorize this session-id in the native mediametrics service.
+ // TODO: plumbing to the native mediametrics service
+ Slog.v(TAG, "Releasing sessionId " + sessionId + " for userId " + userId + " [NOP]");
+ }
+
+ @Override
public String getPlaybackSessionId(int userId) {
return getSessionIdInternal(userId);
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 589b8f1..953b6ae 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -26,6 +26,8 @@
import static android.Manifest.permission.OBSERVE_NETWORK_POLICY;
import static android.Manifest.permission.READ_PHONE_STATE;
import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
+import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
+import static android.app.ActivityManager.isProcStateConsideredInteraction;
import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import static android.content.Intent.ACTION_PACKAGE_ADDED;
@@ -4042,14 +4044,14 @@
isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
!= isProcStateAllowedWhileIdleOrPowerSaveMode(newUidState);
if (allowedWhileIdleOrPowerSaveModeChanged) {
- updateRuleForAppIdleUL(uid);
+ updateRuleForAppIdleUL(uid, procState);
if (mDeviceIdleMode) {
updateRuleForDeviceIdleUL(uid);
}
if (mRestrictPower) {
updateRuleForRestrictPowerUL(uid);
}
- updateRulesForPowerRestrictionsUL(uid);
+ updateRulesForPowerRestrictionsUL(uid, procState);
}
if (mLowPowerStandbyActive) {
boolean allowedInLpsChanged =
@@ -4057,7 +4059,7 @@
!= isProcStateAllowedWhileInLowPowerStandby(newUidState);
if (allowedInLpsChanged) {
if (!allowedWhileIdleOrPowerSaveModeChanged) {
- updateRulesForPowerRestrictionsUL(uid);
+ updateRulesForPowerRestrictionsUL(uid, procState);
}
updateRuleForLowPowerStandbyUL(uid);
}
@@ -4426,7 +4428,7 @@
}
@GuardedBy("mUidRulesFirstLock")
- void updateRuleForAppIdleUL(int uid) {
+ void updateRuleForAppIdleUL(int uid, int uidProcessState) {
if (!isUidValidForDenylistRulesUL(uid)) return;
if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
@@ -4434,7 +4436,7 @@
}
try {
int appId = UserHandle.getAppId(uid);
- if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)
+ if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid, uidProcessState)
&& !isUidForegroundOnRestrictPowerUL(uid)) {
setUidFirewallRuleUL(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY);
if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL DENY " + uid);
@@ -4585,7 +4587,7 @@
final UserInfo user = users.get(i);
int uid = UserHandle.getUid(user.id, appId);
// Update external firewall rules.
- updateRuleForAppIdleUL(uid);
+ updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
updateRuleForDeviceIdleUL(uid);
updateRuleForRestrictPowerUL(uid);
// Update internal rules.
@@ -4633,7 +4635,7 @@
} else {
mAppIdleTempWhitelistAppIds.delete(uid);
}
- updateRuleForAppIdleUL(uid);
+ updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
updateRulesForPowerRestrictionsUL(uid);
} finally {
Binder.restoreCallingIdentity(token);
@@ -4659,7 +4661,15 @@
/** Returns if the UID is currently considered idle. */
@VisibleForTesting
boolean isUidIdle(int uid) {
+ return isUidIdle(uid, PROCESS_STATE_UNKNOWN);
+ }
+
+ private boolean isUidIdle(int uid, int uidProcessState) {
synchronized (mUidRulesFirstLock) {
+ if (uidProcessState != PROCESS_STATE_UNKNOWN && isProcStateConsideredInteraction(
+ uidProcessState)) {
+ return false;
+ }
if (mAppIdleTempWhitelistAppIds.get(uid)) {
// UID is temporarily allowlisted.
return false;
@@ -4746,7 +4756,7 @@
private void updateRestrictionRulesForUidUL(int uid) {
// Methods below only changes the firewall rules for the power-related modes.
updateRuleForDeviceIdleUL(uid);
- updateRuleForAppIdleUL(uid);
+ updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
updateRuleForRestrictPowerUL(uid);
// If the uid has the necessary permissions, then it should be added to the restricted mode
@@ -4920,7 +4930,12 @@
*/
@GuardedBy("mUidRulesFirstLock")
private void updateRulesForPowerRestrictionsUL(int uid) {
- updateRulesForPowerRestrictionsUL(uid, isUidIdle(uid));
+ updateRulesForPowerRestrictionsUL(uid, PROCESS_STATE_UNKNOWN);
+ }
+
+ @GuardedBy("mUidRulesFirstLock")
+ private void updateRulesForPowerRestrictionsUL(int uid, int uidProcState) {
+ updateRulesForPowerRestrictionsUL(uid, isUidIdle(uid, uidProcState));
}
/**
@@ -5028,7 +5043,7 @@
PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
synchronized (mUidRulesFirstLock) {
mLogger.appIdleStateChanged(uid, idle);
- updateRuleForAppIdleUL(uid);
+ updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
updateRulesForPowerRestrictionsUL(uid);
}
} catch (NameNotFoundException nnfe) {
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 4f26809..273afcc 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -42,7 +42,7 @@
private final int mAutoGroupAtCount;
// count the number of ongoing notifications per group
- // userId -> (package name -> (group Id -> (set of notification keys)))
+ // userId|packageName -> (set of ongoing notifications that aren't in an app group)
final ArrayMap<String, ArraySet<String>>
mOngoingGroupCount = new ArrayMap<>();
@@ -55,52 +55,43 @@
mCallback = callback;
}
- private String generatePackageGroupKey(int userId, String pkg, String group) {
- return userId + "|" + pkg + "|" + group;
+ private String generatePackageKey(int userId, String pkg) {
+ return userId + "|" + pkg;
}
@VisibleForTesting
- protected int getOngoingGroupCount(int userId, String pkg, String group) {
- String key = generatePackageGroupKey(userId, pkg, group);
+ protected int getOngoingGroupCount(int userId, String pkg) {
+ String key = generatePackageKey(userId, pkg);
return mOngoingGroupCount.getOrDefault(key, new ArraySet<>(0)).size();
}
- private void addToOngoingGroupCount(StatusBarNotification sbn, boolean add) {
- if (sbn.getNotification().isGroupSummary()) return;
- if (!sbn.isOngoing() && add) return;
- String group = sbn.getGroup();
- if (group == null) return;
- int userId = sbn.getUser().getIdentifier();
- String key = generatePackageGroupKey(userId, sbn.getPackageName(), group);
+ private void updateOngoingGroupCount(StatusBarNotification sbn, boolean add) {
+ if (sbn.getNotification().isGroupSummary()) {
+ return;
+ }
+ String key = generatePackageKey(sbn.getUserId(), sbn.getPackageName());
ArraySet<String> notifications = mOngoingGroupCount.getOrDefault(key, new ArraySet<>(0));
if (add) {
notifications.add(sbn.getKey());
mOngoingGroupCount.put(key, notifications);
} else {
notifications.remove(sbn.getKey());
- // we dont need to put it back if it is default
+ // we don't need to put it back if it is default
}
- String combinedKey = generatePackageGroupKey(userId, sbn.getPackageName(), group);
+
boolean needsOngoingFlag = notifications.size() > 0;
- mCallback.updateAutogroupSummary(userId, sbn.getPackageName(), needsOngoingFlag);
+ mCallback.updateAutogroupSummary(sbn.getUserId(), sbn.getPackageName(), needsOngoingFlag);
}
- public void onNotificationUpdated(StatusBarNotification childSbn,
- boolean autogroupSummaryExists) {
- if (childSbn.getGroup() != AUTOGROUP_KEY
- || childSbn.getNotification().isGroupSummary()) return;
- if (childSbn.isOngoing()) {
- addToOngoingGroupCount(childSbn, true);
- } else {
- addToOngoingGroupCount(childSbn, false);
- }
+ public void onNotificationUpdated(StatusBarNotification childSbn) {
+ updateOngoingGroupCount(childSbn, childSbn.isOngoing() && !childSbn.isAppGroup());
}
public void onNotificationPosted(StatusBarNotification sbn, boolean autogroupSummaryExists) {
- if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey());
try {
+ updateOngoingGroupCount(sbn, sbn.isOngoing() && !sbn.isAppGroup());
+
List<String> notificationsToGroup = new ArrayList<>();
- if (autogroupSummaryExists) addToOngoingGroupCount(sbn, true);
if (!sbn.isAppGroup()) {
// Not grouped by the app, add to the list of notifications for the app;
// send grouping update if app exceeds the autogrouping limit.
@@ -134,6 +125,7 @@
// Grouped, but not by us. Send updates to un-autogroup, if we grouped it.
maybeUngroup(sbn, false, sbn.getUserId());
}
+
} catch (Exception e) {
Slog.e(TAG, "Failure processing new notification", e);
}
@@ -141,7 +133,7 @@
public void onNotificationRemoved(StatusBarNotification sbn) {
try {
- addToOngoingGroupCount(sbn, false);
+ updateOngoingGroupCount(sbn, false);
maybeUngroup(sbn, true, sbn.getUserId());
} catch (Exception e) {
Slog.e(TAG, "Error processing canceled notification", e);
@@ -189,7 +181,8 @@
private void adjustAutogroupingSummary(int userId, String packageName, String triggeringKey,
boolean summaryNeeded) {
if (summaryNeeded) {
- mCallback.addAutoGroupSummary(userId, packageName, triggeringKey);
+ mCallback.addAutoGroupSummary(userId, packageName, triggeringKey,
+ getOngoingGroupCount(userId, packageName) > 0);
} else {
mCallback.removeAutoGroupSummary(userId, packageName);
}
@@ -209,7 +202,8 @@
protected interface Callback {
void addAutoGroup(String key);
void removeAutoGroup(String key);
- void addAutoGroupSummary(int userId, String pkg, String triggeringKey);
+ void addAutoGroupSummary(int userId, String pkg, String triggeringKey,
+ boolean needsOngoingFlag);
void removeAutoGroupSummary(int user, String pkg);
void updateAutogroupSummary(int userId, String pkg, boolean needsOngoingFlag);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1885b55..326a5f2 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2557,8 +2557,10 @@
}
@Override
- public void addAutoGroupSummary(int userId, String pkg, String triggeringKey) {
- NotificationRecord r = createAutoGroupSummary(userId, pkg, triggeringKey);
+ public void addAutoGroupSummary(int userId, String pkg, String triggeringKey,
+ boolean needsOngoingFlag) {
+ NotificationRecord r = createAutoGroupSummary(
+ userId, pkg, triggeringKey, needsOngoingFlag);
if (r != null) {
final boolean isAppForeground =
mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
@@ -5739,6 +5741,7 @@
void removeAutogroupKeyLocked(String key) {
NotificationRecord r = mNotificationsByKey.get(key);
if (r == null) {
+ Slog.w(TAG, "Failed to remove autogroup " + key);
return;
}
if (r.getSbn().getOverrideGroupKey() != null) {
@@ -5778,7 +5781,8 @@
}
// Creates a 'fake' summary for a package that has exceeded the solo-notification limit.
- NotificationRecord createAutoGroupSummary(int userId, String pkg, String triggeringKey) {
+ NotificationRecord createAutoGroupSummary(int userId, String pkg, String triggeringKey,
+ boolean needsOngoingFlag) {
NotificationRecord summaryRecord = null;
boolean isPermissionFixed = mPermissionHelper.isMigrationEnabled()
? mPermissionHelper.isPermissionFixed(pkg, userId) : false;
@@ -5818,6 +5822,7 @@
.setGroup(GroupHelper.AUTOGROUP_KEY)
.setFlag(FLAG_AUTOGROUP_SUMMARY, true)
.setFlag(Notification.FLAG_GROUP_SUMMARY, true)
+ .setFlag(FLAG_ONGOING_EVENT, needsOngoingFlag)
.setColor(adjustedSbn.getNotification().color)
.setLocalOnly(true)
.build();
@@ -7356,17 +7361,16 @@
mListeners.notifyPostedLocked(r, old);
if ((oldSbn == null || !Objects.equals(oldSbn.getGroup(), n.getGroup()))
&& !isCritical(r)) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
+ mHandler.post(() -> {
+ synchronized (mNotificationLock) {
mGroupHelper.onNotificationPosted(
n, hasAutoGroupSummaryLocked(n));
}
});
} else if (oldSbn != null) {
final NotificationRecord finalRecord = r;
- mHandler.post(() -> mGroupHelper.onNotificationUpdated(
- finalRecord.getSbn(), hasAutoGroupSummaryLocked(n)));
+ mHandler.post(() ->
+ mGroupHelper.onNotificationUpdated(finalRecord.getSbn()));
}
} else {
Slog.e(TAG, "Not posting notification without small icon: " + notification);
@@ -10429,10 +10433,10 @@
boolean isPrimary, boolean enabled, boolean userSet) {
super.setPackageOrComponentEnabled(pkgOrComponent, userId, isPrimary, enabled, userSet);
- getContext().sendBroadcastAsUser(
+ mContext.sendBroadcastAsUser(
new Intent(ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED)
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
- UserHandle.ALL, null);
+ UserHandle.of(userId), null);
}
@Override
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index 7b2dc28..152c745 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -1330,7 +1330,9 @@
+ callingUid + " -> " + targetUid);
return true;
}
- return mShouldFilterCache.valueAt(callingIndex, targetIndex);
+ if (!mShouldFilterCache.valueAt(callingIndex, targetIndex)) {
+ return false;
+ }
} else {
if (!shouldFilterApplicationInternal(
callingUid, callingSetting, targetPkgSetting, userId)) {
diff --git a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
index a3134a0..cac9323 100644
--- a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
+++ b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
@@ -246,7 +246,7 @@
private static final DefaultCrossProfileIntentFilter MEDIA_CAPTURE =
new DefaultCrossProfileIntentFilter.Builder(
DefaultCrossProfileIntentFilter.Direction.TO_PARENT,
- /* flags= */0,
+ /* flags= */ ONLY_IF_NO_MATCH_FOUND,
/* letsPersonalDataIntoProfile= */ true)
.addAction(MediaStore.ACTION_IMAGE_CAPTURE)
.addAction(MediaStore.ACTION_IMAGE_CAPTURE_SECURE)
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 0e1c1ad..dc4dd12 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -43,6 +43,7 @@
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.SharedLibraryInfo;
+import android.content.pm.UserInfo;
import android.content.pm.VersionedPackage;
import android.net.Uri;
import android.os.Binder;
@@ -161,6 +162,15 @@
return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
}
+ if (PackageManagerServiceUtils.isSystemApp(uninstalledPs)) {
+ UserInfo userInfo = mUserManagerInternal.getUserInfo(userId);
+ if (userInfo == null || !userInfo.isAdmin()) {
+ Slog.w(TAG, "Not removing package " + packageName
+ + " as only admin user may downgrade system apps");
+ return PackageManager.DELETE_FAILED_USER_RESTRICTED;
+ }
+ }
+
disabledSystemPs = mPm.mSettings.getDisabledSystemPkgLPr(packageName);
// Static shared libs can be declared by any package, so let us not
// allow removing a package if it provides a lib others depend on.
diff --git a/services/core/java/com/android/server/pm/IntentResolverInterceptor.java b/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
index 0ee07b6..5597c9a 100644
--- a/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
+++ b/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
@@ -21,14 +21,11 @@
import android.Manifest;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
-import android.app.ActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
-import android.os.RemoteException;
import android.provider.DeviceConfig;
-import android.util.Slog;
import com.android.internal.R;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
@@ -39,10 +36,8 @@
/**
* Service to register an {@code ActivityInterceptorCallback} that modifies any {@code Intent}
- * that's being used to launch a user-space {@code ChooserActivity}, by adding
- * EXTRA_PERMISSION_TOKEN, a Binder representing a single-use-only permission to invoke the
- * #startActivityAsCaller() API (which normally isn't available in user-space); and setting the
- * destination component to the delegated component when appropriate.
+ * that's being used to launch a user-space {@code ChooserActivity} by setting the destination
+ * component to the delegated component when appropriate.
*/
public final class IntentResolverInterceptor {
private static final String TAG = "IntentResolverIntercept";
@@ -92,7 +87,6 @@
private Intent modifyChooserIntent(Intent intent) {
intent.setComponent(getUnbundledChooserComponentName());
- addStartActivityPermissionTokenToIntent(intent, getUnbundledChooserComponentName());
return intent;
}
@@ -103,18 +97,6 @@
|| targetComponent.equals(getUnbundledChooserComponentName());
}
- private static Intent addStartActivityPermissionTokenToIntent(
- Intent intent, ComponentName grantee) {
- try {
- intent.putExtra(
- ActivityTaskManager.EXTRA_PERMISSION_TOKEN,
- ActivityTaskManager.getService().requestStartActivityPermissionToken(grantee));
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to add permission token to chooser intent");
- }
- return intent;
- }
-
private static ComponentName getSystemChooserComponentName() {
return new ComponentName("android", "com.android.internal.app.ChooserActivity");
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 5ba4cc1..1efaa73 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -272,7 +272,7 @@
/**
* The default value of {@link #mValidatedTargetSdk} is {@link Integer#MAX_VALUE}. If {@link
- * #mValidatedTargetSdk} is compared with {@link Build.VERSION_CODES#Q} before getting the
+ * #mValidatedTargetSdk} is compared with {@link Build.VERSION_CODES#R} before getting the
* target sdk version from a validated apk in {@link #validateApkInstallLocked()}, the compared
* result will not trigger any user action in
* {@link #checkUserActionRequirement(PackageInstallerSession)}.
@@ -2083,7 +2083,7 @@
}
if (validatedTargetSdk != INVALID_TARGET_SDK_VERSION
- && validatedTargetSdk < Build.VERSION_CODES.Q) {
+ && validatedTargetSdk < Build.VERSION_CODES.R) {
session.sendPendingUserActionIntent(target);
return true;
}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index b2b59f1..9ce4cdf 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -338,7 +338,7 @@
public void ensureAllShortcutsVisibleToLauncher(@NonNull List<ShortcutInfo> shortcuts) {
for (ShortcutInfo shortcut : shortcuts) {
- if (!shortcut.isIncludedIn(ShortcutInfo.SURFACE_LAUNCHER)) {
+ if (shortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER)) {
throw new IllegalArgumentException("Shortcut ID=" + shortcut.getId()
+ " is hidden from launcher and may not be manipulated via APIs");
}
@@ -399,7 +399,7 @@
& (ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_CACHED_ALL));
}
- if (!newShortcut.isIncludedIn(ShortcutInfo.SURFACE_LAUNCHER)) {
+ if (newShortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER)) {
if (isAppSearchEnabled()) {
synchronized (mLock) {
mTransientShortcuts.put(newShortcut.getId(), newShortcut);
@@ -477,7 +477,7 @@
& (ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_CACHED_ALL));
}
- if (!newShortcut.isIncludedIn(ShortcutInfo.SURFACE_LAUNCHER)) {
+ if (newShortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER)) {
if (isAppSearchEnabled()) {
synchronized (mLock) {
mTransientShortcuts.put(newShortcut.getId(), newShortcut);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 25fe000..9ca4f24 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -2228,7 +2228,7 @@
Objects.requireNonNull(shortcut);
Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
Preconditions.checkArgument(
- shortcut.isIncludedIn(ShortcutInfo.SURFACE_LAUNCHER),
+ !shortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER),
"Shortcut excluded from launcher cannot be pinned");
ret.complete(String.valueOf(requestPinItem(
packageName, userId, shortcut, null, null, resultIntent)));
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5aa81ac..999428a 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1491,11 +1491,19 @@
}
private long getAccessibilityShortcutTimeout() {
- ViewConfiguration config = ViewConfiguration.get(mContext);
- return Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0, mCurrentUserId) == 0
- ? config.getAccessibilityShortcutKeyTimeout()
- : config.getAccessibilityShortcutKeyTimeoutAfterConfirmation();
+ final ViewConfiguration config = ViewConfiguration.get(mContext);
+ final boolean hasDialogShown = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0, mCurrentUserId) != 0;
+ final boolean skipTimeoutRestriction =
+ Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.SKIP_ACCESSIBILITY_SHORTCUT_DIALOG_TIMEOUT_RESTRICTION, 0,
+ mCurrentUserId) != 0;
+
+ // If users manually set the volume key shortcut for any accessibility service, the
+ // system would bypass the timeout restriction of the shortcut dialog.
+ return hasDialogShown || skipTimeoutRestriction
+ ? config.getAccessibilityShortcutKeyTimeoutAfterConfirmation()
+ : config.getAccessibilityShortcutKeyTimeout();
}
private long getScreenshotChordLongPressDelay() {
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 048f8d6..c04d608 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -40,12 +40,14 @@
import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
+import android.app.AppOpsManager;
import android.app.SynchronousUserSwitchObserver;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
@@ -1454,6 +1456,15 @@
private void acquireWakeLockInternal(IBinder lock, int displayId, int flags, String tag,
String packageName, WorkSource ws, String historyTag, int uid, int pid,
@Nullable IWakeLockCallback callback) {
+
+ boolean isCallerPrivileged = false;
+ try {
+ ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(packageName,
+ PackageManager.ApplicationInfoFlags.of(0));
+ isCallerPrivileged = appInfo.uid == uid && appInfo.isPrivilegedApp();
+ } catch (PackageManager.NameNotFoundException e) {
+ // assume app is not privileged
+ }
synchronized (mLock) {
if (displayId != Display.INVALID_DISPLAY) {
final DisplayInfo displayInfo =
@@ -1500,7 +1511,7 @@
notifyAcquire = true;
}
- applyWakeLockFlagsOnAcquireLocked(wakeLock, uid);
+ applyWakeLockFlagsOnAcquireLocked(wakeLock, isCallerPrivileged);
mDirty |= DIRTY_WAKE_LOCKS;
updatePowerStateLocked();
if (notifyAcquire) {
@@ -1539,8 +1550,34 @@
return null;
}
+ private boolean isAcquireCausesWakeupFlagAllowed(String opPackageName, int opUid,
+ boolean isCallerPrivileged) {
+ if (opPackageName == null) {
+ return false;
+ }
+ if (isCallerPrivileged) {
+ if (DEBUG_SPEW) {
+ Slog.d(TAG, "Allowing device wake-up for privileged app, call attributed to "
+ + opPackageName);
+ }
+ return true;
+ }
+ if (mContext.getSystemService(AppOpsManager.class).checkOpNoThrow(
+ AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName)
+ == AppOpsManager.MODE_ALLOWED) {
+ if (DEBUG_SPEW) {
+ Slog.d(TAG, "Allowing device wake-up for app with special access " + opPackageName);
+ }
+ return true;
+ }
+ if (DEBUG_SPEW) {
+ Slog.d(TAG, "Not allowing device wake-up for " + opPackageName);
+ }
+ return false;
+ }
+
@GuardedBy("mLock")
- private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, int uid) {
+ private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, boolean isCallerPrivileged) {
if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0
&& isScreenLock(wakeLock)) {
String opPackageName;
@@ -1560,10 +1597,30 @@
opPackageName = wakeLock.mPackageName;
opUid = wakeLock.mOwnerUid;
}
- for (int idx = 0; idx < mPowerGroups.size(); idx++) {
- wakePowerGroupLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(),
- PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag, opUid, opPackageName,
- opUid);
+ Integer powerGroupId = wakeLock.getPowerGroupId();
+ // powerGroupId is null if the wakelock associated display is no longer available
+ if (powerGroupId != null && isAcquireCausesWakeupFlagAllowed(opPackageName, opUid,
+ isCallerPrivileged)) {
+ if (powerGroupId == Display.INVALID_DISPLAY_GROUP) {
+ // wake up all display groups
+ if (DEBUG_SPEW) {
+ Slog.d(TAG, "Waking up all power groups");
+ }
+ for (int idx = 0; idx < mPowerGroups.size(); idx++) {
+ wakePowerGroupLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag, opUid,
+ opPackageName, opUid);
+ }
+ return;
+ }
+ if (mPowerGroups.contains(powerGroupId)) {
+ if (DEBUG_SPEW) {
+ Slog.d(TAG, "Waking up power group " + powerGroupId);
+ }
+ wakePowerGroupLocked(mPowerGroups.get(powerGroupId), mClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag, opUid,
+ opPackageName, opUid);
+ }
}
}
}
@@ -1972,7 +2029,7 @@
private boolean dozePowerGroupLocked(final PowerGroup powerGroup, long eventTime,
int reason, int uid) {
if (DEBUG_SPEW) {
- Slog.d(TAG, "sleepDisplayGroupNoUpdateLocked: eventTime=" + eventTime
+ Slog.d(TAG, "dozePowerGroup: eventTime=" + eventTime
+ ", groupId=" + powerGroup.getGroupId() + ", reason=" + reason
+ ", uid=" + uid);
}
@@ -2661,8 +2718,8 @@
@GuardedBy("mLock")
private void updateUserActivitySummaryLocked(long now, int dirty) {
// Update the status of the user activity timeout timer.
- if ((dirty & (DIRTY_DISPLAY_GROUP_WAKEFULNESS | DIRTY_WAKE_LOCKS
- | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) == 0) {
+ if ((dirty & (DIRTY_DISPLAY_GROUP_WAKEFULNESS | DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
+ | DIRTY_WAKEFULNESS | DIRTY_SETTINGS | DIRTY_ATTENTIVE)) == 0) {
return;
}
mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
@@ -2746,6 +2803,11 @@
screenDimDuration);
}
+ if (isAttentiveTimeoutExpired(powerGroup, now)) {
+ groupUserActivitySummary = 0;
+ groupNextTimeout = -1;
+ }
+
hasUserActivitySummary |= groupUserActivitySummary != 0;
if (nextTimeout == -1) {
@@ -3101,7 +3163,7 @@
Message msg = mHandler.obtainMessage(MSG_SANDMAN);
msg.arg1 = powerGroup.getGroupId();
msg.setAsynchronous(true);
- mHandler.sendMessage(msg);
+ mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
}
}
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index a486364..8f4ddea 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.trust;
+import static android.service.trust.GrantTrustResult.STATUS_UNLOCKED_BY_GRANT;
import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;
import android.Manifest;
@@ -642,9 +643,7 @@
if (shouldSendCallback) {
if (resultCallback != null) {
if (DEBUG) Slog.d(TAG, "calling back with UNLOCKED_BY_GRANT");
- resultCallback.complete(
- GrantTrustResult.withStatus(
- GrantTrustResult.STATUS_UNLOCKED_BY_GRANT));
+ resultCallback.complete(new GrantTrustResult(STATUS_UNLOCKED_BY_GRANT));
}
}
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index e37b08f4..c52a4e4 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1598,7 +1598,7 @@
// Do not account space of trusted non-touchable windows, except the split-screen
// divider.
// If it's not trusted, touch events are not sent to the windows behind it.
- if (((a11yWindow.getFlags() & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0)
+ if (!a11yWindow.isTouchable()
&& (a11yWindow.getType() != TYPE_DOCK_DIVIDER)
&& a11yWindow.isTrustedOverlay()) {
return false;
@@ -1623,8 +1623,7 @@
// Ignore non-touchable windows, except the split-screen divider, which is
// occasionally non-touchable but still useful for identifying split-screen
// mode and the PIP menu.
- if (((a11yWindow.getFlags()
- & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0)
+ if (!a11yWindow.isTouchable()
&& (a11yWindow.getType() != TYPE_DOCK_DIVIDER
&& !a11yWindow.isPIPMenu())) {
return false;
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
index 799d59c..ca636b3 100644
--- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -601,14 +601,15 @@
// Data
private IWindow mWindow;
private int mDisplayId;
- private int mFlags;
+ @WindowManager.LayoutParams.WindowType
private int mType;
+ @InputWindowHandle.InputConfigFlags
+ private int mInputConfig;
private int mPrivateFlags;
private boolean mIsPIPMenu;
private boolean mIsFocused;
private boolean mShouldMagnify;
private boolean mIgnoreDuetoRecentsAnimation;
- private boolean mIsTrustedOverlay;
private final Region mTouchableRegionInScreen = new Region();
private final Region mTouchableRegionInWindow = new Region();
private final Region mLetterBoxBounds = new Region();
@@ -631,7 +632,7 @@
instance.mWindow = inputWindowHandle.getWindow();
instance.mDisplayId = inputWindowHandle.displayId;
- instance.mFlags = inputWindowHandle.layoutParamsFlags;
+ instance.mInputConfig = inputWindowHandle.inputConfig;
instance.mType = inputWindowHandle.layoutParamsType;
instance.mIsPIPMenu = inputWindowHandle.getWindow().asBinder().equals(pipIBinder);
@@ -644,8 +645,6 @@
final RecentsAnimationController controller = service.getRecentsAnimationController();
instance.mIgnoreDuetoRecentsAnimation = windowState != null && controller != null
&& controller.shouldIgnoreForAccessibility(windowState);
- instance.mIsTrustedOverlay =
- (inputWindowHandle.inputConfig & InputConfig.TRUSTED_OVERLAY) != 0;
// TODO (b/199358388) : gets the letterbox bounds of the window from other way.
if (windowState != null && windowState.areAppWindowBoundsLetterboxed()) {
@@ -683,13 +682,6 @@
}
/**
- * @return the layout parameter flag {@link android.view.WindowManager.LayoutParams#flags}.
- */
- public int getFlags() {
- return mFlags;
- }
-
- /**
* @return the layout parameter type {@link android.view.WindowManager.LayoutParams#type}.
*/
public int getType() {
@@ -751,7 +743,14 @@
* @return true if this window is the trusted overlay.
*/
public boolean isTrustedOverlay() {
- return mIsTrustedOverlay;
+ return (mInputConfig & InputConfig.TRUSTED_OVERLAY) != 0;
+ }
+
+ /**
+ * @return true if this window is touchable.
+ */
+ public boolean isTouchable() {
+ return (mInputConfig & InputConfig.NOT_TOUCHABLE) == 0;
}
/**
@@ -824,8 +823,8 @@
windowInfo.displayId = window.mDisplayId;
windowInfo.type = window.mType;
windowInfo.token = window.mWindow.asBinder();
- windowInfo.hasFlagWatchOutsideTouch = (window.mFlags
- & WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH) != 0;
+ windowInfo.hasFlagWatchOutsideTouch = (window.mInputConfig
+ & InputConfig.WATCH_OUTSIDE_TOUCH) != 0;
windowInfo.inPictureInPicture = false;
// There only are two windowless windows now, one is split window, and the other
@@ -851,13 +850,13 @@
public String toString() {
String builder = "A11yWindow=[" + mWindow.asBinder()
+ ", displayId=" + mDisplayId
- + ", flag=0x" + Integer.toHexString(mFlags)
+ + ", inputConfig=0x" + Integer.toHexString(mInputConfig)
+ ", type=" + mType
+ ", privateFlag=0x" + Integer.toHexString(mPrivateFlags)
+ ", focused=" + mIsFocused
+ ", shouldMagnify=" + mShouldMagnify
+ ", ignoreDuetoRecentsAnimation=" + mIgnoreDuetoRecentsAnimation
- + ", isTrustedOverlay=" + mIsTrustedOverlay
+ + ", isTrustedOverlay=" + isTrustedOverlay()
+ ", regionInScreen=" + mTouchableRegionInScreen
+ ", touchableRegion=" + mTouchableRegionInWindow
+ ", letterBoxBounds=" + mLetterBoxBounds
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 94f86462..0b52fd6 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -856,6 +856,7 @@
boolean mEnteringAnimation;
boolean mOverrideTaskTransition;
+ boolean mDismissKeyguardIfInsecure;
boolean mAppStopped;
// A hint to override the window specified rotation animation, or -1 to use the window specified
@@ -1953,6 +1954,7 @@
}
mOverrideTaskTransition = options.getOverrideTaskTransition();
+ mDismissKeyguardIfInsecure = options.getDismissKeyguardIfInsecure();
}
ColorDisplayService.ColorDisplayServiceInternal cds = LocalServices.getService(
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index c9b8501..72408b6 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -544,10 +544,8 @@
if (mLastHomeActivityStartRecord != null && (!dumpPackagePresent
|| dumpPackage.equals(mLastHomeActivityStartRecord.packageName))) {
- if (!dumped) {
- dumped = true;
- dumpLastHomeActivityStartResult(pw, prefix);
- }
+ dumped = true;
+ dumpLastHomeActivityStartResult(pw, prefix);
pw.print(prefix);
pw.println("mLastHomeActivityStartRecord:");
mLastHomeActivityStartRecord.dump(pw, prefix + " ", true /* dumpAll */);
@@ -565,6 +563,7 @@
dumpLastHomeActivityStartResult(pw, prefix);
}
pw.print(prefix);
+ pw.println("mLastStarter:");
mLastStarter.dump(pw, prefix + " ");
if (dumpPackagePresent) {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 7b60ea7..0b71754 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -614,6 +614,9 @@
mVoiceInteractor = starter.mVoiceInteractor;
mIntentDelivered = starter.mIntentDelivered;
+ mLastStartActivityResult = starter.mLastStartActivityResult;
+ mLastStartActivityTimeMs = starter.mLastStartActivityTimeMs;
+ mLastStartReason = starter.mLastStartReason;
mRequest.set(starter.mRequest);
}
@@ -1334,6 +1337,21 @@
: (realCallingAppId == Process.SYSTEM_UID)
|| realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
+ // In the case of an SDK sandbox calling uid, check if the corresponding app uid has a
+ // visible window.
+ if (Process.isSdkSandboxUid(realCallingUid)) {
+ int realCallingSdkSandboxUidToAppUid = Process.getAppUidForSdkSandboxUid(
+ UserHandle.getAppId(realCallingUid));
+
+ if (mService.hasActiveVisibleWindow(realCallingSdkSandboxUidToAppUid)) {
+ if (DEBUG_ACTIVITY_STARTS) {
+ Slog.d(TAG, "Activity start allowed: uid in SDK sandbox ("
+ + realCallingUid + ") has visible (non-toast) window.");
+ }
+ return false;
+ }
+ }
+
// Legacy behavior allows to use caller foreground state to bypass BAL restriction.
final boolean balAllowedByPiSender =
PendingIntentRecord.isPendingIntentBalAllowedByCaller(checkedOptions);
@@ -1599,7 +1617,6 @@
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
int result = START_CANCELED;
- boolean startResultSuccessful = false;
final Task startedActivityRootTask;
// Create a transition now to record the original intent of actions taken within
@@ -1615,75 +1632,18 @@
newTransition.setRemoteTransition(remoteTransition);
}
transitionController.collect(r);
- final boolean isTransient = r.getOptions() != null && r.getOptions().getTransientLaunch();
try {
mService.deferWindowLayout();
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
intentGrants);
- startResultSuccessful = ActivityManager.isStartResultSuccessful(result);
- final boolean taskAlwaysOnTop = options != null && options.getTaskAlwaysOnTop();
- // Apply setAlwaysOnTop when starting an Activity is successful regardless of creating
- // a new Activity or recycling the existing Activity.
- if (taskAlwaysOnTop && startResultSuccessful) {
- final Task targetRootTask =
- mTargetRootTask != null ? mTargetRootTask : mTargetTask.getRootTask();
- targetRootTask.setAlwaysOnTop(true);
- }
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
- startedActivityRootTask = handleStartResult(r, result);
+ startedActivityRootTask = handleStartResult(r, options, result, newTransition,
+ remoteTransition);
mService.continueWindowLayout();
- mSupervisor.mUserLeaving = false;
-
- // Transition housekeeping
- if (!startResultSuccessful) {
- if (newTransition != null) {
- newTransition.abort();
- }
- } else {
- if (!mAvoidMoveToFront && mDoResume
- && mRootWindowContainer.hasVisibleWindowAboveButDoesNotOwnNotificationShade(
- r.launchedFromUid)) {
- // If the UID launching the activity has a visible window on top of the
- // notification shade and it's launching an activity that's going to be at the
- // front, we should move the shade out of the way so the user can see it.
- // We want to avoid the case where the activity is launched on top of a
- // background task which is not moved to the front.
- StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal();
- if (statusBar != null) {
- // This results in a async call since the interface is one-way
- statusBar.collapsePanels();
- }
- }
- final boolean started = result == START_SUCCESS || result == START_TASK_TO_FRONT;
- if (started) {
- // The activity is started new rather than just brought forward, so record
- // it as an existence change.
- transitionController.collectExistenceChange(r);
- } else if (result == START_DELIVERED_TO_TOP && newTransition != null) {
- // We just delivered to top, so there isn't an actual transition here
- newTransition.abort();
- newTransition = null;
- }
- if (isTransient) {
- // `r` isn't guaranteed to be the actual relevant activity, so we must wait
- // until after we launched to identify the relevant activity.
- transitionController.setTransientLaunch(mLastStartActivityRecord,
- mPriorAboveTask);
- }
- if (newTransition != null) {
- transitionController.requestStartTransition(newTransition,
- mTargetTask == null ? r.getTask() : mTargetTask,
- remoteTransition, null /* displayChange */);
- } else if (started) {
- // Make the collecting transition wait until this request is ready.
- transitionController.setReady(r, false);
- }
- }
}
-
postStartActivityProcessing(r, result, startedActivityRootTask);
return result;
@@ -1695,40 +1655,89 @@
*
* @return the root task where the successful started activity resides.
*/
- private @Nullable Task handleStartResult(@NonNull ActivityRecord started, int result) {
+ private @Nullable Task handleStartResult(@NonNull ActivityRecord started,
+ ActivityOptions options, int result, Transition newTransition,
+ RemoteTransition remoteTransition) {
+ mSupervisor.mUserLeaving = false;
final Task currentRootTask = started.getRootTask();
- Task startedActivityRootTask = currentRootTask != null ? currentRootTask : mTargetRootTask;
+ final Task startedActivityRootTask =
+ currentRootTask != null ? currentRootTask : mTargetRootTask;
- if (ActivityManager.isStartResultSuccessful(result)) {
- if (startedActivityRootTask != null) {
- // If there is no state change (e.g. a resumed activity is reparented to top of
- // another display) to trigger a visibility/configuration checking, we have to
- // update the configuration for changing to different display.
- final ActivityRecord currentTop = startedActivityRootTask.topRunningActivity();
- if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
- mRootWindowContainer.ensureVisibilityAndConfig(
- currentTop, currentTop.getDisplayId(),
- true /* markFrozenIfConfigChanged */, false /* deferResume */);
- }
+ if (!ActivityManager.isStartResultSuccessful(result) || startedActivityRootTask == null) {
+ // If we are not able to proceed, disassociate the activity from the task. Leaving an
+ // activity in an incomplete state can lead to issues, such as performing operations
+ // without a window container.
+ if (mStartActivity.getTask() != null) {
+ mStartActivity.finishIfPossible("startActivity", true /* oomAdj */);
+ } else if (mStartActivity.getParent() != null) {
+ mStartActivity.getParent().removeChild(mStartActivity);
}
- return startedActivityRootTask;
+
+ // Root task should also be detached from display and be removed if it's empty.
+ if (startedActivityRootTask != null && startedActivityRootTask.isAttached()
+ && !startedActivityRootTask.hasActivity()
+ && !startedActivityRootTask.isActivityTypeHome()) {
+ startedActivityRootTask.removeIfPossible("handleStartResult");
+ }
+ if (newTransition != null) {
+ newTransition.abort();
+ }
+ return null;
}
- // If we are not able to proceed, disassociate the activity from the task. Leaving an
- // activity in an incomplete state can lead to issues, such as performing operations
- // without a window container.
- if (mStartActivity.getTask() != null) {
- mStartActivity.finishIfPossible("startActivity", true /* oomAdj */);
- } else if (mStartActivity.getParent() != null) {
- mStartActivity.getParent().removeChild(mStartActivity);
+ // Apply setAlwaysOnTop when starting an activity is successful regardless of creating
+ // a new Activity or reusing the existing activity.
+ if (options != null && options.getTaskAlwaysOnTop()) {
+ startedActivityRootTask.setAlwaysOnTop(true);
}
- // Root task should also be detached from display and be removed if it's empty.
- if (startedActivityRootTask != null && startedActivityRootTask.isAttached()
- && !startedActivityRootTask.hasActivity()
- && !startedActivityRootTask.isActivityTypeHome()) {
- startedActivityRootTask.removeIfPossible("handleStartResult");
- startedActivityRootTask = null;
+ // If there is no state change (e.g. a resumed activity is reparented to top of
+ // another display) to trigger a visibility/configuration checking, we have to
+ // update the configuration for changing to different display.
+ final ActivityRecord currentTop = startedActivityRootTask.topRunningActivity();
+ if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
+ mRootWindowContainer.ensureVisibilityAndConfig(
+ currentTop, currentTop.getDisplayId(),
+ true /* markFrozenIfConfigChanged */, false /* deferResume */);
+ }
+
+ if (!mAvoidMoveToFront && mDoResume && mRootWindowContainer
+ .hasVisibleWindowAboveButDoesNotOwnNotificationShade(started.launchedFromUid)) {
+ // If the UID launching the activity has a visible window on top of the notification
+ // shade and it's launching an activity that's going to be at the front, we should move
+ // the shade out of the way so the user can see it. We want to avoid the case where the
+ // activity is launched on top of a background task which is not moved to the front.
+ final StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal();
+ if (statusBar != null) {
+ // This results in a async call since the interface is one-way.
+ statusBar.collapsePanels();
+ }
+ }
+
+ // Transition housekeeping.
+ final TransitionController transitionController = started.mTransitionController;
+ final boolean isStarted = result == START_SUCCESS || result == START_TASK_TO_FRONT;
+ if (isStarted) {
+ // The activity is started new rather than just brought forward, so record it as an
+ // existence change.
+ transitionController.collectExistenceChange(started);
+ } else if (result == START_DELIVERED_TO_TOP && newTransition != null) {
+ // We just delivered to top, so there isn't an actual transition here.
+ newTransition.abort();
+ newTransition = null;
+ }
+ if (options != null && options.getTransientLaunch()) {
+ // `started` isn't guaranteed to be the actual relevant activity, so we must wait
+ // until after we launched to identify the relevant activity.
+ transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask);
+ }
+ if (newTransition != null) {
+ transitionController.requestStartTransition(newTransition,
+ mTargetTask == null ? started.getTask() : mTargetTask,
+ remoteTransition, null /* displayChange */);
+ } else if (isStarted) {
+ // Make the collecting transition wait until this request is ready.
+ transitionController.setReady(started, false);
}
return startedActivityRootTask;
}
@@ -2951,7 +2960,8 @@
final boolean onTop =
(aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
- return mRootWindowContainer.getOrCreateRootTask(r, aOptions, task, mSourceRootTask, onTop,
+ final Task sourceTask = mSourceRecord != null ? mSourceRecord.getTask() : null;
+ return mRootWindowContainer.getOrCreateRootTask(r, aOptions, task, sourceTask, onTop,
mLaunchParams, launchFlags);
}
@@ -3169,7 +3179,6 @@
}
void dump(PrintWriter pw, String prefix) {
- prefix = prefix + " ";
pw.print(prefix);
pw.print("mCurrentUser=");
pw.println(mRootWindowContainer.mCurrentUser);
@@ -3215,7 +3224,7 @@
pw.print(" mDoResume=");
pw.print(mDoResume);
pw.print(" mAddingToTask=");
- pw.println(mAddingToTask);
+ pw.print(mAddingToTask);
pw.print(" mInTaskFragment=");
pw.println(mInTaskFragment);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index ad6f354..61e829f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -244,6 +244,7 @@
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.server.LocalManagerRegistry;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
@@ -260,6 +261,7 @@
import com.android.server.firewall.IntentFirewall;
import com.android.server.pm.UserManagerService;
import com.android.server.policy.PermissionPolicyInternal;
+import com.android.server.sdksandbox.SdkSandboxManagerLocal;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriGrantsManagerInternal;
@@ -421,30 +423,6 @@
// How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
- // Permission tokens are used to temporarily granted a trusted app the ability to call
- // #startActivityAsCaller. A client is expected to dump its token after this time has elapsed,
- // showing any appropriate error messages to the user.
- private static final long START_AS_CALLER_TOKEN_TIMEOUT =
- 10 * MINUTE_IN_MILLIS;
-
- // How long before the service actually expires a token. This is slightly longer than
- // START_AS_CALLER_TOKEN_TIMEOUT, to provide a buffer so clients will rarely encounter the
- // expiration exception.
- private static final long START_AS_CALLER_TOKEN_TIMEOUT_IMPL =
- START_AS_CALLER_TOKEN_TIMEOUT + 2 * 1000;
-
- // How long the service will remember expired tokens, for the purpose of providing error
- // messaging when a client uses an expired token.
- private static final long START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT =
- START_AS_CALLER_TOKEN_TIMEOUT_IMPL + 20 * MINUTE_IN_MILLIS;
-
- // The component name of the delegated activities that are allowed to call
- // #startActivityAsCaller with the one-time used permission token.
- final HashMap<IBinder, ComponentName> mStartActivitySources = new HashMap<>();
-
- // Permission tokens that have expired, but we remember for error reporting.
- final ArrayList<IBinder> mExpiredStartAsCallerTokens = new ArrayList<>();
-
private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
// Keeps track of the active voice interaction service component, notified from
@@ -1236,6 +1214,15 @@
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
+ if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
+ SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
+ SdkSandboxManagerLocal.class);
+ if (sdkSandboxManagerLocal == null) {
+ throw new IllegalStateException("SdkSandboxManagerLocal not found when starting"
+ + " an activity from an SDK sandbox uid.");
+ }
+ sdkSandboxManagerLocal.enforceAllowedToStartActivity(intent);
+ }
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
@@ -1547,41 +1534,19 @@
}
@Override
- public IBinder requestStartActivityPermissionToken(ComponentName componentName) {
- int callingUid = Binder.getCallingUid();
- if (UserHandle.getAppId(callingUid) != SYSTEM_UID) {
- throw new SecurityException("Only the system process can request a permission token, "
- + "received request from uid: " + callingUid);
- }
- IBinder permissionToken = new Binder();
- synchronized (mGlobalLock) {
- mStartActivitySources.put(permissionToken, componentName);
- }
-
- Message expireMsg = PooledLambda.obtainMessage(
- ActivityTaskManagerService::expireStartAsCallerTokenMsg, this, permissionToken);
- mUiHandler.sendMessageDelayed(expireMsg, START_AS_CALLER_TOKEN_TIMEOUT_IMPL);
-
- Message forgetMsg = PooledLambda.obtainMessage(
- ActivityTaskManagerService::forgetStartAsCallerTokenMsg, this, permissionToken);
- mUiHandler.sendMessageDelayed(forgetMsg, START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT);
-
- return permissionToken;
- }
-
- @Override
public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, IBinder permissionToken,
+ int startFlags, ProfilerInfo profilerInfo, Bundle bOptions,
boolean ignoreTargetSecurity, int userId) {
// This is very dangerous -- it allows you to perform a start activity (including
// permission grants) as any app that may launch one of your own activities. So we only
// allow this in two cases:
- // 1) The caller is an activity that is part of the core framework, and then only when it
- // is running as the system.
- // 2) The caller provides a valid permissionToken. Permission tokens are one-time use and
- // can only be requested from system uid, which may then delegate this call to
- // another app.
+ // 1) The calling process holds the signature permission START_ACTIVITY_AS_CALLER
+ //
+ // 2) The calling process is an activity belonging to the package "android" which is
+ // running as UID_SYSTEM or as the target UID (the activity which started the activity
+ // calling this method).
+
final ActivityRecord sourceRecord;
final int targetUid;
final String targetPackage;
@@ -1600,26 +1565,8 @@
throw new SecurityException("Called without a process attached to activity");
}
- final ComponentName componentName;
- if (permissionToken != null) {
- // To even attempt to use a permissionToken, an app must also have this signature
- // permission.
- mAmInternal.enforceCallingPermission(
- android.Manifest.permission.START_ACTIVITY_AS_CALLER,
- "startActivityAsCaller");
- // If called with a permissionToken, the caller must be the same component that
- // was allowed to use the permissionToken.
- componentName = mStartActivitySources.remove(permissionToken);
- if (!sourceRecord.mActivityComponent.equals(componentName)) {
- if (mExpiredStartAsCallerTokens.contains(permissionToken)) {
- throw new SecurityException("Called with expired permission token: "
- + permissionToken);
- } else {
- throw new SecurityException("Called with invalid permission token: "
- + permissionToken);
- }
- }
- } else {
+ if (checkCallingPermission(Manifest.permission.START_ACTIVITY_AS_CALLER)
+ != PERMISSION_GRANTED) {
// Whether called directly or from a delegate, the source activity must be from the
// android package.
if (!sourceRecord.info.packageName.equals("android")) {
@@ -4453,15 +4400,6 @@
Settings.System.putConfigurationForUser(resolver, config, userId);
}
- private void expireStartAsCallerTokenMsg(IBinder permissionToken) {
- mStartActivitySources.remove(permissionToken);
- mExpiredStartAsCallerTokens.add(permissionToken);
- }
-
- private void forgetStartAsCallerTokenMsg(IBinder permissionToken) {
- mExpiredStartAsCallerTokens.remove(permissionToken);
- }
-
boolean isActivityStartsLoggingEnabled() {
return mAmInternal.isActivityStartsLoggingEnabled();
}
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index a31d860..0b4d887 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -666,22 +666,19 @@
"Override with TaskFragment remote animation for transit=%s",
AppTransition.appTransitionOldToString(transit));
- final boolean hasUntrustedEmbedding = task.forAllLeafTasks(
- taskFragment -> !taskFragment.isAllowedToBeEmbeddedInTrustedMode());
final RemoteAnimationController remoteAnimationController =
mDisplayContent.mAppTransition.getRemoteAnimationController();
- if (hasUntrustedEmbedding && remoteAnimationController != null) {
- // We are going to use client-driven animation, but the Task is in untrusted embedded
- // mode. We need to disable all input on activity windows during the animation to
- // ensure it is safe. This is needed for all activity windows in the animation Task.
+ if (remoteAnimationController != null) {
+ // We are going to use client-driven animation, Disable all input on activity windows
+ // during the animation to ensure it is safe to allow client to animate the surfaces.
+ // This is needed for all activity windows in the animation Task.
remoteAnimationController.setOnRemoteAnimationReady(() -> {
final Consumer<ActivityRecord> updateActivities =
activity -> activity.setDropInputForAnimation(true);
task.forAllActivities(updateActivities);
});
- ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "Task=%d contains embedded TaskFragment in"
- + " untrusted mode. Disabled all input during TaskFragment remote animation.",
- task.mTaskId);
+ ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "Task=%d contains embedded TaskFragment."
+ + " Disabled all input during TaskFragment remote animation.", task.mTaskId);
}
return true;
}
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index 5c1ddd9..6e205be 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -30,6 +30,8 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
+import java.util.ArrayList;
+
/**
* Utility class for collecting WindowContainers that will merge transactions.
* For example to use to synchronously resize all the children of a window container
@@ -64,9 +66,17 @@
void onTransactionReady(int mSyncId, SurfaceControl.Transaction transaction);
}
- interface SyncEngineListener {
- /** Called when there is no more active sync set. */
- void onSyncEngineFree();
+ /**
+ * Represents the desire to make a {@link BLASTSyncEngine.SyncGroup} while another is active.
+ *
+ * @see #queueSyncSet
+ */
+ private static class PendingSyncSet {
+ /** Called immediately when the {@link BLASTSyncEngine} is free. */
+ private Runnable mStartSync;
+
+ /** Posted to the main handler after {@link #mStartSync} is called. */
+ private Runnable mApplySync;
}
/**
@@ -142,8 +152,21 @@
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
mActiveSyncs.remove(mSyncId);
mWm.mH.removeCallbacks(mOnTimeout);
- if (mSyncEngineListener != null && mActiveSyncs.size() == 0) {
- mSyncEngineListener.onSyncEngineFree();
+
+ // Immediately start the next pending sync-transaction if there is one.
+ if (mActiveSyncs.size() == 0 && !mPendingSyncSets.isEmpty()) {
+ ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "PendingStartTransaction found");
+ final PendingSyncSet pt = mPendingSyncSets.remove(0);
+ pt.mStartSync.run();
+ if (mActiveSyncs.size() == 0) {
+ throw new IllegalStateException("Pending Sync Set didn't start a sync.");
+ }
+ // Post this so that the now-playing transition setup isn't interrupted.
+ mWm.mH.post(() -> {
+ synchronized (mWm.mGlobalLock) {
+ pt.mApplySync.run();
+ }
+ });
}
}
@@ -183,17 +206,18 @@
private final WindowManagerService mWm;
private int mNextSyncId = 0;
private final SparseArray<SyncGroup> mActiveSyncs = new SparseArray<>();
- private SyncEngineListener mSyncEngineListener;
+
+ /**
+ * A queue of pending sync-sets waiting for their turn to run.
+ *
+ * @see #queueSyncSet
+ */
+ private final ArrayList<PendingSyncSet> mPendingSyncSets = new ArrayList<>();
BLASTSyncEngine(WindowManagerService wms) {
mWm = wms;
}
- /** Sets listener listening to whether the sync engine is free. */
- void setSyncEngineListener(SyncEngineListener listener) {
- mSyncEngineListener = listener;
- }
-
/**
* Prepares a {@link SyncGroup} that is not active yet. Caller must call {@link #startSyncSet}
* before calling {@link #addToSyncSet(int, WindowContainer)} on any {@link WindowContainer}.
@@ -275,4 +299,31 @@
mActiveSyncs.valueAt(i).onSurfacePlacement();
}
}
+
+ /**
+ * Queues a sync operation onto this engine. It will wait until any current/prior sync-sets
+ * have finished to run. This is needed right now because currently {@link BLASTSyncEngine}
+ * only supports 1 sync at a time.
+ *
+ * Code-paths should avoid using this unless absolutely necessary. Usually, we use this for
+ * difficult edge-cases that we hope to clean-up later.
+ *
+ * @param startSync will be called immediately when the {@link BLASTSyncEngine} is free to
+ * "reserve" the {@link BLASTSyncEngine} by calling one of the
+ * {@link BLASTSyncEngine#startSyncSet} variants.
+ * @param applySync will be posted to the main handler after {@code startSync} has been
+ * called. This is posted so that it doesn't interrupt any clean-up for the
+ * prior sync-set.
+ */
+ void queueSyncSet(@NonNull Runnable startSync, @NonNull Runnable applySync) {
+ final PendingSyncSet pt = new PendingSyncSet();
+ pt.mStartSync = startSync;
+ pt.mApplySync = applySync;
+ mPendingSyncSets.add(pt);
+ }
+
+ /** @return {@code true} if there are any sync-sets waiting to start. */
+ boolean hasPendingSyncSets() {
+ return !mPendingSyncSets.isEmpty();
+ }
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 61cd221..8eb0046 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -4071,12 +4071,12 @@
t.setColorSpace(activity.mSurfaceControl, ColorSpace.get(ColorSpace.Named.SRGB));
t.setLayer(imeSurface, 1);
- final Point surfacePosition = new Point(
- imeWindow.getFrame().left - mImeTarget.getFrame().left,
- imeWindow.getFrame().top - mImeTarget.getFrame().top);
+ final Point surfacePosition = new Point(imeWindow.getFrame().left,
+ imeWindow.getFrame().top);
if (imeParent == activity.getSurfaceControl()) {
t.setPosition(imeSurface, surfacePosition.x, surfacePosition.y);
} else {
+ surfacePosition.offset(-mImeTarget.getFrame().left, -mImeTarget.getFrame().top);
surfacePosition.offset(mImeTarget.mAttrs.surfaceInsets.left,
mImeTarget.mAttrs.surfaceInsets.top);
t.setPosition(imeSurface, surfacePosition.x, surfacePosition.y);
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 7bf150b..2ebb597 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -28,6 +28,7 @@
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
+import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
@@ -408,6 +409,25 @@
}
/**
+ * Called when keyguard going away state changed.
+ */
+ private void handleKeyguardGoingAwayChanged(DisplayContent dc) {
+ mService.deferWindowLayout();
+ try {
+ dc.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, 0 /* transitFlags */);
+ // We are deprecating TRANSIT_KEYGUARD_GOING_AWAY for Shell transition and use
+ // TRANSIT_FLAG_KEYGUARD_GOING_AWAY to indicate that it should animate keyguard going
+ // away.
+ dc.mAtmService.getTransitionController().requestTransitionIfNeeded(
+ TRANSIT_OPEN, TRANSIT_FLAG_KEYGUARD_GOING_AWAY, null /* trigger */, dc);
+ updateKeyguardSleepToken();
+ mWindowManager.executeAppTransition();
+ } finally {
+ mService.continueWindowLayout();
+ }
+ }
+
+ /**
* Called when somebody wants to dismiss the Keyguard via the flag.
*/
private void handleDismissKeyguard(int displayId) {
@@ -533,11 +553,13 @@
}
/**
- * Updates {@link #mOccluded}, {@link #mTopTurnScreenOnActivity} and
- * {@link #mDismissingKeyguardActivity} if the top task could be visible.
+ * Updates keyguard status if the top task could be visible. The top task may occlude
+ * keyguard, request to dismiss keyguard or make insecure keyguard go away based on its
+ * properties.
*/
void updateVisibility(KeyguardController controller, DisplayContent display) {
final boolean lastOccluded = mOccluded;
+ final boolean lastKeyguardGoingAway = mKeyguardGoingAway;
final ActivityRecord lastDismissKeyguardActivity = mDismissingKeyguardActivity;
final ActivityRecord lastTurnScreenOnActivity = mTopTurnScreenOnActivity;
@@ -561,14 +583,18 @@
mTopTurnScreenOnActivity = top;
}
- final boolean showWhenLocked = top.canShowWhenLocked();
- if (showWhenLocked) {
+ final boolean isKeyguardSecure = controller.mWindowManager.isKeyguardSecure(
+ controller.mService.getCurrentUserId());
+ if (top.mDismissKeyguardIfInsecure && mKeyguardShowing && !isKeyguardSecure) {
+ mKeyguardGoingAway = true;
+ } else if (top.canShowWhenLocked()) {
mTopOccludesActivity = top;
}
// Only the top activity may control occluded, as we can't occlude the Keyguard
// if the top app doesn't want to occlude it.
- occludedByActivity = showWhenLocked || (mDismissingKeyguardActivity != null
+ occludedByActivity = mTopOccludesActivity != null
+ || (mDismissingKeyguardActivity != null
&& task.topRunningActivity() == mDismissingKeyguardActivity
&& controller.canShowWhileOccluded(
true /* dismissKeyguard */, false /* showWhenLocked */));
@@ -583,10 +609,8 @@
&& top.getActivityType() == ACTIVITY_TYPE_DREAM);
mOccluded = mShowingDream || occludedByActivity;
mRequestDismissKeyguard = lastDismissKeyguardActivity != mDismissingKeyguardActivity
- && !mOccluded
- && mDismissingKeyguardActivity != null
- && controller.mWindowManager.isKeyguardSecure(
- controller.mService.getCurrentUserId());
+ && !mOccluded && !mKeyguardGoingAway
+ && mDismissingKeyguardActivity != null;
if (mTopTurnScreenOnActivity != lastTurnScreenOnActivity
&& mTopTurnScreenOnActivity != null
@@ -598,6 +622,8 @@
if (lastOccluded != mOccluded) {
controller.handleOccludedChanged(mDisplayId, mTopOccludesActivity);
+ } else if (!lastKeyguardGoingAway && mKeyguardGoingAway) {
+ controller.handleKeyguardGoingAwayChanged(display);
}
}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 9ad25ac8..f75a06d 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -116,6 +116,8 @@
private float mLastReportedAnimatorScale;
private String mPackageName;
private String mRelayoutTag;
+ private String mUpdateViewVisibilityTag;
+ private String mUpdateWindowLayoutTag;
private final InsetsVisibilities mDummyRequestedVisibilities = new InsetsVisibilities();
private final InsetsSourceControl[] mDummyControls = new InsetsSourceControl[0];
final boolean mSetsUnrestrictedKeepClearAreas;
@@ -223,6 +225,27 @@
}
@Override
+ public int updateVisibility(IWindow client, WindowManager.LayoutParams attrs,
+ int viewVisibility, MergedConfiguration outMergedConfiguration,
+ SurfaceControl outSurfaceControl, InsetsState outInsetsState,
+ InsetsSourceControl[] outActiveControls) {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mUpdateViewVisibilityTag);
+ int res = mService.updateViewVisibility(this, client, attrs, viewVisibility,
+ outMergedConfiguration, outSurfaceControl, outInsetsState, outActiveControls);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ return res;
+ }
+
+ @Override
+ public void updateLayout(IWindow window, WindowManager.LayoutParams attrs, int flags,
+ ClientWindowFrames clientFrames, int requestedWidth, int requestedHeight) {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mUpdateWindowLayoutTag);
+ mService.updateWindowLayout(this, window, attrs, flags, clientFrames, requestedWidth,
+ requestedHeight);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ }
+
+ @Override
public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) {
mService.setWillReplaceWindows(appToken, childrenOnly);
}
@@ -689,6 +712,8 @@
if (wpc != null) {
mPackageName = wpc.mInfo.packageName;
mRelayoutTag = "relayoutWindow: " + mPackageName;
+ mUpdateViewVisibilityTag = "updateVisibility: " + mPackageName;
+ mUpdateWindowLayoutTag = "updateLayout: " + mPackageName;
} else {
Slog.e(TAG_WM, "Unknown process pid=" + mPid);
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index f3cefca..731a045 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -2360,6 +2360,20 @@
return parentTask == null ? null : parentTask.getOrganizedTask();
}
+ /** @return the first create-by-organizer task. */
+ @Nullable
+ Task getCreatedByOrganizerTask() {
+ if (mCreatedByOrganizer) {
+ return this;
+ }
+ final WindowContainer parent = getParent();
+ if (parent == null) {
+ return null;
+ }
+ final Task parentTask = parent.asTask();
+ return parentTask == null ? null : parentTask.getCreatedByOrganizerTask();
+ }
+
// TODO(task-merge): Figure out what's the right thing to do for places that used it.
boolean isRootTask() {
return getRootTask() == this;
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index 3b79274..61963c4 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -20,6 +20,7 @@
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ITaskStackListener;
import android.app.TaskInfo;
+import android.app.TaskStackListener;
import android.content.ComponentName;
import android.os.Binder;
import android.os.Handler;
@@ -286,6 +287,9 @@
if (listener instanceof Binder) {
synchronized (mLocalTaskStackListeners) {
if (!mLocalTaskStackListeners.contains(listener)) {
+ if (listener instanceof TaskStackListener) {
+ ((TaskStackListener) listener).setIsLocal();
+ }
mLocalTaskStackListeners.add(listener);
}
}
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 7bb7870..7a7bf1f 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1125,9 +1125,9 @@
if ((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0
&& mLaunchAdjacentFlagRootTask != null) {
// If the adjacent launch is coming from the same root, launch to adjacent root instead.
- if (sourceTask != null
- && sourceTask.getRootTask().mTaskId == mLaunchAdjacentFlagRootTask.mTaskId
- && mLaunchAdjacentFlagRootTask.getAdjacentTaskFragment() != null) {
+ if (sourceTask != null && mLaunchAdjacentFlagRootTask.getAdjacentTaskFragment() != null
+ && (sourceTask == mLaunchAdjacentFlagRootTask
+ || sourceTask.isDescendantOf(mLaunchAdjacentFlagRootTask))) {
return mLaunchAdjacentFlagRootTask.getAdjacentTaskFragment().asTask();
} else {
return mLaunchAdjacentFlagRootTask;
@@ -1141,18 +1141,22 @@
? launchRootTask.getAdjacentTaskFragment() : null;
final Task adjacentRootTask =
adjacentTaskFragment != null ? adjacentTaskFragment.asTask() : null;
- if (sourceTask != null && sourceTask.getRootTask() == adjacentRootTask) {
+ if (sourceTask != null && adjacentRootTask != null
+ && (sourceTask == adjacentRootTask
+ || sourceTask.isDescendantOf(adjacentRootTask))) {
return adjacentRootTask;
} else {
return launchRootTask;
}
}
}
- // For better split UX, If task launch by the source task which root task is created by
- // organizer, it should also launch in that root too.
- if (sourceTask != null && sourceTask.getRootTask().mCreatedByOrganizer) {
- return sourceTask.getRootTask();
+
+ // For a better split UX, If a task is launching from a created-by-organizer task, it should
+ // be launched into the same created-by-organizer task as well.
+ if (sourceTask != null) {
+ return sourceTask.getCreatedByOrganizerTask();
}
+
return null;
}
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index b8b151f..18a7640 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -31,6 +31,7 @@
import android.app.WindowConfiguration;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
+import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
@@ -250,7 +251,13 @@
// possible.
while (!mOrganizedTasks.isEmpty()) {
final Task t = mOrganizedTasks.get(0);
- t.updateTaskOrganizerState(true /* forceUpdate */);
+ if (t.mCreatedByOrganizer) {
+ // The tasks created by this organizer should ideally be deleted when this
+ // organizer is disposed off to avoid inconsistent behavior.
+ t.removeImmediately();
+ } else {
+ t.updateTaskOrganizerState(true /* forceUpdate */);
+ }
if (mOrganizedTasks.contains(t)) {
// updateTaskOrganizerState should remove the task from the list, but still
// check it again to avoid while-loop isn't terminate.
@@ -474,10 +481,12 @@
}
}
- static SurfaceControl applyStartingWindowAnimation(WindowContainer window) {
+ static SurfaceControl applyStartingWindowAnimation(WindowState window) {
+ final SurfaceControl.Transaction t = window.getPendingTransaction();
+ final Rect mainFrame = window.getRelativeFrame();
final StartingWindowAnimationAdaptor adaptor = new StartingWindowAnimationAdaptor();
- window.startAnimation(window.getPendingTransaction(), adaptor, false,
- ANIMATION_TYPE_STARTING_REVEAL);
+ window.startAnimation(t, adaptor, false, ANIMATION_TYPE_STARTING_REVEAL);
+ t.setPosition(adaptor.mAnimationLeash, mainFrame.left, mainFrame.top);
return adaptor.mAnimationLeash;
}
@@ -530,8 +539,6 @@
final SurfaceControl.Transaction t = mainWindow.getPendingTransaction();
removalInfo.windowAnimationLeash = applyStartingWindowAnimation(mainWindow);
removalInfo.mainFrame = mainWindow.getRelativeFrame();
- t.setPosition(removalInfo.windowAnimationLeash,
- removalInfo.mainFrame.left, removalInfo.mainFrame.top);
}
}
}
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index cde9927..814656d 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -480,12 +480,17 @@
}
final HardwareBuffer buffer = screenshotBuffer == null ? null
: screenshotBuffer.getHardwareBuffer();
- if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
+ if (isInvalidHardwareBuffer(buffer)) {
return null;
}
return screenshotBuffer;
}
+ static boolean isInvalidHardwareBuffer(HardwareBuffer buffer) {
+ return buffer == null || buffer.isClosed() // This must be checked before getting size.
+ || buffer.getWidth() <= 1 || buffer.getHeight() <= 1;
+ }
+
@Nullable
TaskSnapshot snapshotTask(Task task) {
return snapshotTask(task, PixelFormat.UNKNOWN);
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 9fbcd7c..03098e3 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -407,6 +407,10 @@
}
boolean writeBuffer() {
+ if (TaskSnapshotController.isInvalidHardwareBuffer(mSnapshot.getHardwareBuffer())) {
+ Slog.e(TAG, "Invalid task snapshot hw buffer, taskId=" + mTaskId);
+ return false;
+ }
final Bitmap bitmap = Bitmap.wrapHardwareBuffer(
mSnapshot.getHardwareBuffer(), mSnapshot.getColorSpace());
if (bitmap == null) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index a0d68a1..973f983 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -189,6 +189,9 @@
private boolean mNavBarAttachedToApp = false;
private int mRecentsDisplayId = INVALID_DISPLAY;
+ /** @see #setCanPipOnFinish */
+ private boolean mCanPipOnFinish = true;
+
Transition(@TransitionType int type, @TransitionFlags int flags,
TransitionController controller, BLASTSyncEngine syncEngine) {
mType = type;
@@ -448,6 +451,15 @@
}
/**
+ * Set whether this transition can start a pip-enter transition when finished. This is usually
+ * true, but gets set to false when recents decides that it wants to finish its animation but
+ * not actually finish its animation (yeah...).
+ */
+ void setCanPipOnFinish(boolean canPipOnFinish) {
+ mCanPipOnFinish = canPipOnFinish;
+ }
+
+ /**
* The transition has finished animating and is ready to finalize WM state. This should not
* be called directly; use {@link TransitionController#finishTransition} instead.
*/
@@ -475,7 +487,7 @@
// activity in a bad state.
if (!visibleAtTransitionEnd && !ar.isVisibleRequested()) {
boolean commitVisibility = true;
- if (ar.isVisible() && ar.getTask() != null) {
+ if (mCanPipOnFinish && ar.isVisible() && ar.getTask() != null) {
if (ar.pictureInPictureArgs != null
&& ar.pictureInPictureArgs.isAutoEnterEnabled()) {
if (mTransientLaunches != null) {
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 18851b3..23479a2 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -99,9 +99,6 @@
// TODO(b/188595497): remove when not needed.
final StatusBarManagerInternal mStatusBar;
- /** Pending transitions from Shell that are waiting the SyncEngine to be free. */
- private final ArrayList<PendingStartTransition> mPendingTransitions = new ArrayList<>();
-
TransitionController(ActivityTaskManagerService atm,
TaskSnapshotController taskSnapshotController) {
mAtm = atm;
@@ -146,7 +143,7 @@
}
/** Starts Collecting */
- private void moveToCollecting(@NonNull Transition transition) {
+ void moveToCollecting(@NonNull Transition transition) {
if (mCollectingTransition != null) {
throw new IllegalStateException("Simultaneous transition collection not supported.");
}
@@ -160,26 +157,6 @@
dispatchLegacyAppTransitionPending();
}
- /** Creates a transition representation but doesn't start collecting. */
- @NonNull
- PendingStartTransition createPendingTransition(@WindowManager.TransitionType int type) {
- if (mTransitionPlayer == null) {
- throw new IllegalStateException("Shell Transitions not enabled");
- }
- final PendingStartTransition out = new PendingStartTransition(new Transition(type,
- 0 /* flags */, this, mAtm.mWindowManager.mSyncEngine));
- mPendingTransitions.add(out);
- // We want to start collecting immediately when the engine is free, otherwise it may
- // be busy again.
- out.setStartSync(() -> {
- mPendingTransitions.remove(out);
- moveToCollecting(out.mTransition);
- });
- ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Creating PendingTransition: %s",
- out.mTransition);
- return out;
- }
-
void registerTransitionPlayer(@Nullable ITransitionPlayer player,
@Nullable IApplicationThread appThread) {
try {
@@ -601,24 +578,16 @@
if (!mPlayingTransitions.isEmpty()) {
state = LEGACY_STATE_RUNNING;
} else if ((mCollectingTransition != null && mCollectingTransition.getLegacyIsReady())
- || !mPendingTransitions.isEmpty()) {
- // The transition may not be "ready", but we have transition waiting to start, so it
- // can't be IDLE for test purpose. Ideally, we should have a STATE_COLLECTING.
+ || mAtm.mWindowManager.mSyncEngine.hasPendingSyncSets()) {
+ // The transition may not be "ready", but we have a sync-transaction waiting to start.
+ // Usually the pending transaction is for a transition, so assuming that is the case,
+ // we can't be IDLE for test purposes. Ideally, we should have a STATE_COLLECTING.
state = LEGACY_STATE_READY;
}
proto.write(AppTransitionProto.APP_TRANSITION_STATE, state);
proto.end(token);
}
- /** Represents a startTransition call made while there is other active BLAST SyncGroup. */
- class PendingStartTransition extends WindowOrganizerController.PendingTransaction {
- final Transition mTransition;
-
- PendingStartTransition(Transition transition) {
- mTransition = transition;
- }
- }
-
static class TransitionMetricsReporter extends ITransitionMetricsReporter.Stub {
private final ArrayMap<IBinder, LongConsumer> mMetricConsumers = new ArrayMap<>();
diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java
index a307ee8..1cb6303 100644
--- a/services/core/java/com/android/server/wm/WindowFrames.java
+++ b/services/core/java/com/android/server/wm/WindowFrames.java
@@ -81,6 +81,8 @@
private boolean mContentChanged;
+ private boolean mInsetsChanged;
+
public void setFrames(Rect parentFrame, Rect displayFrame) {
mParentFrame.set(parentFrame);
mDisplayFrame.set(displayFrame);
@@ -158,6 +160,20 @@
return mContentChanged;
}
+ /**
+ * Sets whether we need to report {@link android.view.InsetsState} to the client.
+ */
+ void setInsetsChanged(boolean insetsChanged) {
+ mInsetsChanged = insetsChanged;
+ }
+
+ /**
+ * @see #setInsetsChanged(boolean)
+ */
+ boolean hasInsetsChanged() {
+ return mInsetsChanged;
+ }
+
public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
mParentFrame.dumpDebug(proto, PARENT_FRAME);
@@ -169,9 +185,10 @@
public void dump(PrintWriter pw, String prefix) {
pw.println(prefix + "Frames: parent=" + mParentFrame.toShortString(sTmpSB)
- + " display=" + mDisplayFrame.toShortString(sTmpSB));
- pw.println(prefix + "mFrame=" + mFrame.toShortString(sTmpSB)
- + " last=" + mLastFrame.toShortString(sTmpSB));
+ + " display=" + mDisplayFrame.toShortString(sTmpSB)
+ + " frame=" + mFrame.toShortString(sTmpSB)
+ + " last=" + mLastFrame.toShortString(sTmpSB)
+ + " insetsChanged=" + mInsetsChanged);
}
String getInsetsChangedInfo() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7165854..cbb39d2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -709,6 +709,9 @@
// State while inside of layoutAndPlaceSurfacesLocked().
boolean mFocusMayChange;
+ // Number of windows whose insets state have been changed.
+ int mWindowsInsetsChanged = 0;
+
// This is held as long as we have the screen frozen, to give us time to
// perform a rotation animation when turning off shows the lock screen which
// changes the orientation.
@@ -2627,6 +2630,19 @@
return result;
}
+ int updateViewVisibility(Session session, IWindow client, LayoutParams attrs,
+ int viewVisibility, MergedConfiguration outMergedConfiguration,
+ SurfaceControl outSurfaceControl, InsetsState outInsetsState,
+ InsetsSourceControl[] outActiveControls) {
+ // TODO(b/161810301): Finish the implementation.
+ return 0;
+ }
+
+ void updateWindowLayout(Session session, IWindow client, LayoutParams attrs, int flags,
+ ClientWindowFrames clientWindowFrames, int requestedWidth, int requestedHeight) {
+ // TODO(b/161810301): Finish the implementation.
+ }
+
public boolean outOfMemoryWindow(Session session, IWindow client) {
final long origId = Binder.clearCallingIdentity();
@@ -5205,6 +5221,7 @@
public static final int LAYOUT_AND_ASSIGN_WINDOW_LAYERS_IF_NEEDED = 63;
public static final int WINDOW_STATE_BLAST_SYNC_TIMEOUT = 64;
public static final int REPARENT_TASK_TO_DEFAULT_DISPLAY = 65;
+ public static final int INSETS_CHANGED = 66;
/**
* Used to denote that an integer field in a message will not be used.
@@ -5531,6 +5548,17 @@
}
break;
}
+ case INSETS_CHANGED: {
+ synchronized (mGlobalLock) {
+ if (mWindowsInsetsChanged > 0) {
+ mWindowsInsetsChanged = 0;
+ // We need to update resizing windows and dispatch the new insets state
+ // to them.
+ mRoot.performSurfacePlacement();
+ }
+ }
+ break;
+ }
}
if (DEBUG_WINDOW_TRACE) {
Slog.v(TAG_WM, "handleMessage: exit");
@@ -9032,13 +9060,18 @@
}
TaskSnapshot taskSnapshot;
- synchronized (mGlobalLock) {
- Task task = mRoot.anyTaskForId(taskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
- if (task == null) {
- throw new IllegalArgumentException(
- "Failed to find matching task for taskId=" + taskId);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ Task task = mRoot.anyTaskForId(taskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
+ if (task == null) {
+ throw new IllegalArgumentException(
+ "Failed to find matching task for taskId=" + taskId);
+ }
+ taskSnapshot = mTaskSnapshotController.captureTaskSnapshot(task, false);
}
- taskSnapshot = mTaskSnapshotController.captureTaskSnapshot(task, false);
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
if (taskSnapshot == null || taskSnapshot.getHardwareBuffer() == null) {
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index fe5f675..b5cf708 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -99,7 +99,7 @@
* @see android.window.WindowOrganizer
*/
class WindowOrganizerController extends IWindowOrganizerController.Stub
- implements BLASTSyncEngine.TransactionReadyListener, BLASTSyncEngine.SyncEngineListener {
+ implements BLASTSyncEngine.TransactionReadyListener {
private static final String TAG = "WindowOrganizerController";
@@ -122,21 +122,6 @@
private final HashMap<Integer, IWindowContainerTransactionCallback>
mTransactionCallbacksByPendingSyncId = new HashMap();
- /**
- * A queue of transaction waiting for their turn to sync. Currently {@link BLASTSyncEngine} only
- * supports 1 sync at a time, so we have to queue them.
- *
- * WMCore has enough information to ensure that it won't end up collecting multiple transitions
- * in parallel by itself; however, Shell can start transitions/apply sync transaction at
- * arbitrary times via {@link WindowOrganizerController#startTransition} and
- * {@link WindowOrganizerController#applySyncTransaction}, so we have to support those coming in
- * at any time (even while already syncing).
- *
- * This is really just a back-up for unrealistic situations (eg. during tests). In practice,
- * this shouldn't ever happen.
- */
- private final ArrayList<PendingTransaction> mPendingTransactions = new ArrayList<>();
-
final TaskOrganizerController mTaskOrganizerController;
final DisplayAreaOrganizerController mDisplayAreaOrganizerController;
final TaskFragmentOrganizerController mTaskFragmentOrganizerController;
@@ -160,7 +145,6 @@
void setWindowManager(WindowManagerService wms) {
mTransitionController = new TransitionController(mService, wms.mTaskSnapshotController);
mTransitionController.registerLegacyListener(wms.mActivityManagerAppTransitionNotifier);
- wms.mSyncEngine.setSyncEngineListener(this);
}
TransitionController getTransitionController() {
@@ -231,16 +215,12 @@
} else {
// Because the BLAST engine only supports one sync at a time, queue the
// transaction.
- final PendingTransaction pt = new PendingTransaction();
- // Start sync group immediately when the SyncEngine is free.
- pt.setStartSync(() ->
- mService.mWindowManager.mSyncEngine.startSyncSet(syncGroup));
- // Those will be post so that it won't interrupt ongoing transition.
- pt.setStartTransaction(() -> {
- applyTransaction(t, syncId, null /*transition*/, caller);
- setSyncReady(syncId);
- });
- mPendingTransactions.add(pt);
+ mService.mWindowManager.mSyncEngine.queueSyncSet(
+ () -> mService.mWindowManager.mSyncEngine.startSyncSet(syncGroup),
+ () -> {
+ applyTransaction(t, syncId, null /*transition*/, caller);
+ setSyncReady(syncId);
+ });
}
return syncId;
}
@@ -283,19 +263,24 @@
// transition starts collecting. This should almost never happen except during
// tests.
if (mService.mWindowManager.mSyncEngine.hasActiveSync()) {
- Slog.e(TAG, "startTransition() while one is already collecting.");
- final TransitionController.PendingStartTransition pt =
- mTransitionController.createPendingTransition(type);
- // Those will be post so that it won't interrupt ongoing transition.
- pt.setStartTransaction(() -> {
- pt.mTransition.start();
- applyTransaction(wct, -1 /*syncId*/, pt.mTransition, caller);
- if (needsSetReady) {
- pt.mTransition.setAllReady();
- }
- });
- mPendingTransactions.add(pt);
- return pt.mTransition;
+ Slog.w(TAG, "startTransition() while one is already collecting.");
+ final Transition nextTransition = new Transition(type, 0 /* flags */,
+ mTransitionController, mService.mWindowManager.mSyncEngine);
+ ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
+ "Creating Pending Transition: %s", nextTransition);
+ mService.mWindowManager.mSyncEngine.queueSyncSet(
+ // Make sure to collect immediately to prevent another transition
+ // from sneaking in before it. Note: moveToCollecting internally
+ // calls startSyncSet.
+ () -> mTransitionController.moveToCollecting(nextTransition),
+ () -> {
+ nextTransition.start();
+ applyTransaction(wct, -1 /*syncId*/, nextTransition, caller);
+ if (needsSetReady) {
+ nextTransition.setAllReady();
+ }
+ });
+ return nextTransition;
}
transition = mTransitionController.createTransition(type);
}
@@ -426,6 +411,14 @@
}
if (transition != null) transition.collect(wc);
+ if (finishTransition != null) {
+ // Deal with edge-cases in recents where it pretends to finish itself.
+ if ((entry.getValue().getChangeMask()
+ & WindowContainerTransaction.Change.CHANGE_FORCE_NO_PIP) != 0) {
+ finishTransition.setCanPipOnFinish(false /* canPipOnFinish */);
+ }
+ }
+
int containerEffect = applyWindowContainerChange(wc, entry.getValue());
effects |= containerEffect;
@@ -1190,23 +1183,6 @@
}
@Override
- public void onSyncEngineFree() {
- if (mPendingTransactions.isEmpty()) {
- return;
- }
-
- ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "PendingStartTransaction found");
- final PendingTransaction pt = mPendingTransactions.remove(0);
- pt.startSync();
- // Post this so that the now-playing transition setup isn't interrupted.
- mService.mH.post(() -> {
- synchronized (mGlobalLock) {
- pt.startTransaction();
- }
- });
- }
-
- @Override
public void registerTransitionPlayer(ITransitionPlayer player) {
enforceTaskPermission("registerTransitionPlayer()");
final int callerPid = Binder.getCallingPid();
@@ -1555,38 +1531,4 @@
+ result + " when starting " + intent);
}
}
-
- /**
- * Represents a sync {@link WindowContainerTransaction} call made while there is other active
- * {@link BLASTSyncEngine.SyncGroup}.
- */
- static class PendingTransaction {
- private Runnable mStartSync;
- private Runnable mStartTransaction;
-
- /**
- * The callback will be called immediately when the {@link BLASTSyncEngine} is free. One
- * should call {@link BLASTSyncEngine#startSyncSet(BLASTSyncEngine.SyncGroup)} here to
- * reserve the {@link BLASTSyncEngine}.
- */
- void setStartSync(@NonNull Runnable callback) {
- mStartSync = callback;
- }
-
- /**
- * The callback will be post to the main handler after the {@link BLASTSyncEngine} is free
- * to apply the pending {@link WindowContainerTransaction}.
- */
- void setStartTransaction(@NonNull Runnable callback) {
- mStartTransaction = callback;
- }
-
- private void startSync() {
- mStartSync.run();
- }
-
- private void startTransaction() {
- mStartTransaction.run();
- }
- }
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 0ca1058..7bf7295 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1537,12 +1537,14 @@
* dimensions or insets have changed.
*/
void updateResizingWindowIfNeeded() {
- final WindowStateAnimator winAnimator = mWinAnimator;
- if (!mHasSurface || getDisplayContent().mLayoutSeq != mLayoutSeq || isGoneForLayout()) {
+ final boolean insetsChanged = mWindowFrames.hasInsetsChanged();
+ if ((!mHasSurface || getDisplayContent().mLayoutSeq != mLayoutSeq || isGoneForLayout())
+ && !insetsChanged) {
return;
}
- boolean didFrameInsetsChange = setReportResizeHints();
+ final WindowStateAnimator winAnimator = mWinAnimator;
+ final boolean didFrameInsetsChange = setReportResizeHints();
// The latest configuration will be returned by the out parameter of relayout, so it is
// unnecessary to report resize if this window is running relayout.
final boolean configChanged = !mInRelayout && !isLastConfigReportedToClient();
@@ -1567,6 +1569,7 @@
// already. This because the window is waiting on a finishDrawing from the client.
if (didFrameInsetsChange
|| configChanged
+ || insetsChanged
|| dragResizingChanged
|| mReportOrientationChanged
|| shouldSendRedrawForSync()) {
@@ -1576,6 +1579,14 @@
this, mWindowFrames.getInsetsChangedInfo(),
configChanged, dragResizingChanged, mReportOrientationChanged);
+ if (insetsChanged) {
+ mWindowFrames.setInsetsChanged(false);
+ mWmService.mWindowsInsetsChanged--;
+ if (mWmService.mWindowsInsetsChanged == 0) {
+ mWmService.mH.removeMessages(WindowManagerService.H.INSETS_CHANGED);
+ }
+ }
+
// If it's a dead window left on screen, and the configuration changed, there is nothing
// we can do about it. Remove the window now.
if (mActivityRecord != null && mAppDied) {
@@ -3962,8 +3973,8 @@
try {
mClient.resized(mClientWindowFrames, reportDraw, mLastReportedConfiguration,
- forceRelayout, alwaysConsumeSystemBars, displayId, Integer.MAX_VALUE,
- resizeMode);
+ getCompatInsetsState(), forceRelayout, alwaysConsumeSystemBars, displayId,
+ mSyncSeqId, resizeMode);
if (drawPending && reportOrientation && mOrientationChanging) {
mOrientationChangeRedrawRequestTime = SystemClock.elapsedRealtime();
ProtoLog.v(WM_DEBUG_ORIENTATION,
@@ -3992,13 +4003,14 @@
*/
void notifyInsetsChanged() {
ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "notifyInsetsChanged for %s ", this);
- try {
- mClient.insetsChanged(getCompatInsetsState(),
- hasMoved(),
- mWindowFrames.isFrameSizeChangeReported());
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to deliver inset state change w=" + this, e);
- }
+ mWindowFrames.setInsetsChanged(true);
+
+ // If the new InsetsState won't be dispatched before releasing WM lock, the following
+ // message will be executed.
+ mWmService.mWindowsInsetsChanged++;
+ mWmService.mH.removeMessages(WindowManagerService.H.INSETS_CHANGED);
+ mWmService.mH.sendEmptyMessage(WindowManagerService.H.INSETS_CHANGED);
+
final WindowContainer p = getParent();
if (p != null) {
p.updateOverlayInsetsState(this);
@@ -4015,9 +4027,7 @@
getDisplayContent().getInsetsStateController();
try {
mClient.insetsControlChanged(getCompatInsetsState(),
- stateController.getControlsForDispatch(this),
- hasMoved(),
- mWindowFrames.isFrameSizeChangeReported());
+ stateController.getControlsForDispatch(this));
} catch (RemoteException e) {
Slog.w(TAG, "Failed to deliver inset state change to w=" + this, e);
}
@@ -5288,7 +5298,7 @@
if (mControllableInsetProvider != null) {
return;
}
- if (mDisplayContent.inTransition()) {
+ if (getDisplayContent().inTransition()) {
// Skip because the animation is usually unnoticeable (e.g. covered by rotation
// animation) and the animation bounds could be inconsistent, such as depending
// on when the window applies its draw transaction with new rotation.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
index 48c4052..aca1389 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
@@ -19,6 +19,8 @@
import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+import static android.app.admin.WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST;
+import static android.app.admin.WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST;
import static com.android.server.devicepolicy.DevicePolicyManagerService.LOG_TAG;
@@ -33,7 +35,9 @@
import android.app.admin.FactoryResetProtectionPolicy;
import android.app.admin.PasswordPolicy;
import android.app.admin.PreferentialNetworkServiceConfig;
+import android.app.admin.WifiSsidPolicy;
import android.graphics.Color;
+import android.net.wifi.WifiSsid;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.UserHandle;
@@ -53,6 +57,7 @@
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -60,6 +65,7 @@
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
+import java.util.stream.Collectors;
class ActiveAdmin {
private static final String TAG_DISABLE_KEYGUARD_FEATURES = "disable-keyguard-features";
@@ -242,13 +248,8 @@
// List of package names to keep cached.
List<String> keepUninstalledPackages;
- // The allowlist of SSIDs the device may connect to.
- // By default, the allowlist restriction is deactivated.
- List<String> mSsidAllowlist;
-
- // The denylist of SSIDs the device may not connect to.
- // By default, the denylist restriction is deactivated.
- List<String> mSsidDenylist;
+ // Wi-Fi SSID restriction policy.
+ WifiSsidPolicy mWifiSsidPolicy;
// TODO: review implementation decisions with frameworks team
boolean specifiesGlobalProxy = false;
@@ -594,12 +595,20 @@
if (mWifiMinimumSecurityLevel != DevicePolicyManager.WIFI_SECURITY_OPEN) {
writeAttributeValueToXml(out, TAG_WIFI_MIN_SECURITY, mWifiMinimumSecurityLevel);
}
- if (mSsidAllowlist != null && !mSsidAllowlist.isEmpty()) {
- writeAttributeValuesToXml(out, TAG_SSID_ALLOWLIST, TAG_SSID, mSsidAllowlist);
+ if (mWifiSsidPolicy != null) {
+ List<String> ssids = ssidsToStrings(mWifiSsidPolicy.getSsids());
+ if (mWifiSsidPolicy.getPolicyType() == WIFI_SSID_POLICY_TYPE_ALLOWLIST) {
+ writeAttributeValuesToXml(out, TAG_SSID_ALLOWLIST, TAG_SSID, ssids);
+ } else if (mWifiSsidPolicy.getPolicyType() == WIFI_SSID_POLICY_TYPE_DENYLIST) {
+ writeAttributeValuesToXml(out, TAG_SSID_DENYLIST, TAG_SSID, ssids);
+ }
}
- if (mSsidDenylist != null && !mSsidDenylist.isEmpty()) {
- writeAttributeValuesToXml(out, TAG_SSID_DENYLIST, TAG_SSID, mSsidDenylist);
- }
+ }
+
+ private List<String> ssidsToStrings(Set<WifiSsid> ssids) {
+ return ssids.stream()
+ .map(ssid -> new String(ssid.getBytes(), StandardCharsets.UTF_8))
+ .collect(Collectors.toList());
}
void writeTextToXml(TypedXmlSerializer out, String tag, String text) throws IOException {
@@ -855,11 +864,13 @@
} else if (TAG_WIFI_MIN_SECURITY.equals(tag)) {
mWifiMinimumSecurityLevel = parser.getAttributeInt(null, ATTR_VALUE);
} else if (TAG_SSID_ALLOWLIST.equals(tag)) {
- mSsidAllowlist = new ArrayList<>();
- readAttributeValues(parser, TAG_SSID, mSsidAllowlist);
+ List<WifiSsid> ssids = readWifiSsids(parser, TAG_SSID);
+ mWifiSsidPolicy = new WifiSsidPolicy(
+ WIFI_SSID_POLICY_TYPE_ALLOWLIST, new ArraySet<>(ssids));
} else if (TAG_SSID_DENYLIST.equals(tag)) {
- mSsidDenylist = new ArrayList<>();
- readAttributeValues(parser, TAG_SSID, mSsidDenylist);
+ List<WifiSsid> ssids = readWifiSsids(parser, TAG_SSID);
+ mWifiSsidPolicy = new WifiSsidPolicy(
+ WIFI_SSID_POLICY_TYPE_DENYLIST, new ArraySet<>(ssids));
} else {
Slogf.w(LOG_TAG, "Unknown admin tag: %s", tag);
XmlUtils.skipCurrentTag(parser);
@@ -867,6 +878,16 @@
}
}
+ private List<WifiSsid> readWifiSsids(TypedXmlPullParser parser, String tag)
+ throws XmlPullParserException, IOException {
+ List<String> ssidStrings = new ArrayList<>();
+ readAttributeValues(parser, tag, ssidStrings);
+ List<WifiSsid> ssids = ssidStrings.stream()
+ .map(ssid -> WifiSsid.fromBytes(ssid.getBytes(StandardCharsets.UTF_8)))
+ .collect(Collectors.toList());
+ return ssids;
+ }
+
private List<String> readPackageList(TypedXmlPullParser parser,
String tag) throws XmlPullParserException, IOException {
List<String> result = new ArrayList<String>();
@@ -1222,11 +1243,14 @@
pw.print("mWifiMinimumSecurityLevel=");
pw.println(mWifiMinimumSecurityLevel);
- pw.print("mSsidAllowlist=");
- pw.println(mSsidAllowlist);
-
- pw.print("mSsidDenylist=");
- pw.println(mSsidDenylist);
+ if (mWifiSsidPolicy != null) {
+ if (mWifiSsidPolicy.getPolicyType() == WIFI_SSID_POLICY_TYPE_ALLOWLIST) {
+ pw.print("mSsidAllowlist=");
+ } else {
+ pw.print("mSsidDenylist=");
+ }
+ pw.println(ssidsToStrings(mWifiSsidPolicy.getSsids()));
+ }
if (mFactoryResetProtectionPolicy != null) {
pw.println("mFactoryResetProtectionPolicy:");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 234252c0..17b44e3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -138,6 +138,7 @@
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
+import static android.provider.Settings.Global.BYPASS_DEVICE_POLICY_MANAGEMENT_ROLE_QUALIFICATIONS;
import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
import static android.provider.Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
@@ -274,7 +275,6 @@
import android.net.VpnManager;
import android.net.metrics.IpConnectivityLog;
import android.net.wifi.WifiManager;
-import android.net.wifi.WifiSsid;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -395,7 +395,6 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
-import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@@ -7233,7 +7232,7 @@
return;
}
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.SEND_LOST_MODE_LOCATION_UPDATES));
+ hasCallingOrSelfPermission(permission.TRIGGER_LOST_MODE));
synchronized (getLockObject()) {
final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(
@@ -12269,7 +12268,7 @@
+ " only profile owner or device owner may control the preferential"
+ " network service");
synchronized (getLockObject()) {
- final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(
+ final ActiveAdmin requiredAdmin = getDeviceOrProfileOwnerAdminLocked(
caller.getUserId());
if (!requiredAdmin.mPreferentialNetworkServiceConfigs.equals(
preferentialNetworkServiceConfigs)) {
@@ -12299,7 +12298,8 @@
+ " only profile owner or device owner may retrieve the preferential"
+ " network service configurations");
synchronized (getLockObject()) {
- final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(caller.getUserId());
+ final ActiveAdmin requiredAdmin = getDeviceOrProfileOwnerAdminLocked(
+ caller.getUserId());
return requiredAdmin.mPreferentialNetworkServiceConfigs;
}
}
@@ -13985,16 +13985,10 @@
return;
}
}
- try {
- if (!isRuntimePermission(permission)) {
- callback.sendResult(null);
- return;
- }
- } catch (NameNotFoundException e) {
- throw new RemoteException("Cannot check if " + permission
- + "is a runtime permission", e, false, true);
+ if (!isRuntimePermission(permission)) {
+ callback.sendResult(null);
+ return;
}
-
if (grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
|| grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED
|| grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT) {
@@ -14107,11 +14101,15 @@
});
}
- public boolean isRuntimePermission(String permissionName) throws NameNotFoundException {
- final PackageManager packageManager = mInjector.getPackageManager();
- PermissionInfo permissionInfo = packageManager.getPermissionInfo(permissionName, 0);
- return (permissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
- == PermissionInfo.PROTECTION_DANGEROUS;
+ private boolean isRuntimePermission(String permissionName) {
+ try {
+ final PackageManager packageManager = mInjector.getPackageManager();
+ PermissionInfo permissionInfo = packageManager.getPermissionInfo(permissionName, 0);
+ return (permissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
+ == PermissionInfo.PROTECTION_DANGEROUS;
+ } catch (NameNotFoundException e) {
+ return false;
+ }
}
@Override
@@ -18571,13 +18569,11 @@
.notifyMinimumRequiredWifiSecurityLevelChanged(level));
}
- private void notifyWifiSsidPolicyChanged(int policyType, List<String> ssids) {
- List<WifiSsid> wifiSsidList = new ArrayList<>();
- for (String ssid : ssids) {
- wifiSsidList.add(
- WifiSsid.fromBytes(ssid.getBytes(StandardCharsets.UTF_8)));
+ private void notifyWifiSsidPolicyChanged(WifiSsidPolicy policy) {
+ if (policy == null) {
+ // If policy doesn't limit SSIDs, no need to disconnect anything.
+ return;
}
- WifiSsidPolicy policy = new WifiSsidPolicy(policyType, new ArraySet<>(wifiSsidList));
mInjector.binderWithCleanCallingIdentity(
() -> mInjector.getWifiManager().notifyWifiSsidPolicyChanged(policy));
}
@@ -18613,84 +18609,40 @@
}
@Override
- public void setSsidAllowlist(List<String> ssids) {
- final CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
- "SSID allowlist can only be controlled by a device owner or "
- + "a profile owner on an organization-owned device.");
-
- Collections.sort(ssids);
- boolean changed = false;
- synchronized (getLockObject()) {
- final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller);
- if (!ssids.equals(admin.mSsidAllowlist)) {
- admin.mSsidAllowlist = ssids;
- admin.mSsidDenylist = null;
- changed = true;
- }
- if (changed) saveSettingsLocked(caller.getUserId());
- }
- if (changed && !ssids.isEmpty()) {
- notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST, ssids);
- }
- }
-
- @Override
- public List<String> getSsidAllowlist() {
+ public WifiSsidPolicy getWifiSsidPolicy() {
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(
isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller)
|| canQueryAdminPolicy(caller),
- "SSID allowlist can only be retrieved by a device owner or "
+ "SSID policy can only be retrieved by a device owner or "
+ "a profile owner on an organization-owned device or "
+ "an app with the QUERY_ADMIN_POLICY permission.");
synchronized (getLockObject()) {
final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(
UserHandle.USER_SYSTEM);
- return (admin == null || admin.mSsidAllowlist == null) ? new ArrayList<>()
- : admin.mSsidAllowlist;
+ return admin != null ? admin.mWifiSsidPolicy : null;
}
}
@Override
- public void setSsidDenylist(List<String> ssids) {
+ public void setWifiSsidPolicy(WifiSsidPolicy policy) {
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(
isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
"SSID denylist can only be controlled by a device owner or "
+ "a profile owner on an organization-owned device.");
- Collections.sort(ssids);
boolean changed = false;
synchronized (getLockObject()) {
final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller);
- if (!ssids.equals(admin.mSsidDenylist)) {
- admin.mSsidDenylist = ssids;
- admin.mSsidAllowlist = null;
+ if (!Objects.equals(policy, admin.mWifiSsidPolicy)) {
+ admin.mWifiSsidPolicy = policy;
changed = true;
}
if (changed) saveSettingsLocked(caller.getUserId());
}
if (changed) {
- notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST, ssids);
- }
- }
-
- @Override
- public List<String> getSsidDenylist() {
- final CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller)
- || canQueryAdminPolicy(caller),
- "SSID denylist can only be retrieved by a device owner or "
- + "a profile owner on an organization-owned device or "
- + "an app with the QUERY_ADMIN_POLICY permission.");
- synchronized (getLockObject()) {
- final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(
- UserHandle.USER_SYSTEM);
- return (admin == null || admin.mSsidDenylist == null) ? new ArrayList<>()
- : admin.mSsidDenylist;
+ notifyWifiSsidPolicyChanged(policy);
}
}
@@ -18825,15 +18777,28 @@
Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
android.Manifest.permission.MANAGE_ROLE_HOLDERS));
return mInjector.binderWithCleanCallingIdentity(() -> {
- if (mUserManager.getUserCount() > 1) {
- return false;
+ if (mInjector.settingsGlobalGetInt(
+ BYPASS_DEVICE_POLICY_MANAGEMENT_ROLE_QUALIFICATIONS, /* def= */ 0) == 1) {
+ return true;
}
- AccountManager am = AccountManager.get(mContext);
- Account[] accounts = am.getAccounts();
- return accounts.length == 0;
+ if (shouldAllowBypassingDevicePolicyManagementRoleQualificationInternal()) {
+ mInjector.settingsGlobalPutInt(
+ BYPASS_DEVICE_POLICY_MANAGEMENT_ROLE_QUALIFICATIONS, /* value= */ 1);
+ return true;
+ }
+ return false;
});
}
+ private boolean shouldAllowBypassingDevicePolicyManagementRoleQualificationInternal() {
+ if (mUserManager.getUserCount() > 1) {
+ return false;
+ }
+ AccountManager am = AccountManager.get(mContext);
+ Account[] accounts = am.getAccounts();
+ return accounts.length == 0;
+ }
+
@Override
public List<UserHandle> getPolicyManagedProfiles(@NonNull UserHandle user) {
Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java b/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java
index 964be38..c72e1ea 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java
@@ -16,6 +16,8 @@
package com.android.server.devicepolicy;
+import static com.android.server.FactoryResetter.setFactoryResetting;
+
import android.annotation.Nullable;
import android.app.admin.DevicePolicySafetyChecker;
import android.content.Context;
@@ -36,7 +38,10 @@
/**
* Entry point for "factory reset" requests.
+ *
+ * @deprecated TODO(b/225012970): should be moved to {@code com.android.server.FactoryResetter}
*/
+@Deprecated
public final class FactoryResetter {
private static final String TAG = FactoryResetter.class.getSimpleName();
@@ -60,6 +65,8 @@
Preconditions.checkCallAuthorization(mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MASTER_CLEAR) == PackageManager.PERMISSION_GRANTED);
+ setFactoryResetting(mContext);
+
if (mSafetyChecker == null) {
factoryResetInternalUnchecked();
return true;
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index e096687..4a51e41 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -217,6 +217,8 @@
@Mock
private AppOpsManager mAppOpsManager;
@Mock
+ private BatteryManager mBatteryManager;
+ @Mock
private DeviceIdleInternal mDeviceIdleInternal;
@Mock
private PermissionManagerServiceInternal mPermissionManagerInternal;
@@ -453,6 +455,7 @@
eq(Manifest.permission.USE_EXACT_ALARM), anyInt(), anyInt(), anyString()));
when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
+ when(mMockContext.getSystemService(BatteryManager.class)).thenReturn(mBatteryManager);
registerAppIds(new String[]{TEST_CALLING_PACKAGE},
new Integer[]{UserHandle.getAppId(TEST_CALLING_UID)});
@@ -477,6 +480,8 @@
// Other boot phases don't matter
mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
+
+ verify(mBatteryManager).isCharging();
setTareEnabled(false);
mAppStandbyWindow = mService.mConstants.APP_STANDBY_WINDOW;
mAllowWhileIdleWindow = mService.mConstants.ALLOW_WHILE_IDLE_WINDOW;
@@ -1101,6 +1106,7 @@
new Intent(parole ? BatteryManager.ACTION_CHARGING
: BatteryManager.ACTION_DISCHARGING));
assertAndHandleMessageSync(CHARGING_STATUS_CHANGED);
+ assertEquals(parole, mService.mAppStandbyParole);
}
@Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 50a0a68..c747a5f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -63,6 +63,7 @@
import static com.android.server.am.ProcessList.VISIBLE_APP_ADJ;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.AdditionalAnswers.answer;
import static org.mockito.Mockito.any;
@@ -444,7 +445,7 @@
@SuppressWarnings("GuardedBy")
@Test
- public void testUpdateOomAdj_DoOne_PerceptibleRecent() {
+ public void testUpdateOomAdj_DoOne_PerceptibleRecent_FgService() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
app.mServices.setHasForegroundServices(true, 0);
@@ -458,6 +459,70 @@
@SuppressWarnings("GuardedBy")
@Test
+ public void testUpdateOomAdj_DoOne_PerceptibleRecent_AlmostPerceptibleService() {
+ // Grace period allows the adjustment.
+ {
+ ProcessRecord system = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, true));
+ long nowUptime = SystemClock.uptimeMillis();
+ app.mState.setLastTopTime(nowUptime);
+ // Simulate the system starting and binding to a service in the app.
+ ServiceRecord s = bindService(app, system,
+ null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class));
+ s.lastTopAlmostPerceptibleBindRequestUptimeMs = nowUptime;
+ s.getConnections().clear();
+ app.mServices.updateHasTopStartedAlmostPerceptibleServices();
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+ sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+ }
+
+ // Out of grace period but valid binding allows the adjustment.
+ {
+ ProcessRecord system = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, true));
+ long nowUptime = SystemClock.uptimeMillis();
+ app.mState.setLastTopTime(nowUptime);
+ // Simulate the system starting and binding to a service in the app.
+ ServiceRecord s = bindService(app, system,
+ null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class));
+ s.lastTopAlmostPerceptibleBindRequestUptimeMs =
+ nowUptime - 2 * sService.mConstants.mServiceBindAlmostPerceptibleTimeoutMs;
+ app.mServices.updateHasTopStartedAlmostPerceptibleServices();
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+ sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+ }
+
+ // Out of grace period and no valid binding so no adjustment.
+ {
+ ProcessRecord system = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, true));
+ long nowUptime = SystemClock.uptimeMillis();
+ app.mState.setLastTopTime(nowUptime);
+ // Simulate the system starting and binding to a service in the app.
+ ServiceRecord s = bindService(app, system,
+ null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class));
+ s.lastTopAlmostPerceptibleBindRequestUptimeMs =
+ nowUptime - 2 * sService.mConstants.mServiceBindAlmostPerceptibleTimeoutMs;
+ s.getConnections().clear();
+ app.mServices.updateHasTopStartedAlmostPerceptibleServices();
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+ sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertNotEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+ }
+ }
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_DoOne_Toast() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
diff --git a/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java b/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java
index 457c8db..4ffa0fb 100644
--- a/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java
@@ -14,11 +14,13 @@
* limitations under the License.
*/
+// TODO(b/225012970): should be moved to com.android.server
package com.android.server.devicepolicy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.FactoryResetter.isFactoryResetting;
import static com.google.common.truth.Truth.assertThat;
@@ -165,6 +167,7 @@
.factoryReset();
assertThat(success).isTrue();
+ assertThat(isFactoryResetting()).isTrue();
verifyWipeAdoptableStorageCalled();
verifyWipeFactoryResetProtectionNotCalled();
verifyRebootWipeUserDataMinimumArgsCalled();
@@ -179,6 +182,7 @@
.build().factoryReset();
assertThat(success).isTrue();
+ assertThat(isFactoryResetting()).isTrue();
verifyWipeAdoptableStorageNotCalled();
verifyWipeFactoryResetProtectionCalled();
verifyRebootWipeUserDataMinimumArgsCalled();
@@ -198,6 +202,7 @@
.build().factoryReset();
assertThat(success).isTrue();
+ assertThat(isFactoryResetting()).isTrue();
verifyWipeAdoptableStorageCalled();
verifyWipeFactoryResetProtectionCalled();
verifyRebootWipeUserDataAllArgsCalled();
@@ -211,6 +216,7 @@
.setSafetyChecker(mSafetyChecker).build().factoryReset();
assertThat(success).isFalse();
+ assertThat(isFactoryResetting()).isTrue();
verifyWipeAdoptableStorageNotCalled();
verifyWipeFactoryResetProtectionNotCalled();
verifyRebootWipeUserDataNotCalled();
@@ -238,6 +244,7 @@
.build().factoryReset();
assertThat(success).isFalse();
+ assertThat(isFactoryResetting()).isTrue();
verifyWipeAdoptableStorageCalled();
verifyWipeFactoryResetProtectionCalled();
verifyRebootWipeUserDataAllArgsCalled();
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 8d6269c..617321b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -178,7 +178,7 @@
// This should be public
assertDisplayPrivateFlag(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(),
PORT_A, false);
- // This should be public
+ // This should be private
assertDisplayPrivateFlag(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(),
PORT_B, true);
// This should be public
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt
new file mode 100644
index 0000000..c9598bd
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm
+
+import android.content.pm.PackageManager
+import android.content.pm.UserInfo
+import android.os.Build
+import android.util.Log
+import com.android.server.testutils.any
+import com.android.server.testutils.spy
+import com.android.server.testutils.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mockito.doAnswer
+
+@RunWith(JUnit4::class)
+class DeletePackageHelperTest {
+
+ @Rule
+ @JvmField
+ val rule = MockSystemRule()
+
+ private lateinit var mPms: PackageManagerService
+ private lateinit var mUserManagerInternal: UserManagerInternal
+
+ @Before
+ @Throws(Exception::class)
+ fun setup() {
+ Log.i("system.out", "setup", Exception())
+ rule.system().stageNominalSystemState()
+ rule.system().stageScanExistingPackage(
+ "a.data.package", 1L, rule.system().dataAppDirectory)
+
+ mUserManagerInternal = rule.mocks().injector.userManagerInternal
+ whenever(mUserManagerInternal.getUserIds()).thenReturn(intArrayOf(0, 1))
+
+ mPms = createPackageManagerService()
+ doAnswer { false }.`when`(mPms).isPackageDeviceAdmin(any(), any())
+ doAnswer { null }.`when`(mPms).freezePackageForDelete(any(), any(), any(), any())
+ }
+
+ private fun createPackageManagerService(): PackageManagerService {
+ return spy(PackageManagerService(rule.mocks().injector,
+ false /*coreOnly*/,
+ false /*factoryTest*/,
+ MockSystem.DEFAULT_VERSION_INFO.fingerprint,
+ false /*isEngBuild*/,
+ false /*isUserDebugBuild*/,
+ Build.VERSION_CODES.CUR_DEVELOPMENT,
+ Build.VERSION.INCREMENTAL))
+ }
+
+ @Test
+ fun deleteSystemPackageFailsIfNotAdmin() {
+ val ps = mPms.mSettings.getPackageLPr("a.data.package")
+ whenever(PackageManagerServiceUtils.isSystemApp(ps)).thenReturn(true)
+ whenever(mUserManagerInternal.getUserInfo(1)).thenReturn(UserInfo(1, "test", 0))
+
+ val dph = DeletePackageHelper(mPms)
+ val result = dph.deletePackageX("a.data.package", 1L, 1, 0, false)
+
+ assertThat(result).isEqualTo(PackageManager.DELETE_FAILED_USER_RESTRICTED)
+ }
+
+ @Test
+ fun deleteSystemPackageSucceedsIfAdmin() {
+ val ps = mPms.mSettings.getPackageLPr("a.data.package")
+ whenever(PackageManagerServiceUtils.isSystemApp(ps)).thenReturn(true)
+ whenever(mUserManagerInternal.getUserInfo(1)).thenReturn(
+ UserInfo(1, "test", UserInfo.FLAG_ADMIN))
+
+ val dph = DeletePackageHelper(mPms)
+ val result = dph.deletePackageX("a.data.package", 1L, 1,
+ PackageManager.DELETE_SYSTEM_APP, false)
+
+ assertThat(result).isEqualTo(PackageManager.DELETE_SUCCEEDED)
+ }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
index 27637c2..ed0336a 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
@@ -21,6 +21,7 @@
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HIDDEN;
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_IGNORE_HARD_KEYBOARD;
+import static android.content.pm.PackageManager.FEATURE_WINDOW_MAGNIFICATION;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
import static android.view.accessibility.AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED;
@@ -42,6 +43,7 @@
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Color;
import android.provider.Settings;
@@ -92,6 +94,8 @@
@Mock private AccessibilityUserState.ServiceInfoChangeListener mMockListener;
+ @Mock private PackageManager mMockPackageManager;
+
@Mock private Context mMockContext;
private MockContentResolver mMockResolver;
@@ -113,6 +117,8 @@
when(mMockServiceInfo.getComponentName()).thenReturn(COMPONENT_NAME);
when(mMockConnection.getServiceInfo()).thenReturn(mMockServiceInfo);
when(mMockContext.getResources()).thenReturn(resources);
+ when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+ when(mMockPackageManager.hasSystemFeature(FEATURE_WINDOW_MAGNIFICATION)).thenReturn(true);
mFocusStrokeWidthDefaultValue =
resources.getDimensionPixelSize(R.dimen.accessibility_focus_highlight_stroke_width);
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 2690948..997a138 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -35,6 +35,7 @@
import android.accounts.CantAddAccountActivity;
import android.accounts.IAccountManagerResponse;
import android.app.AppOpsManager;
+import android.app.PropertyInvalidatedCache;
import android.app.INotificationManager;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
@@ -132,6 +133,8 @@
protected void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ PropertyInvalidatedCache.disableForTestMode();
+
when(mMockPackageManager.checkSignatures(anyInt(), anyInt()))
.thenReturn(PackageManager.SIGNATURE_MATCH);
final UserInfo ui = new UserInfo(UserHandle.USER_SYSTEM, "user0", 0);
diff --git a/services/tests/servicestests/src/com/android/server/audio/AbsoluteVolumeBehaviorTest.java b/services/tests/servicestests/src/com/android/server/audio/AbsoluteVolumeBehaviorTest.java
new file mode 100644
index 0000000..ad2e7e4
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/audio/AbsoluteVolumeBehaviorTest.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.audio;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.argThat;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
+import android.media.AudioDeviceVolumeManager;
+import android.media.AudioManager;
+import android.media.AudioSystem;
+import android.media.IAudioDeviceVolumeDispatcher;
+import android.media.VolumeInfo;
+import android.os.RemoteException;
+import android.os.test.TestLooper;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+public class AbsoluteVolumeBehaviorTest {
+ private static final String TAG = "AbsoluteVolumeBehaviorTest";
+
+ private static final AudioDeviceAttributes DEVICE_SPEAKER_OUT = new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, "");
+
+ private Context mContext;
+ private String mPackageName;
+ private AudioSystemAdapter mSpyAudioSystem;
+ private SystemServerAdapter mSystemServer;
+ private SettingsAdapter mSettingsAdapter;
+ private TestLooper mTestLooper;
+
+ private AudioService mAudioService;
+
+ private IAudioDeviceVolumeDispatcher.Stub mMockDispatcher =
+ mock(IAudioDeviceVolumeDispatcher.Stub.class);
+
+ @Before
+ public void setUp() throws Exception {
+ mTestLooper = new TestLooper();
+ mContext = InstrumentationRegistry.getTargetContext();
+ mPackageName = mContext.getOpPackageName();
+ mSpyAudioSystem = spy(new NoOpAudioSystemAdapter());
+
+ mSystemServer = new NoOpSystemServerAdapter();
+ mSettingsAdapter = new NoOpSettingsAdapter();
+ mAudioService = new AudioService(mContext, mSpyAudioSystem, mSystemServer,
+ mSettingsAdapter, mTestLooper.getLooper()) {
+ @Override
+ public int getDeviceForStream(int stream) {
+ return AudioSystem.DEVICE_OUT_SPEAKER;
+ }
+ };
+
+ mTestLooper.dispatchAll();
+ }
+
+ @Test
+ public void registerDispatcher_setsVolumeBehaviorToAbsolute() {
+ List<VolumeInfo> volumes = Collections.singletonList(
+ new VolumeInfo.Builder(AudioManager.STREAM_MUSIC).build());
+
+ mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+ mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true);
+ mTestLooper.dispatchAll();
+
+ assertThat(mAudioService.getDeviceVolumeBehavior(DEVICE_SPEAKER_OUT))
+ .isEqualTo(AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+ }
+
+ @Test
+ public void registerDispatcher_setsVolume() {
+ List<VolumeInfo> volumes = Collections.singletonList(
+ new VolumeInfo.Builder(AudioManager.STREAM_MUSIC)
+ .setMinVolumeIndex(0)
+ .setMaxVolumeIndex(250) // Max index is 10 times that of STREAM_MUSIC
+ .setVolumeIndex(50)
+ .build());
+
+ mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+ mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true);
+ mTestLooper.dispatchAll();
+
+ assertThat(mAudioService.getStreamVolume(AudioManager.STREAM_MUSIC))
+ .isEqualTo(5);
+ }
+
+ @Test
+ public void unregisterDispatcher_deviceBecomesVariableVolume_listenerNoLongerTriggered()
+ throws RemoteException {
+
+ List<VolumeInfo> volumes = Collections.singletonList(
+ new VolumeInfo.Builder(AudioManager.STREAM_MUSIC).build());
+
+ mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+ mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true);
+ mTestLooper.dispatchAll();
+
+ mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(false,
+ mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true);
+ mTestLooper.dispatchAll();
+
+ assertThat(mAudioService.getDeviceVolumeBehavior(DEVICE_SPEAKER_OUT))
+ .isEqualTo(AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE);
+
+ mAudioService.setStreamVolume(AudioManager.STREAM_MUSIC, 15, 0, mPackageName);
+ mTestLooper.dispatchAll();
+
+ verify(mMockDispatcher, never()).dispatchDeviceVolumeChanged(
+ eq(DEVICE_SPEAKER_OUT), any());
+ }
+
+ @Test
+ public void setDeviceVolumeBehavior_unregistersDispatcher() throws RemoteException {
+ List<VolumeInfo> volumes = Collections.singletonList(
+ new VolumeInfo.Builder(AudioManager.STREAM_MUSIC).build());
+
+ mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+ mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true);
+ mTestLooper.dispatchAll();
+
+ mAudioService.setDeviceVolumeBehavior(DEVICE_SPEAKER_OUT,
+ AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL, mPackageName);
+ mTestLooper.dispatchAll();
+
+ mAudioService.setStreamVolume(AudioManager.STREAM_MUSIC, 15, 0, mPackageName);
+ mTestLooper.dispatchAll();
+
+ verify(mMockDispatcher, never()).dispatchDeviceVolumeChanged(
+ eq(DEVICE_SPEAKER_OUT), any());
+ }
+
+ @Test
+ public void setStreamVolume_noAbsVolFlag_dispatchesVolumeChanged() throws RemoteException {
+ VolumeInfo volumeInfo = new VolumeInfo.Builder(AudioManager.STREAM_MUSIC)
+ .setMinVolumeIndex(0)
+ .setMaxVolumeIndex(250) // Max index is 10 times that of STREAM_MUSIC
+ .setVolumeIndex(50)
+ .build();
+
+ mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+ mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
+ Collections.singletonList(volumeInfo), true);
+ mTestLooper.dispatchAll();
+
+ // Set stream volume without FLAG_ABSOLUTE_VOLUME
+ mAudioService.setStreamVolume(AudioManager.STREAM_MUSIC, 15, 0, mPackageName);
+ mTestLooper.dispatchAll();
+
+ // Dispatched volume index is scaled to the range in the initial VolumeInfo
+ verify(mMockDispatcher).dispatchDeviceVolumeChanged(DEVICE_SPEAKER_OUT,
+ new VolumeInfo.Builder(volumeInfo).setVolumeIndex(150).build());
+ }
+
+ @Test
+ public void setStreamVolume_absVolFlagSet_doesNotDispatchVolumeChanged()
+ throws RemoteException {
+ VolumeInfo volumeInfo = new VolumeInfo.Builder(AudioManager.STREAM_MUSIC)
+ .setMinVolumeIndex(0)
+ .setMaxVolumeIndex(250)
+ .setVolumeIndex(50)
+ .build();
+
+ mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+ mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
+ Collections.singletonList(volumeInfo), true);
+ mTestLooper.dispatchAll();
+
+ // Set stream volume with FLAG_ABSOLUTE_VOLUME
+ mAudioService.setStreamVolume(AudioManager.STREAM_MUSIC, 15,
+ AudioManager.FLAG_ABSOLUTE_VOLUME, mPackageName);
+ mTestLooper.dispatchAll();
+
+ verify(mMockDispatcher, never()).dispatchDeviceVolumeChanged(eq(DEVICE_SPEAKER_OUT),
+ any());
+ }
+
+ @Test
+ public void adjustStreamVolume_handlesAdjust_noAbsVolFlag_noVolChange_dispatchesVolumeAdjusted()
+ throws RemoteException {
+ VolumeInfo volumeInfo = new VolumeInfo.Builder(AudioManager.STREAM_MUSIC)
+ .setMinVolumeIndex(0)
+ .setMaxVolumeIndex(250)
+ .setVolumeIndex(0)
+ .build();
+
+ // Register dispatcher with handlesVolumeAdjustment = true
+ mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+ mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
+ Collections.singletonList(volumeInfo), true);
+ mTestLooper.dispatchAll();
+
+ // Adjust stream volume without FLAG_ABSOLUTE_VOLUME
+ mAudioService.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE,
+ 0, mPackageName);
+ mTestLooper.dispatchAll();
+
+ // Stream volume does not change
+ assertThat(mAudioService.getStreamVolume(AudioManager.STREAM_MUSIC)).isEqualTo(0);
+ // Listener is notified via dispatchDeviceVolumeAdjusted
+ verify(mMockDispatcher, never()).dispatchDeviceVolumeChanged(eq(DEVICE_SPEAKER_OUT), any());
+ verify(mMockDispatcher).dispatchDeviceVolumeAdjusted(eq(DEVICE_SPEAKER_OUT),
+ argThat((VolumeInfo v) -> v.getStreamType() == AudioManager.STREAM_MUSIC),
+ eq(AudioManager.ADJUST_RAISE), eq(AudioDeviceVolumeManager.ADJUST_MODE_NORMAL));
+ }
+
+ @Test
+ public void adjustStreamVolume_noHandleAdjust_noAbsVolFlag_volChanges_dispatchesVolumeChanged()
+ throws RemoteException {
+ VolumeInfo volumeInfo = new VolumeInfo.Builder(AudioManager.STREAM_MUSIC)
+ .setMinVolumeIndex(0)
+ .setMaxVolumeIndex(250)
+ .setVolumeIndex(0)
+ .build();
+
+ // Register dispatcher with handlesVolumeAdjustment = false
+ mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+ mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
+ Collections.singletonList(volumeInfo), false);
+ mTestLooper.dispatchAll();
+
+ // Adjust stream volume without FLAG_ABSOLUTE_VOLUME
+ mAudioService.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE,
+ 0, mPackageName);
+ mTestLooper.dispatchAll();
+
+ // Stream volume changes
+ assertThat(mAudioService.getStreamVolume(AudioManager.STREAM_MUSIC)).isNotEqualTo(0);
+ // Listener is notified via dispatchDeviceVolumeChanged
+ verify(mMockDispatcher).dispatchDeviceVolumeChanged(eq(DEVICE_SPEAKER_OUT), any());
+ verify(mMockDispatcher, never()).dispatchDeviceVolumeAdjusted(eq(DEVICE_SPEAKER_OUT), any(),
+ anyInt(), anyInt());
+ }
+
+ @Test
+ public void adjustStreamVolume_absVolFlagSet_streamVolumeChanges_nothingDispatched()
+ throws RemoteException {
+ VolumeInfo volumeInfo = new VolumeInfo.Builder(AudioManager.STREAM_MUSIC)
+ .setMinVolumeIndex(0)
+ .setMaxVolumeIndex(250)
+ .setVolumeIndex(0)
+ .build();
+
+ mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+ mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
+ Collections.singletonList(volumeInfo), true);
+ mTestLooper.dispatchAll();
+
+ // Adjust stream volume with FLAG_ABSOLUTE_VOLUME set
+ mAudioService.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE,
+ AudioManager.FLAG_ABSOLUTE_VOLUME, mPackageName);
+ mTestLooper.dispatchAll();
+
+ // Stream volume changes
+ assertThat(mAudioService.getStreamVolume(AudioManager.STREAM_MUSIC)).isNotEqualTo(0);
+ // Nothing is dispatched
+ verify(mMockDispatcher, never()).dispatchDeviceVolumeChanged(eq(DEVICE_SPEAKER_OUT), any());
+ verify(mMockDispatcher, never()).dispatchDeviceVolumeAdjusted(eq(DEVICE_SPEAKER_OUT), any(),
+ anyInt(), anyInt());
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 484dc84..197c21f 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -8455,7 +8455,7 @@
@Test
public void testSendLostModeLocationUpdate_notOrganizationOwnedDevice() {
- mContext.callerPermissions.add(permission.SEND_LOST_MODE_LOCATION_UPDATES);
+ mContext.callerPermissions.add(permission.TRIGGER_LOST_MODE);
assertThrows(IllegalStateException.class, () -> dpm.sendLostModeLocationUpdate(
getServices().executor, /* empty callback */ result -> {}));
}
@@ -8463,7 +8463,7 @@
@Test
public void testSendLostModeLocationUpdate_asDeviceOwner() throws Exception {
final String TEST_PROVIDER = "network";
- mContext.callerPermissions.add(permission.SEND_LOST_MODE_LOCATION_UPDATES);
+ mContext.callerPermissions.add(permission.TRIGGER_LOST_MODE);
setDeviceOwner();
when(getServices().locationManager.getAllProviders()).thenReturn(List.of(TEST_PROVIDER));
when(getServices().locationManager.isProviderEnabled(TEST_PROVIDER)).thenReturn(true);
@@ -8480,7 +8480,7 @@
final int MANAGED_PROFILE_ADMIN_UID =
UserHandle.getUid(CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
- mContext.callerPermissions.add(permission.SEND_LOST_MODE_LOCATION_UPDATES);
+ mContext.callerPermissions.add(permission.TRIGGER_LOST_MODE);
addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
when(getServices().locationManager.getAllProviders()).thenReturn(List.of(TEST_PROVIDER));
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index 1fb5898..bf3c7c3 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -393,7 +393,8 @@
displayDeviceInfo.displayCutout = new DisplayCutout(
Insets.of(0, 10, 0, 0),
zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect);
- displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY;
+ displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY;
+ displayDeviceInfo.address = new TestUtils.TestDisplayAddress();
displayDevice.setDisplayDeviceInfo(displayDeviceInfo);
displayManager.getDisplayDeviceRepository()
.onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
@@ -1307,7 +1308,8 @@
displayDeviceInfo.displayCutout = new DisplayCutout(
Insets.of(0, 10, 0, 0),
zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect);
- displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY;
+ displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY;
+ displayDeviceInfo.address = new TestUtils.TestDisplayAddress();
displayDevice.setDisplayDeviceInfo(displayDeviceInfo);
displayManager.getDisplayDeviceRepository()
.onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
index 86b6da0..cc68ba8 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -42,7 +42,6 @@
import android.os.Handler;
import android.os.IPowerManager;
import android.os.IThermalService;
-import android.os.Parcel;
import android.os.PowerManager;
import android.os.Process;
import android.os.test.TestLooper;
@@ -146,7 +145,7 @@
@Test
public void testDisplayDeviceAddAndRemove_Internal() {
DisplayDevice device = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY);
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
// add
LogicalDisplay displayAdded = add(device);
@@ -179,7 +178,7 @@
public void testDisplayDeviceAdd_TwoInternalOneDefault() {
DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0);
DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY);
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
LogicalDisplay display1 = add(device1);
assertEquals(info(display1).address, info(device1).address);
@@ -193,9 +192,9 @@
@Test
public void testDisplayDeviceAdd_TwoInternalBothDefault() {
DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY);
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY);
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
LogicalDisplay display1 = add(device1);
assertEquals(info(display1).address, info(device1).address);
@@ -208,9 +207,57 @@
}
@Test
+ public void testDisplayDeviceAddAndRemove_OneExternalDefault() {
+ DisplayDevice device = createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800,
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+
+ // add
+ LogicalDisplay displayAdded = add(device);
+ assertEquals(info(displayAdded).address, info(device).address);
+ assertEquals(Display.DEFAULT_DISPLAY, id(displayAdded));
+
+ // remove
+ mDisplayDeviceRepo.onDisplayDeviceEvent(device, DISPLAY_DEVICE_EVENT_REMOVED);
+ verify(mListenerMock).onLogicalDisplayEventLocked(
+ mDisplayCaptor.capture(), eq(LOGICAL_DISPLAY_EVENT_REMOVED));
+ LogicalDisplay displayRemoved = mDisplayCaptor.getValue();
+ assertEquals(DEFAULT_DISPLAY, id(displayRemoved));
+ assertEquals(displayAdded, displayRemoved);
+ }
+
+ @Test
+ public void testDisplayDeviceAddAndRemove_SwitchDefault() {
+ DisplayDevice device1 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+ DisplayDevice device2 = createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+
+ LogicalDisplay display1 = add(device1);
+ assertEquals(info(display1).address, info(device1).address);
+ assertEquals(DEFAULT_DISPLAY, id(display1));
+
+ LogicalDisplay display2 = add(device2);
+ assertEquals(info(display2).address, info(device2).address);
+ // We can only have one default display
+ assertEquals(DEFAULT_DISPLAY, id(display1));
+
+ // remove
+ mDisplayDeviceRepo.onDisplayDeviceEvent(device1, DISPLAY_DEVICE_EVENT_REMOVED);
+
+ verify(mListenerMock).onLogicalDisplayEventLocked(
+ mDisplayCaptor.capture(), eq(LOGICAL_DISPLAY_EVENT_REMOVED));
+ LogicalDisplay displayRemoved = mDisplayCaptor.getValue();
+ // Display 1 is still the default logical display
+ assertEquals(DEFAULT_DISPLAY, id(display1));
+ // The logical displays had their devices swapped and Display 2 was removed
+ assertEquals(display2, displayRemoved);
+ assertEquals(info(display1).address, info(device2).address);
+ }
+
+ @Test
public void testGetDisplayIdsLocked() {
add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_EXTERNAL, 600, 800, 0));
add(createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800, 0));
@@ -223,19 +270,19 @@
@Test
public void testGetDisplayInfoForStateLocked_oneDisplayGroup_internalType() {
add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_INTERNAL, 700, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked(
DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfos.size()).isEqualTo(3);
+ assertThat(displayInfos.size()).isEqualTo(1);
for (DisplayInfo displayInfo : displayInfos) {
assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY);
assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfo.logicalWidth).isAnyOf(600, 200, 700);
+ assertThat(displayInfo.logicalWidth).isEqualTo(600);
assertThat(displayInfo.logicalHeight).isEqualTo(800);
}
}
@@ -243,19 +290,19 @@
@Test
public void testGetDisplayInfoForStateLocked_oneDisplayGroup_differentTypes() {
add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_EXTERNAL, 700, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked(
DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfos.size()).isEqualTo(2);
+ assertThat(displayInfos.size()).isEqualTo(1);
for (DisplayInfo displayInfo : displayInfos) {
assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY);
assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfo.logicalWidth).isAnyOf(600, 200);
+ assertThat(displayInfo.logicalWidth).isEqualTo(600);
assertThat(displayInfo.logicalHeight).isEqualTo(800);
}
}
@@ -263,19 +310,19 @@
@Test
public void testGetDisplayInfoForStateLocked_multipleDisplayGroups_defaultGroup() {
add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_INTERNAL, 200, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
add(createDisplayDevice(Display.TYPE_VIRTUAL, 700, 800,
DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP));
Set<DisplayInfo> displayInfos = mLogicalDisplayMapper.getDisplayInfoForStateLocked(
DeviceStateToLayoutMap.STATE_DEFAULT, DEFAULT_DISPLAY, DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfos.size()).isEqualTo(2);
+ assertThat(displayInfos.size()).isEqualTo(1);
for (DisplayInfo displayInfo : displayInfos) {
assertThat(displayInfo.displayId).isEqualTo(DEFAULT_DISPLAY);
assertThat(displayInfo.displayGroupId).isEqualTo(DEFAULT_DISPLAY_GROUP);
- assertThat(displayInfo.logicalWidth).isAnyOf(600, 200);
+ assertThat(displayInfo.logicalWidth).isEqualTo(600);
assertThat(displayInfo.logicalHeight).isEqualTo(800);
}
}
@@ -283,7 +330,7 @@
@Test
public void testSingleDisplayGroup() {
LogicalDisplay display1 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
LogicalDisplay display2 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0));
LogicalDisplay display3 = add(createDisplayDevice(Display.TYPE_VIRTUAL, 600, 800, 0));
@@ -298,7 +345,7 @@
@Test
public void testMultipleDisplayGroups() {
LogicalDisplay display1 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800,
- DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY));
+ DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
LogicalDisplay display2 = add(createDisplayDevice(Display.TYPE_INTERNAL, 600, 800, 0));
@@ -371,7 +418,7 @@
/////////////////
private TestDisplayDevice createDisplayDevice(int type, int width, int height, int flags) {
- return createDisplayDevice(new DisplayAddressImpl(), type, width, height, flags);
+ return createDisplayDevice(new TestUtils.TestDisplayAddress(), type, width, height, flags);
}
private TestDisplayDevice createDisplayDevice(
@@ -385,7 +432,7 @@
displayDeviceInfo.supportedModes = new Display.Mode[1];
displayDeviceInfo.supportedModes[0] = new Display.Mode(1, width, height, 60f);
displayDeviceInfo.modeId = 1;
- displayDeviceInfo.address = new DisplayAddressImpl();
+ displayDeviceInfo.address = address;
return device;
}
@@ -427,18 +474,8 @@
assertNotEquals(DEFAULT_DISPLAY, id(displayRemoved));
}
- /**
- * Create a custom {@link DisplayAddress} to ensure we're not relying on any specific
- * display-address implementation in our code. Intentionally uses default object (reference)
- * equality rules.
- */
- class DisplayAddressImpl extends DisplayAddress {
- @Override
- public void writeToParcel(Parcel out, int flags) { }
- }
-
class TestDisplayDevice extends DisplayDevice {
- private DisplayDeviceInfo mInfo = new DisplayDeviceInfo();
+ private DisplayDeviceInfo mInfo;
private DisplayDeviceInfo mSentInfo;
TestDisplayDevice() {
diff --git a/services/tests/servicestests/src/com/android/server/display/TestUtils.java b/services/tests/servicestests/src/com/android/server/display/TestUtils.java
index 859dfe3..0454587 100644
--- a/services/tests/servicestests/src/com/android/server/display/TestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/display/TestUtils.java
@@ -18,7 +18,9 @@
import android.hardware.Sensor;
import android.hardware.SensorEvent;
+import android.os.Parcel;
import android.os.SystemClock;
+import android.view.DisplayAddress;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -57,4 +59,13 @@
return sensor;
}
+ /**
+ * Create a custom {@link DisplayAddress} to ensure we're not relying on any specific
+ * display-address implementation in our code. Intentionally uses default object (reference)
+ * equality rules.
+ */
+ public static class TestDisplayAddress extends DisplayAddress {
+ @Override
+ public void writeToParcel(Parcel out, int flags) { }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/GiveFeaturesActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/GiveFeaturesActionTest.java
deleted file mode 100644
index 0b31db6..0000000
--- a/services/tests/servicestests/src/com/android/server/hdmi/GiveFeaturesActionTest.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.hdmi;
-
-import static android.hardware.hdmi.DeviceFeatures.FEATURE_SUPPORTED;
-import static android.hardware.hdmi.DeviceFeatures.FEATURE_SUPPORT_UNKNOWN;
-import static android.hardware.hdmi.HdmiControlManager.HDMI_CEC_VERSION_2_0;
-import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM;
-
-import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.hardware.hdmi.DeviceFeatures;
-import android.hardware.hdmi.HdmiControlManager;
-import android.hardware.hdmi.HdmiDeviceInfo;
-import android.hardware.hdmi.IHdmiControlCallback;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.test.TestLooper;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-
-import com.android.server.SystemService;
-
-import com.google.android.collect.Lists;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-
-@SmallTest
-@Presubmit
-@RunWith(JUnit4.class)
-public class GiveFeaturesActionTest {
- private HdmiControlService mHdmiControlServiceSpy;
- private HdmiCecController mHdmiCecController;
- private HdmiCecLocalDevicePlayback mPlaybackDevice;
- private FakeNativeWrapper mNativeWrapper;
- private FakePowerManagerWrapper mPowerManager;
- private Looper mLooper;
- private Context mContextSpy;
- private TestLooper mTestLooper = new TestLooper();
- private int mPhysicalAddress = 0x1100;
- private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
- private int mPlaybackLogicalAddress;
-
- private TestCallback mTestCallback;
- private GiveFeaturesAction mAction;
-
- /**
- * Setup: Local Playback device queries the features of a connected TV.
- */
- @Before
- public void setUp() throws RemoteException {
- mContextSpy = spy(new ContextWrapper(
- InstrumentationRegistry.getInstrumentation().getTargetContext()));
-
- mHdmiControlServiceSpy = spy(new HdmiControlService(mContextSpy, Collections.emptyList()));
- doNothing().when(mHdmiControlServiceSpy)
- .writeStringSystemProperty(anyString(), anyString());
-
- mLooper = mTestLooper.getLooper();
- mHdmiControlServiceSpy.setIoLooper(mLooper);
- mHdmiControlServiceSpy.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
-
- mNativeWrapper = new FakeNativeWrapper();
- mNativeWrapper.setPhysicalAddress(mPhysicalAddress);
-
- mHdmiCecController = HdmiCecController.createWithNativeWrapper(
- mHdmiControlServiceSpy, mNativeWrapper, mHdmiControlServiceSpy.getAtomWriter());
- mHdmiControlServiceSpy.setCecController(mHdmiCecController);
- mHdmiControlServiceSpy.setHdmiMhlController(
- HdmiMhlControllerStub.create(mHdmiControlServiceSpy));
- mHdmiControlServiceSpy.initService();
- mPowerManager = new FakePowerManagerWrapper(mContextSpy);
- mHdmiControlServiceSpy.setPowerManager(mPowerManager);
-
- mPlaybackDevice = new HdmiCecLocalDevicePlayback(mHdmiControlServiceSpy);
- mPlaybackDevice.init();
- mLocalDevices.add(mPlaybackDevice);
-
- mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
- mHdmiControlServiceSpy.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
- mTestLooper.dispatchAll();
-
- synchronized (mPlaybackDevice.mLock) {
- mPlaybackLogicalAddress = mPlaybackDevice.getDeviceInfo().getLogicalAddress();
- }
-
- // Setup specific to these tests
- mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
- Constants.ADDR_TV, 0x0000, HdmiDeviceInfo.DEVICE_TV));
- mTestLooper.dispatchAll();
-
- mTestCallback = new TestCallback();
- mAction = new GiveFeaturesAction(mPlaybackDevice, Constants.ADDR_TV, mTestCallback);
- }
-
- @Test
- public void sendsGiveFeaturesMessage() {
- mPlaybackDevice.addAndStartAction(mAction);
- mTestLooper.dispatchAll();
-
- HdmiCecMessage giveFeatures = HdmiCecMessageBuilder.buildGiveFeatures(
- mPlaybackLogicalAddress, Constants.ADDR_TV);
- assertThat(mNativeWrapper.getResultMessages()).contains(giveFeatures);
- }
-
- @Test
- public void noMatchingReportFeaturesReceived_actionFailsAndNetworkIsNotUpdated() {
- mPlaybackDevice.addAndStartAction(mAction);
- mTestLooper.dispatchAll();
-
- // Wrong source
- mNativeWrapper.onCecMessage(ReportFeaturesMessage.build(
- Constants.ADDR_AUDIO_SYSTEM, HdmiControlManager.HDMI_CEC_VERSION_2_0,
- Arrays.asList(DEVICE_AUDIO_SYSTEM), Constants.RC_PROFILE_SOURCE,
- Collections.emptyList(), DeviceFeatures.NO_FEATURES_SUPPORTED));
- mTestLooper.dispatchAll();
-
- mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
- mTestLooper.dispatchAll();
-
- @DeviceFeatures.FeatureSupportStatus int avcSupport =
- mHdmiControlServiceSpy.getHdmiCecNetwork().getCecDeviceInfo(Constants.ADDR_TV)
- .getDeviceFeatures().getSetAudioVolumeLevelSupport();
-
- assertThat(avcSupport).isEqualTo(FEATURE_SUPPORT_UNKNOWN);
- assertThat(mTestCallback.getResult()).isEqualTo(
- HdmiControlManager.RESULT_COMMUNICATION_FAILED);
- }
-
- @Test
- public void matchingReportFeaturesReceived_actionSucceedsAndNetworkIsUpdated() {
- mPlaybackDevice.addAndStartAction(mAction);
- mTestLooper.dispatchAll();
-
- mNativeWrapper.onCecMessage(
- ReportFeaturesMessage.build(
- Constants.ADDR_TV, HDMI_CEC_VERSION_2_0, Collections.emptyList(),
- Constants.RC_PROFILE_TV, Lists.newArrayList(Constants.RC_PROFILE_TV_NONE),
- DeviceFeatures.NO_FEATURES_SUPPORTED.toBuilder()
- .setSetAudioVolumeLevelSupport(FEATURE_SUPPORTED)
- .build()
- )
- );
- mTestLooper.dispatchAll();
-
- @DeviceFeatures.FeatureSupportStatus int avcSupport =
- mHdmiControlServiceSpy.getHdmiCecNetwork().getCecDeviceInfo(Constants.ADDR_TV)
- .getDeviceFeatures().getSetAudioVolumeLevelSupport();
-
- assertThat(avcSupport).isEqualTo(FEATURE_SUPPORTED);
- assertThat(mTestCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
- }
-
- private static class TestCallback extends IHdmiControlCallback.Stub {
- private final ArrayList<Integer> mCallbackResult = new ArrayList<Integer>();
-
- @Override
- public void onComplete(int result) {
- mCallbackResult.add(result);
- }
-
- private int getResult() {
- assertThat(mCallbackResult.size()).isEqualTo(1);
- return mCallbackResult.get(0);
- }
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index b2f506a..89450ff 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -210,6 +210,8 @@
Settings.Global.putInt(mContextSpy.getContentResolver(),
Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
+ Settings.Secure.putInt(mContextSpy.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 0);
mClock = new OffsettableClock.Stopped();
mTestLooper = new TestLooper(mClock::now);
@@ -709,6 +711,48 @@
assertThat(mService.getBinderServiceInstance().forceSuspend()).isFalse();
}
+ @SuppressWarnings("GuardedBy")
+ @Test
+ public void testScreensaverActivateOnSleepDisabled_powered_afterTimeout_goesToDozing() {
+ when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(true);
+
+ doAnswer(inv -> {
+ when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
+ return null;
+ }).when(mDreamManagerInternalMock).startDream(anyBoolean());
+
+ setMinimumScreenOffTimeoutConfig(5);
+ createService();
+ startSystem();
+
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ advanceTime(15000);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
+ public void testScreensaverActivateOnSleepEnabled_powered_afterTimeout_goesToDreaming() {
+ when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(true);
+ Settings.Secure.putInt(mContextSpy.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
+
+ doAnswer(inv -> {
+ when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
+ return null;
+ }).when(mDreamManagerInternalMock).startDream(anyBoolean());
+
+ setMinimumScreenOffTimeoutConfig(5);
+ createService();
+ startSystem();
+
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ advanceTime(15000);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
+ }
+
@Test
public void testSetDozeOverrideFromDreamManager_triggersSuspendBlocker() {
final String suspendBlockerName = "PowerManagerService.Display";
@@ -1042,6 +1086,23 @@
assertThat(mService.getGlobalWakefulnessLocked()).isNotEqualTo(WAKEFULNESS_ASLEEP);
}
+
+ @SuppressWarnings("GuardedBy")
+ @Test
+ public void testInattentiveSleep_goesToSleepFromDream() {
+ setAttentiveTimeout(20000);
+ createService();
+ startSystem();
+ setPluggedIn(true);
+ forceAwake();
+ forceDream();
+ when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
+
+ advanceTime(20500);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ }
+
@Test
public void testWakeLock_affectsProperDisplayGroup() {
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
@@ -1136,6 +1197,11 @@
info.displayGroupId = nonDefaultDisplayGroupId;
when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(info);
+ doAnswer(inv -> {
+ when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
+ return null;
+ }).when(mDreamManagerInternalMock).startDream(anyBoolean());
+
final String pkg = mContextSpy.getOpPackageName();
final Binder token = new Binder();
final String tag = "testRemovedDisplayGroupWakeLock_affectsNoDisplayGroups";
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 210d2fa..17464a6 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -512,8 +512,30 @@
return controller;
}
- private long getCurrentTime() {
- return TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
+ private void setupInitialUsageHistory() throws Exception {
+ final int[] userIds = new int[] { USER_ID, USER_ID2, USER_ID3 };
+ final String[] packages = new String[] {
+ PACKAGE_1,
+ PACKAGE_2,
+ PACKAGE_EXEMPTED_1,
+ PACKAGE_SYSTEM_HEADFULL,
+ PACKAGE_SYSTEM_HEADLESS,
+ PACKAGE_WELLBEING,
+ PACKAGE_BACKGROUND_LOCATION,
+ ADMIN_PKG,
+ ADMIN_PKG2,
+ ADMIN_PKG3
+ };
+ for (int userId : userIds) {
+ for (String pkg : packages) {
+ final AppIdleHistory.AppUsageHistory usageHistory = mController
+ .getAppIdleHistoryForTest().getAppUsageHistory(
+ pkg, userId, mInjector.mElapsedRealtime);
+ usageHistory.lastUsedElapsedTime = 0;
+ usageHistory.lastUsedByUserElapsedTime = 0;
+ usageHistory.lastUsedScreenTime = 0;
+ }
+ }
}
@Before
@@ -524,6 +546,7 @@
MyContextWrapper myContext = new MyContextWrapper(InstrumentationRegistry.getContext());
mInjector = new MyInjector(myContext, Looper.getMainLooper());
mController = setupController();
+ setupInitialUsageHistory();
}
@After
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 5458a5b..ff6c976 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -20,6 +20,7 @@
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
@@ -53,7 +54,7 @@
public class GroupHelperTest extends UiServiceTestCase {
private @Mock GroupHelper.Callback mCallback;
- private final static int AUTOGROUP_AT_COUNT = 4;
+ private final static int AUTOGROUP_AT_COUNT = 7;
private GroupHelper mGroupHelper;
@Before
@@ -88,7 +89,7 @@
false);
}
verify(mCallback, never()).addAutoGroupSummary(
- eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
+ eq(UserHandle.USER_SYSTEM), eq(pkg), anyString(), anyBoolean());
verify(mCallback, never()).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
@@ -105,7 +106,7 @@
mGroupHelper.onNotificationPosted(
getSbn(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
verify(mCallback, never()).addAutoGroupSummary(
- eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
+ eq(UserHandle.USER_SYSTEM), eq(pkg), anyString(), anyBoolean());
verify(mCallback, never()).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
@@ -120,7 +121,8 @@
}
mGroupHelper.onNotificationPosted(
getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.ALL), false);
- verify(mCallback, never()).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
+ verify(mCallback, never()).addAutoGroupSummary(
+ anyInt(), eq(pkg), anyString(), anyBoolean());
verify(mCallback, never()).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
@@ -136,13 +138,12 @@
mGroupHelper.onNotificationPosted(
getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"), false);
verify(mCallback, never()).addAutoGroupSummary(
- eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
+ eq(UserHandle.USER_SYSTEM), eq(pkg), anyString(), anyBoolean());
verify(mCallback, never()).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
}
-
@Test
public void testPostingOverLimit() throws Exception {
final String pkg = "package";
@@ -150,7 +151,23 @@
mGroupHelper.onNotificationPosted(
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), eq(false));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ }
+
+ @Test
+ public void testPostingOverLimit_addsOngoingFlag() throws Exception {
+ final String pkg = "package";
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+ if (i == 0) {
+ sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+ }
+ mGroupHelper.onNotificationPosted(sbn, false);
+ }
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), eq(true));
verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
@@ -178,7 +195,7 @@
int userId = UserHandle.SYSTEM.getIdentifier();
assertEquals(mGroupHelper.getOngoingGroupCount(
- userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT + 1);
+ userId, pkg), AUTOGROUP_AT_COUNT + 1);
}
@Test
@@ -199,15 +216,14 @@
}
notifications.get(0).getNotification().flags &= ~Notification.FLAG_ONGOING_EVENT;
-
- mGroupHelper.onNotificationUpdated(notifications.get(0), true);
+ mGroupHelper.onNotificationUpdated(notifications.get(0));
verify(mCallback, times(AUTOGROUP_AT_COUNT + 2))
.updateAutogroupSummary(anyInt(), anyString(), eq(true));
int userId = UserHandle.SYSTEM.getIdentifier();
assertEquals(mGroupHelper.getOngoingGroupCount(
- userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT);
+ userId, pkg), AUTOGROUP_AT_COUNT);
}
@Test
@@ -229,18 +245,18 @@
notifications.get(0).getNotification().flags &= ~Notification.FLAG_ONGOING_EVENT;
- mGroupHelper.onNotificationUpdated(notifications.get(0), true);
+ mGroupHelper.onNotificationUpdated(notifications.get(0));
notifications.get(0).getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
- mGroupHelper.onNotificationUpdated(notifications.get(0), true);
+ mGroupHelper.onNotificationUpdated(notifications.get(0));
verify(mCallback, times(AUTOGROUP_AT_COUNT + 3))
.updateAutogroupSummary(anyInt(), anyString(), eq(true));
int userId = UserHandle.SYSTEM.getIdentifier();
assertEquals(mGroupHelper.getOngoingGroupCount(
- userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT + 1);
+ userId, pkg), AUTOGROUP_AT_COUNT + 1);
}
@Test
@@ -267,7 +283,7 @@
int userId = UserHandle.SYSTEM.getIdentifier();
assertEquals(mGroupHelper.getOngoingGroupCount(
- userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT);
+ userId, pkg), AUTOGROUP_AT_COUNT);
}
@@ -288,14 +304,14 @@
}
notifications.get(0).getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
- mGroupHelper.onNotificationUpdated(notifications.get(0), true);
+ mGroupHelper.onNotificationUpdated(notifications.get(0));
verify(mCallback, times(1))
.updateAutogroupSummary(anyInt(), anyString(), eq(true));
int userId = UserHandle.SYSTEM.getIdentifier();
assertEquals(mGroupHelper.getOngoingGroupCount(
- userId, pkg, AUTOGROUP_KEY), 1);
+ userId, pkg), 1);
}
@Test
@@ -305,7 +321,7 @@
for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) {
notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
}
- StatusBarNotification sbn = notifications.get(0);
+ StatusBarNotification sbn = notifications.get(AUTOGROUP_AT_COUNT);
sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
sbn.setOverrideGroupKey(AUTOGROUP_KEY);
@@ -319,7 +335,7 @@
int userId = UserHandle.SYSTEM.getIdentifier();
assertEquals(mGroupHelper.getOngoingGroupCount(
- userId, pkg, AUTOGROUP_KEY), 1);
+ userId, pkg), 1);
}
@Test
@@ -342,7 +358,7 @@
.updateAutogroupSummary(anyInt(), anyString(), eq(true));
int userId = UserHandle.SYSTEM.getIdentifier();
- assertEquals(mGroupHelper.getOngoingGroupCount(userId, pkg, AUTOGROUP_KEY), 0);
+ assertEquals(mGroupHelper.getOngoingGroupCount(userId, pkg), 0);
}
@@ -355,7 +371,7 @@
posted.add(sbn);
mGroupHelper.onNotificationPosted(sbn, false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), eq(false));
verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
@@ -382,28 +398,22 @@
posted.add(sbn);
mGroupHelper.onNotificationPosted(sbn, false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
+ verify(mCallback, times(1)).addAutoGroupSummary(
+ anyInt(), eq(pkg), anyString(), anyBoolean());
verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
Mockito.reset(mCallback);
- int i = 0;
- for (i = 0; i < AUTOGROUP_AT_COUNT - 2; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn =
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
mGroupHelper.onNotificationPosted(sbn, false);
+ verify(mCallback, times(1)).removeAutoGroup(sbn.getKey());
+ if (i < AUTOGROUP_AT_COUNT -1) {
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ }
}
- verify(mCallback, times(AUTOGROUP_AT_COUNT - 2)).removeAutoGroup(anyString());
- verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
- Mockito.reset(mCallback);
-
- for (; i < AUTOGROUP_AT_COUNT; i++) {
- final StatusBarNotification sbn =
- getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
- mGroupHelper.onNotificationPosted(sbn, false);
- }
- verify(mCallback, times(2)).removeAutoGroup(anyString());
verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
}
@@ -417,7 +427,7 @@
posted.add(sbn);
mGroupHelper.onNotificationPosted(sbn, false);
}
- verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), eq(false));
verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
@@ -441,7 +451,7 @@
final StatusBarNotification sbn = getSbn(pkg, 5, String.valueOf(5), UserHandle.SYSTEM);
posted.add(sbn);
mGroupHelper.onNotificationPosted(sbn, true);
- verify(mCallback, times(posted.size())).addAutoGroup(anyString());
+ verify(mCallback, times(1)).addAutoGroup(sbn.getKey());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
index d4420bd..f4b9e25 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
@@ -27,8 +27,13 @@
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.INotificationManager;
@@ -38,8 +43,10 @@
import android.content.pm.ServiceInfo;
import android.content.pm.VersionedPackage;
import android.os.Bundle;
+import android.os.UserHandle;
import android.service.notification.NotificationListenerFilter;
import android.service.notification.NotificationListenerService;
+import android.testing.TestableContext;
import android.util.ArraySet;
import android.util.Pair;
import android.util.TypedXmlPullParser;
@@ -69,6 +76,7 @@
NotificationManagerService mNm;
@Mock
private INotificationManager mINm;
+ private TestableContext mContext = spy(getContext());
NotificationManagerService.NotificationListeners mListeners;
@@ -80,6 +88,7 @@
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
getContext().setMockPackageManager(mPm);
+ doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
mListeners = spy(mNm.new NotificationListeners(
mContext, new Object(), mock(ManagedServices.UserProfiles.class), miPm));
@@ -370,4 +379,13 @@
assertFalse(mListeners.hasAllowedListener(mCn2.getPackageName(), uid1));
assertFalse(mListeners.hasAllowedListener(mCn2.getPackageName(), uid2));
}
+
+ @Test
+ public void testBroadcastUsers() {
+ int userId = 0;
+ mListeners.setPackageOrComponentEnabled(mCn1.flattenToString(), userId, true, false, true);
+
+ verify(mContext).sendBroadcastAsUser(
+ any(), eq(UserHandle.of(userId)), nullable(String.class));
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
index 2ba587d..0f6d5a5 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
@@ -722,7 +722,7 @@
when(mPermissionHelper.isPermissionFixed(PKG, temp.getUserId())).thenReturn(true);
NotificationRecord r = mService.createAutoGroupSummary(
- temp.getUserId(), temp.getSbn().getPackageName(), temp.getKey());
+ temp.getUserId(), temp.getSbn().getPackageName(), temp.getKey(), false);
assertThat(r.isImportanceFixed()).isTrue();
}
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index 57bbe40..079d765 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -58,6 +58,7 @@
"hamcrest-library",
"platform-compat-test-rules",
"CtsSurfaceValidatorLib",
+ "service-sdksandbox.impl",
],
libs: [
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index f9d4dff..3be7011 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -3159,12 +3159,14 @@
doReturn(true).when(app2).isReadyToDispatchInsetsState();
mDisplayContent.setImeLayeringTarget(app2);
mDisplayContent.updateImeInputAndControlTarget(app2);
+ mDisplayContent.mWmService.mRoot.performSurfacePlacement();
// Verify after unfreezing app2's IME insets state, we won't dispatch visible IME insets
// to client if the app didn't request IME visible.
assertFalse(app2.mActivityRecord.mImeInsetsFrozenUntilStartInput);
- verify(app2.mClient, atLeastOnce()).insetsChanged(insetsStateCaptor.capture(), anyBoolean(),
- anyBoolean());
+ verify(app2.mClient, atLeastOnce()).resized(any(), anyBoolean(), any(),
+ insetsStateCaptor.capture(), anyBoolean(), anyBoolean(), anyInt(), anyInt(),
+ anyInt());
assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
index 66da2a6..716612c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
@@ -284,7 +284,7 @@
.setCreateActivity(true).build().getTopMostActivity();
activity2.getTask().setResumedActivity(activity2, "test");
- mAtm.mAmInternal.deletePendingTopUid(activity1.getUid());
+ mAtm.mAmInternal.deletePendingTopUid(activity1.getUid(), Long.MAX_VALUE);
clearInvocations(mAtm);
activity1.moveFocusableActivityToTop("test");
assertTrue(mAtm.mAmInternal.isPendingTopUid(activity1.getUid()));
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 94f900e..97d477f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -1064,6 +1064,47 @@
verify(activity2).setDropInputMode(DropInputMode.NONE);
}
+ /**
+ * Since we don't have any use case to rely on handling input during animation, disable it even
+ * if it is trusted embedding so that it could cover some edge-cases when a previously trusted
+ * host starts doing something bad.
+ */
+ @Test
+ public void testOverrideTaskFragmentAdapter_inputProtectedForTrustedAnimation() {
+ final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
+ final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner();
+ setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner);
+
+ // Create a TaskFragment with only trusted embedded activity
+ final Task task = createTask(mDisplayContent);
+ final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
+ .setParentTask(task)
+ .createActivityCount(1)
+ .setOrganizer(organizer)
+ .build();
+ final ActivityRecord activity = taskFragment.getChildAt(0).asActivityRecord();
+ prepareActivityForAppTransition(activity);
+ doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity);
+ spyOn(mDisplayContent.mAppTransition);
+
+ // Prepare and start transition.
+ prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
+ mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+
+ // The animation will be animated remotely by client and all activities are input disabled
+ // for untrusted animation.
+ assertTrue(remoteAnimationRunner.isAnimationStarted());
+ verify(activity).setDropInputForAnimation(true);
+ verify(activity).setDropInputMode(DropInputMode.ALL);
+
+ // Reset input after animation is finished.
+ clearInvocations(activity);
+ remoteAnimationRunner.finishAnimation();
+
+ verify(activity).setDropInputForAnimation(false);
+ verify(activity).setDropInputMode(DropInputMode.NONE);
+ }
+
@Test
public void testTransitionGoodToGoForTaskFragments() {
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index 70d71bc..7409d62 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -31,13 +31,13 @@
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
-import android.window.TaskSnapshot;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
import android.util.ArraySet;
import android.view.Surface;
+import android.window.TaskSnapshot;
import androidx.test.filters.MediumTest;
@@ -83,6 +83,12 @@
assertEquals(TEST_INSETS, snapshot.getContentInsets());
assertNotNull(snapshot.getSnapshot());
assertEquals(Configuration.ORIENTATION_PORTRAIT, snapshot.getOrientation());
+
+ snapshot.getHardwareBuffer().close();
+ mPersister.persistSnapshot(1, mTestUserId, snapshot);
+ mPersister.waitForQueueEmpty();
+ assertTrueForFiles(files, file -> !file.exists(),
+ " snapshot files must be removed by invalid buffer");
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index 437d418..f71ed2f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -131,8 +131,7 @@
}
TaskSnapshot createSnapshot() {
- return new TaskSnapshotBuilder()
- .build();
+ return new TaskSnapshotBuilder().setTopActivityComponent(getUniqueComponentName()).build();
}
protected static void assertTrueForFiles(File[] files, Predicate<File> predicate,
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
index 7cf4b2e..bb5aceb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
@@ -43,17 +43,14 @@
@Override
public void resized(ClientWindowFrames frames, boolean reportDraw,
- MergedConfiguration mergedConfig, boolean forceLayout, boolean alwaysConsumeSystemBars,
- int displayId, int seqId, int resizeMode) throws RemoteException {
- }
-
- @Override
- public void insetsChanged(InsetsState insetsState, boolean willMove, boolean willResize) {
+ MergedConfiguration mergedConfig, InsetsState insetsState, boolean forceLayout,
+ boolean alwaysConsumeSystemBars, int displayId, int seqId, int resizeMode)
+ throws RemoteException {
}
@Override
public void insetsControlChanged(InsetsState insetsState,
- InsetsSourceControl[] activeControls, boolean willMove, boolean willResize) {
+ InsetsSourceControl[] activeControls) {
}
@Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 9faf499..eb91d5e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -309,6 +309,52 @@
}
@Test
+ public void testUnregisterOrganizer_removesTasksCreatedByIt() throws RemoteException {
+ final Task rootTask = createRootTask();
+ final Task task = createTask(rootTask);
+ final Task rootTask2 = createRootTask();
+ rootTask2.mCreatedByOrganizer = true;
+ final Task task2 = createTask(rootTask2);
+ final ArrayList<TaskAppearedInfo> existingTasks = new ArrayList<>();
+ final ITaskOrganizer organizer = registerMockOrganizer(existingTasks);
+ // Ensure events dispatch to organizer.
+ mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
+
+ // verify that tasks are returned and taskAppeared is called only for rootTask2 since it
+ // is the one created by this organizer.
+ assertContainsTasks(existingTasks, rootTask);
+ verify(organizer, times(1)).onTaskAppeared(any(RunningTaskInfo.class),
+ any(SurfaceControl.class));
+ verify(organizer, times(0)).onTaskVanished(any());
+ assertTrue(rootTask.isOrganized());
+
+ // Now we replace the registration and verify the new organizer receives existing tasks
+ final ArrayList<TaskAppearedInfo> existingTasks2 = new ArrayList<>();
+ final ITaskOrganizer organizer2 = registerMockOrganizer(existingTasks2);
+ // Ensure events dispatch to organizer.
+ mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
+ assertContainsTasks(existingTasks2, rootTask);
+ verify(organizer2, times(1)).onTaskAppeared(any(RunningTaskInfo.class),
+ any(SurfaceControl.class));
+ verify(organizer2, times(0)).onTaskVanished(any());
+ // Removed tasks from the original organizer
+ assertTaskVanished(organizer, true /* expectVanished */, rootTask, rootTask2);
+ assertTrue(rootTask2.isOrganized());
+
+ // Now we unregister the second one, the first one should automatically be reregistered
+ // so we verify that it's now seeing changes.
+ mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer2);
+ // Ensure events dispatch to organizer.
+ mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
+
+ verify(organizer, times(2))
+ .onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
+ assertFalse(rootTask2.isOrganized());
+ assertTaskVanished(organizer2, true /* expectVanished */, rootTask,
+ rootTask2);
+ }
+
+ @Test
public void testOrganizerDeathReturnsRegistrationToPrevious() throws RemoteException {
final Task rootTask = createRootTask();
final Task task = createTask(rootTask);
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 91bde7b..bb0c7f7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -692,8 +692,9 @@
try {
doThrow(new RemoteException("test")).when(win.mClient).resized(any() /* frames */,
anyBoolean() /* reportDraw */, any() /* mergedConfig */,
- anyBoolean() /* forceLayout */, anyBoolean() /* alwaysConsumeSystemBars */,
- anyInt() /* displayId */, anyInt() /* seqId */, anyInt() /* resizeMode */);
+ any() /* insetsState */, anyBoolean() /* forceLayout */,
+ anyBoolean() /* alwaysConsumeSystemBars */, anyInt() /* displayId */,
+ anyInt() /* seqId */, anyInt() /* resizeMode */);
} catch (RemoteException ignored) {
}
win.reportResized();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 6e0d854..bcab4a5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -903,7 +903,7 @@
doReturn(100).when(hardwareBuffer).getHeight();
}
- private static ComponentName getUniqueComponentName() {
+ static ComponentName getUniqueComponentName() {
return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
DEFAULT_COMPONENT_CLASS_NAME + sCurrentActivityId++);
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 366ab09..da54c32 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -79,6 +79,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -1982,6 +1983,10 @@
}
}
+ void clearLastUsedTimestamps(@NonNull String packageName, @UserIdInt int userId) {
+ mAppStandby.clearLastUsedTimestampsForTest(packageName, userId);
+ }
+
private final class BinderService extends IUsageStatsManager.Stub {
private boolean hasPermission(String callingPackage) {
@@ -2816,6 +2821,14 @@
}
return mAppStandby.getAppStandbyConstant(key);
}
+
+ @Override
+ public int handleShellCommand(@NonNull ParcelFileDescriptor in,
+ @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
+ @NonNull String[] args) {
+ return new UsageStatsShellCommand(UsageStatsService.this).exec(this,
+ in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), args);
+ }
}
void registerAppUsageObserver(int callingUid, int observerId, String[] packages,
diff --git a/services/usage/java/com/android/server/usage/UsageStatsShellCommand.java b/services/usage/java/com/android/server/usage/UsageStatsShellCommand.java
new file mode 100644
index 0000000..772b22a
--- /dev/null
+++ b/services/usage/java/com/android/server/usage/UsageStatsShellCommand.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.usage;
+
+import android.annotation.SuppressLint;
+import android.app.ActivityManager;
+import android.os.ShellCommand;
+import android.os.UserHandle;
+
+import java.io.PrintWriter;
+
+class UsageStatsShellCommand extends ShellCommand {
+ private final UsageStatsService mService;
+
+ UsageStatsShellCommand(UsageStatsService usageStatsService) {
+ mService = usageStatsService;
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ if (cmd == null) {
+ return handleDefaultCommands(null);
+ }
+ switch (cmd) {
+ case "clear-last-used-timestamps":
+ return runClearLastUsedTimestamps();
+ default:
+ return handleDefaultCommands(cmd);
+ }
+ }
+
+ @Override
+ public void onHelp() {
+ final PrintWriter pw = getOutPrintWriter();
+ pw.println("UsageStats service (usagestats) commands:");
+ pw.println("help");
+ pw.println(" Print this help text.");
+ pw.println();
+ pw.println("clear-last-used-timestamps PACKAGE_NAME [-u | --user USER_ID]");
+ pw.println(" Clears any existing usage data for the given package.");
+ pw.println();
+ }
+
+ @SuppressLint("AndroidFrameworkRequiresPermission")
+ private int runClearLastUsedTimestamps() {
+ final String packageName = getNextArgRequired();
+
+ int userId = UserHandle.USER_CURRENT;
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ if ("-u".equals(opt) || "--user".equals(opt)) {
+ userId = UserHandle.parseUserArg(getNextArgRequired());
+ } else {
+ getErrPrintWriter().println("Error: unknown option: " + opt);
+ return -1;
+ }
+ }
+ if (userId == UserHandle.USER_CURRENT) {
+ userId = ActivityManager.getCurrentUser();
+ }
+
+ mService.clearLastUsedTimestamps(packageName, userId);
+ return 0;
+ }
+}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index b290669..b2cc104 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -175,7 +175,11 @@
// Delay for debouncing USB disconnects.
// We often get rapid connect/disconnect events when enabling USB functions,
// which need debouncing.
- private static final int UPDATE_DELAY = 1000;
+ private static final int DEVICE_STATE_UPDATE_DELAY_EXT = 3000;
+ private static final int DEVICE_STATE_UPDATE_DELAY = 1000;
+
+ // Delay for debouncing USB disconnects on Type-C ports in host mode
+ private static final int HOST_STATE_UPDATE_DELAY = 1000;
// Timeout for entering USB request mode.
// Request is cancelled if host does not configure device within 10 seconds.
@@ -646,7 +650,9 @@
msg.arg1 = connected;
msg.arg2 = configured;
// debounce disconnects to avoid problems bringing up USB tethering
- sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0);
+ sendMessageDelayed(msg,
+ (connected == 0) ? (mScreenLocked ? DEVICE_STATE_UPDATE_DELAY
+ : DEVICE_STATE_UPDATE_DELAY_EXT) : 0);
}
public void updateHostState(UsbPort port, UsbPortStatus status) {
@@ -661,7 +667,7 @@
removeMessages(MSG_UPDATE_PORT_STATE);
Message msg = obtainMessage(MSG_UPDATE_PORT_STATE, args);
// debounce rapid transitions of connect/disconnect on type-c ports
- sendMessageDelayed(msg, UPDATE_DELAY);
+ sendMessageDelayed(msg, HOST_STATE_UPDATE_DELAY);
}
private void setAdbEnabled(boolean enable) {
diff --git a/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java b/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java
index 0fa79df..04c52f7 100644
--- a/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java
+++ b/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java
@@ -84,7 +84,7 @@
private final Object mLock = new Object();
private boolean mIsOpen;
- private final UsbMidiPacketConverter mUsbMidiPacketConverter = new UsbMidiPacketConverter();
+ private UsbMidiPacketConverter mUsbMidiPacketConverter;
private final MidiDeviceServer.Callback mCallback = new MidiDeviceServer.Callback() {
@@ -264,6 +264,11 @@
Log.d(TAG, "openLocked()");
UsbManager manager = mContext.getSystemService(UsbManager.class);
+ // Converting from raw MIDI to USB MIDI is not thread-safe.
+ // UsbMidiPacketConverter creates a converter from raw MIDI
+ // to USB MIDI for each USB output.
+ mUsbMidiPacketConverter = new UsbMidiPacketConverter(mNumOutputs);
+
mUsbDeviceConnections = new ArrayList<UsbDeviceConnection>(mUsbInterfaces.size());
mInputUsbEndpoints = new ArrayList<ArrayList<UsbEndpoint>>(mUsbInterfaces.size());
mOutputUsbEndpoints = new ArrayList<ArrayList<UsbEndpoint>>(mUsbInterfaces.size());
@@ -415,7 +420,7 @@
} else {
convertedArray =
mUsbMidiPacketConverter.rawMidiToUsbMidi(
- event.data, event.count);
+ event.data, event.count, portFinal);
}
if (DEBUG) {
@@ -518,6 +523,8 @@
mInputUsbEndpoints = null;
mOutputUsbEndpoints = null;
+ mUsbMidiPacketConverter = null;
+
mIsOpen = false;
}
diff --git a/services/usb/java/com/android/server/usb/UsbMidiPacketConverter.java b/services/usb/java/com/android/server/usb/UsbMidiPacketConverter.java
index 7c93c76..56bb236 100644
--- a/services/usb/java/com/android/server/usb/UsbMidiPacketConverter.java
+++ b/services/usb/java/com/android/server/usb/UsbMidiPacketConverter.java
@@ -74,8 +74,15 @@
private static final byte SYSEX_START_EXCLUSIVE = (byte) 0xF0;
private static final byte SYSEX_END_EXCLUSIVE = (byte) 0xF7;
- private UsbMidiEncoder mUsbMidiEncoder = new UsbMidiEncoder();
private UsbMidiDecoder mUsbMidiDecoder = new UsbMidiDecoder();
+ private UsbMidiEncoder[] mUsbMidiEncoders;
+
+ public UsbMidiPacketConverter(int numEncoders) {
+ mUsbMidiEncoders = new UsbMidiEncoder[numEncoders];
+ for (int i = 0; i < numEncoders; i++) {
+ mUsbMidiEncoders[i] = new UsbMidiEncoder();
+ }
+ }
/**
* Converts a USB MIDI array into a raw MIDI array.
@@ -93,10 +100,11 @@
*
* @param midiBytes the raw MIDI bytes to convert
* @param size the size of usbMidiBytes
+ * @param encoderId which encoder to use
* @return byte array of USB MIDI packets
*/
- public byte[] rawMidiToUsbMidi(byte[] midiBytes, int size) {
- return mUsbMidiEncoder.encode(midiBytes, size);
+ public byte[] rawMidiToUsbMidi(byte[] midiBytes, int size, int encoderId) {
+ return mUsbMidiEncoders[encoderId].encode(midiBytes, size);
}
private class UsbMidiDecoder {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index d527a23..c86f38d 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -679,6 +679,7 @@
private void restartProcessLocked() {
Slog.v(TAG, "Restarting hotword detection process");
ServiceConnection oldConnection = mRemoteHotwordDetectionService;
+ HotwordDetectionServiceIdentity previousIdentity = mIdentity;
// TODO(volnov): this can be done after connect() has been successful.
if (mValidatingDspTrigger) {
@@ -722,6 +723,9 @@
}
oldConnection.ignoreConnectionStatusEvents();
oldConnection.unbind();
+ if (previousIdentity != null) {
+ removeServiceUidForAudioPolicy(previousIdentity.getIsolatedUid());
+ }
}
static final class SoundTriggerCallback extends IRecognitionStatusCallback.Stub {
diff --git a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java
index 0d0b3e0..076059f 100644
--- a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java
+++ b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java
@@ -108,7 +108,7 @@
@Override
public void generateCinematicEffect(@NonNull CinematicEffectRequest request,
@NonNull ICinematicEffectListener listener) {
- if (!runForUserLocked("generateCinematicEffect", (service) ->
+ if (!runForUser("generateCinematicEffect", true, (service) ->
service.onGenerateCinematicEffectLocked(request, listener))) {
try {
listener.onCinematicEffectGenerated(
@@ -126,7 +126,7 @@
@Override
public void returnCinematicEffectResponse(@NonNull CinematicEffectResponse response) {
- runForUserLocked("returnCinematicResponse", (service) ->
+ runForUser("returnCinematicResponse", false, (service) ->
service.onReturnCinematicEffectResponseLocked(response));
}
@@ -140,30 +140,42 @@
}
/**
- * Execute the operation for the user locked. Return true if
- * WallpaperEffectsGenerationPerUserService is found for the user.
- * Otherwise return false.
+ * Execute the operation for the user.
+ *
+ * @param func The name of function for logging purpose.
+ * @param checkManageWallpaperEffectsPermission whether to check if caller has
+ * MANAGE_WALLPAPER_EFFECTS_GENERATION.
+ * If false, check the uid of caller matching bind service.
+ * @param c WallpaperEffectsGenerationPerUserService operation.
+ * @return whether WallpaperEffectsGenerationPerUserService is found.
*/
- private boolean runForUserLocked(@NonNull final String func,
+ private boolean runForUser(@NonNull final String func,
+ @NonNull final boolean checkManageWallpaperEffectsPermission,
@NonNull final Consumer<WallpaperEffectsGenerationPerUserService> c) {
ActivityManagerInternal am = LocalServices.getService(ActivityManagerInternal.class);
final int userId = am.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Binder.getCallingUserHandle().getIdentifier(), false, ALLOW_NON_FULL,
null, null);
if (DEBUG) {
- Slog.d(TAG, "runForUserLocked:" + func + " from pid=" + Binder.getCallingPid()
+ Slog.d(TAG, "runForUser:" + func + " from pid=" + Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid());
}
- Context ctx = getContext();
- if (!(ctx.checkCallingPermission(MANAGE_WALLPAPER_EFFECTS_GENERATION)
- == PERMISSION_GRANTED
- || mServiceNameResolver.isTemporary(userId)
- || mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid()))) {
- String msg = "Permission Denial: Cannot call " + func + " from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
- Slog.w(TAG, msg);
- throw new SecurityException(msg);
+ if (checkManageWallpaperEffectsPermission) {
+ // MANAGE_WALLPAPER_EFFECTS_GENERATION is required for all functions except for
+ // "returnCinematicResponse", whose calling permission checked in
+ // WallpaperEffectsGenerationPerUserService against remote binding.
+ Context ctx = getContext();
+ if (!(ctx.checkCallingPermission(MANAGE_WALLPAPER_EFFECTS_GENERATION)
+ == PERMISSION_GRANTED
+ || mServiceNameResolver.isTemporary(userId)
+ || mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid()))) {
+ String msg = "Permission Denial: Cannot call " + func + " from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
}
+ final int origCallingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
boolean accepted = false;
try {
@@ -171,6 +183,16 @@
final WallpaperEffectsGenerationPerUserService service =
getServiceForUserLocked(userId);
if (service != null) {
+ // Check uid of caller matches bind service implementation if
+ // MANAGE_WALLPAPER_EFFECTS_GENERATION is skipped. This is useful
+ // for service implementation to return response.
+ if (!checkManageWallpaperEffectsPermission
+ && !service.isCallingUidAllowed(origCallingUid)) {
+ String msg = "Permission Denial: cannot call " + func + ", uid["
+ + origCallingUid + "] doesn't match service implementation";
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
accepted = true;
c.accept(service);
}
diff --git a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java
index d541051..7ba72db 100644
--- a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java
+++ b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java
@@ -141,6 +141,13 @@
invokeCinematicListenerAndCleanup(cinematicEffectResponse);
}
+ /**
+ * Checks whether the calling uid matches the bind service uid.
+ */
+ public boolean isCallingUidAllowed(int callingUid) {
+ return getServiceUidLocked() == callingUid;
+ }
+
@GuardedBy("mLock")
private void updateRemoteServiceLocked() {
if (mRemoteService != null) {
@@ -152,7 +159,6 @@
invokeCinematicListenerAndCleanup(
createErrorCinematicEffectResponse(mCinematicEffectListenerWrapper.mTaskId));
}
-
}
void onPackageUpdatedLocked() {
diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java
index 98db291..78b0b84 100644
--- a/telephony/common/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/common/com/android/internal/telephony/SmsApplication.java
@@ -68,7 +68,7 @@
public final class SmsApplication {
static final String LOG_TAG = "SmsApplication";
public static final String PHONE_PACKAGE_NAME = "com.android.phone";
- public static final String BLUETOOTH_PACKAGE_NAME = "com.android.bluetooth";
+ public static final String BLUETOOTH_PACKAGE_NAME = "com.android.bluetooth.services";
public static final String MMS_SERVICE_PACKAGE_NAME = "com.android.mms.service";
public static final String TELEPHONY_PROVIDER_PACKAGE_NAME = "com.android.providers.telephony";
diff --git a/telephony/java/android/telephony/ModemActivityInfo.java b/telephony/java/android/telephony/ModemActivityInfo.java
index 730a9d1..2d0135a 100644
--- a/telephony/java/android/telephony/ModemActivityInfo.java
+++ b/telephony/java/android/telephony/ModemActivityInfo.java
@@ -383,8 +383,6 @@
* activity.
*/
public @NonNull ModemActivityInfo getDelta(@NonNull ModemActivityInfo other) {
- int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
-
ActivityStatsTechSpecificInfo[] mDeltaSpecificInfo;
mDeltaSpecificInfo = new ActivityStatsTechSpecificInfo[other.getSpecificInfoLength()];
@@ -399,6 +397,7 @@
if (other.mActivityStatsTechSpecificInfo[i].getFrequencyRange()
== mActivityStatsTechSpecificInfo[j].getFrequencyRange()) {
int freq = mActivityStatsTechSpecificInfo[j].getFrequencyRange();
+ int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
txTimeMs[lvl] =
(int) (other.getTransmitDurationMillisAtPowerLevel(
@@ -416,6 +415,7 @@
- getReceiveTimeMillis(rat, freq)));
}
} else {
+ int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
txTimeMs[lvl] =
(int) (other.getTransmitDurationMillisAtPowerLevel(lvl, rat)
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 725518d..ade5543 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -16788,32 +16788,6 @@
}
/**
- * Callback to listen for when the set of packages with carrier privileges for a SIM changes.
- *
- * @hide
- * @deprecated Use {@link CarrierPrivilegesCallback} instead. This API will be removed soon
- * prior to API finalization.
- */
- @Deprecated
- @SystemApi
- public interface CarrierPrivilegesListener {
- /**
- * Called when the set of packages with carrier privileges has changed.
- *
- * <p>Of note, this callback will <b>not</b> be fired if a carrier triggers a SIM profile
- * switch and the same set of packages remains privileged after the switch.
- *
- * <p>At registration, the callback will receive the current set of privileged packages.
- *
- * @param privilegedPackageNames The updated set of package names that have carrier
- * privileges
- * @param privilegedUids The updated set of UIDs that have carrier privileges
- */
- void onCarrierPrivilegesChanged(
- @NonNull List<String> privilegedPackageNames, @NonNull int[] privilegedUids);
- }
-
- /**
* Callbacks to listen for when the set of packages with carrier privileges for a SIM changes.
*
* <p>Of note, when multiple callbacks are registered, they may be triggered one after another.
@@ -16862,61 +16836,6 @@
}
/**
- * Registers a {@link CarrierPrivilegesListener} on the given {@code logicalSlotIndex} to
- * receive callbacks when the set of packages with carrier privileges changes. The callback will
- * immediately be called with the latest state.
- *
- * @param logicalSlotIndex The SIM slot to listen on
- * @param executor The executor where {@code listener} will be invoked
- * @param listener The callback to register
- * @hide
- * @deprecated Use {@link #registerCarrierPrivilegesCallback} instead. This API will be
- * removed prior to API finalization.
- */
- @Deprecated
- @SystemApi
- @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public void addCarrierPrivilegesListener(
- int logicalSlotIndex,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull CarrierPrivilegesListener listener) {
- if (mContext == null) {
- throw new IllegalStateException("Telephony service is null");
- } else if (executor == null || listener == null) {
- throw new IllegalArgumentException(
- "CarrierPrivilegesListener and executor must be non-null");
- }
- mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
- if (mTelephonyRegistryMgr == null) {
- throw new IllegalStateException("Telephony registry service is null");
- }
- mTelephonyRegistryMgr.addCarrierPrivilegesListener(logicalSlotIndex, executor, listener);
- }
-
- /**
- * Unregisters an existing {@link CarrierPrivilegesListener}.
- *
- * @hide
- * @deprecated Use {@link #unregisterCarrierPrivilegesCallback} instead. This API will be
- * removed prior to API finalization.
- */
- @Deprecated
- @SystemApi
- @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public void removeCarrierPrivilegesListener(@NonNull CarrierPrivilegesListener listener) {
- if (mContext == null) {
- throw new IllegalStateException("Telephony service is null");
- } else if (listener == null) {
- throw new IllegalArgumentException("CarrierPrivilegesListener must be non-null");
- }
- mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
- if (mTelephonyRegistryMgr == null) {
- throw new IllegalStateException("Telephony registry service is null");
- }
- mTelephonyRegistryMgr.removeCarrierPrivilegesListener(listener);
- }
-
- /**
* Sets a voice service state override from telecom based on the current {@link PhoneAccount}s
* registered. See {@link PhoneAccount#CAPABILITY_VOICE_CALLING_AVAILABLE}.
*
diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java
index a846088..fb97336 100644
--- a/telephony/java/android/telephony/data/QualifiedNetworksService.java
+++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java
@@ -26,6 +26,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.Annotation.ApnType;
import android.util.Log;
@@ -134,26 +135,31 @@
* invoked for certain APN types, then frameworks uses its own logic to determine the
* transport to setup the data network.
*
- * For example, QNS can suggest frameworks to setup IMS on IWLAN by specifying
- * {@link ApnSetting#TYPE_IMS} with a list containing single element
+ * For example, QNS can suggest frameworks setting up IMS data network on IWLAN by
+ * specifying {@link ApnSetting#TYPE_IMS} with a list containing
* {@link AccessNetworkType#IWLAN}.
*
- * Or if QNS consider multiple access networks are qualified for certain APN type, it can
- * suggest frameworks by specifying the APN type with multiple elements in the list like
- * {{@link AccessNetworkType#EUTRAN}, {@link AccessNetworkType#IWLAN}}. Frameworks will then
- * first attempt to setup data on LTE network. If the device moves from LTE to UMTS, then
- * frameworks can perform handover the data network to the second preferred access network
- * if available.
+ * If QNS considers multiple access networks qualified for certain APN type, it can
+ * suggest frameworks by specifying the APN type with multiple access networks in the list,
+ * for example {{@link AccessNetworkType#EUTRAN}, {@link AccessNetworkType#IWLAN}}.
+ * Frameworks will then first attempt to setup data on LTE network, and If the device moves
+ * from LTE to UMTS, then frameworks will perform handover the data network to the second
+ * preferred access network if available.
*
* If the {@code qualifiedNetworkTypes} list is empty, it means QNS has no suggestion to the
- * frameworks, and frameworks will decide the transport to setup the data network.
+ * frameworks, and for that APN type frameworks will route the corresponding network
+ * requests to {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN}.
*
- * @param apnTypes APN types of the qualified networks. This must be a bitmask combination
- * of {@link ApnType}.
- * @param qualifiedNetworkTypes List of network types which are qualified for data
- * connection setup for {@link @apnType} in the preferred order. Each element in the list
- * is a {@link AccessNetworkType}. Note that {@link AccessNetworkType#UNKNOWN} is not a
- * valid input here.
+ * @param apnTypes APN type(s) of the qualified networks. This must be a bitmask combination
+ * of {@link ApnType}. The same qualified networks will be applicable to all APN types
+ * specified here.
+ * @param qualifiedNetworkTypes List of access network types which are qualified for data
+ * connection setup for {@code apnTypes} in the preferred order. Empty list means QNS has no
+ * suggestion to the frameworks, and for that APN type frameworks will route the
+ * corresponding network requests to {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN}.
+ *
+ * If one of the element is invalid, for example, {@link AccessNetworkType#UNKNOWN}, then
+ * this operation becomes a no-op.
*/
public final void updateQualifiedNetworkTypes(
@ApnType int apnTypes, @NonNull List<Integer> qualifiedNetworkTypes) {
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 4820d33..eede9dc 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -25,12 +25,14 @@
import android.annotation.SystemApi;
import android.app.Activity;
import android.app.PendingIntent;
+import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
+import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
@@ -827,6 +829,18 @@
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
public static final long SWITCH_WITHOUT_PORT_INDEX_EXCEPTION_ON_DISABLE = 218393363L;
+ /**
+ * With support for MEP(multiple enabled profile) in Android T, a SIM card can enable multiple
+ * profile on different port. If apps are not target SDK T yet and keep calling the
+ * switchToSubscription or download API without specifying the port index, we should
+ * keep the existing behaviour by always use port index 0 even the device itself has MEP eUICC,
+ * this is for carrier app's backward compatibility.
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
+ public static final long SHOULD_RESOLVE_PORT_INDEX_FOR_APPS = 224562872L;
+
private final Context mContext;
private int mCardId;
@@ -1165,7 +1179,8 @@
* subscription on the eUICC and the platform will internally resolve a port based on following
* rules:
* <ul>
- * <li>always use the default port 0 is eUICC does not support MEP.
+ * <li>always use the default port 0 is eUICC does not support MEP or the apps are
+ * not targeting on Android T.
* <li>In SS(Single SIM) mode, if the embedded slot already has an active port, then enable
* the subscription on this port.
* <li>In SS mode, if the embedded slot is not active, then try to enable the subscription on
diff --git a/tests/BlobStoreTestUtils/src/com/android/utils/blob/FakeBlobData.java b/tests/BlobStoreTestUtils/src/com/android/utils/blob/FakeBlobData.java
index 56db4f9..f469298 100644
--- a/tests/BlobStoreTestUtils/src/com/android/utils/blob/FakeBlobData.java
+++ b/tests/BlobStoreTestUtils/src/com/android/utils/blob/FakeBlobData.java
@@ -17,6 +17,7 @@
import static com.android.utils.blob.Utils.BUFFER_SIZE_BYTES;
import static com.android.utils.blob.Utils.copy;
+import static com.android.utils.blob.Utils.writeRandomData;
import static com.google.common.truth.Truth.assertThat;
@@ -123,7 +124,7 @@
public void prepare() throws Exception {
try (RandomAccessFile file = new RandomAccessFile(mFile, "rw")) {
- writeRandomData(file, mFileSize);
+ writeRandomData(file, mRandom, mFileSize);
}
mFileDigest = FileUtils.digest(mFile, "SHA-256");
mExpiryTimeMs = System.currentTimeMillis() + mExpiryDurationMs;
@@ -239,18 +240,4 @@
}
return digest.digest();
}
-
- private void writeRandomData(RandomAccessFile file, long fileSize)
- throws Exception {
- long bytesWritten = 0;
- final byte[] buffer = new byte[BUFFER_SIZE_BYTES];
- while (bytesWritten < fileSize) {
- mRandom.nextBytes(buffer);
- final int toWrite = (bytesWritten + buffer.length <= fileSize)
- ? buffer.length : (int) (fileSize - bytesWritten);
- file.seek(bytesWritten);
- file.write(buffer, 0, toWrite);
- bytesWritten += toWrite;
- }
- }
}
diff --git a/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java b/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java
index 2d230a7..f6c0e6d 100644
--- a/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java
+++ b/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java
@@ -30,11 +30,14 @@
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;
+import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.util.Random;
public class Utils {
public static final String TAG = "BlobStoreTest";
@@ -164,6 +167,25 @@
runShellCmd("cmd blob_store idle-maintenance");
}
+ public static void writeRandomData(File file, long fileSizeBytes)
+ throws Exception {
+ writeRandomData(new RandomAccessFile(file, "rw"), new Random(0), fileSizeBytes);
+ }
+
+ public static void writeRandomData(RandomAccessFile file, Random random, long fileSizeBytes)
+ throws Exception {
+ long bytesWritten = 0;
+ final byte[] buffer = new byte[BUFFER_SIZE_BYTES];
+ while (bytesWritten < fileSizeBytes) {
+ random.nextBytes(buffer);
+ final int toWrite = (bytesWritten + buffer.length <= fileSizeBytes)
+ ? buffer.length : (int) (fileSizeBytes - bytesWritten);
+ file.seek(bytesWritten);
+ file.write(buffer, 0, toWrite);
+ bytesWritten += toWrite;
+ }
+ }
+
public static String runShellCmd(String cmd) throws IOException {
final UiDevice uiDevice = UiDevice.getInstance(
InstrumentationRegistry.getInstrumentation());
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
index 2a296b7..78aea1f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
@@ -17,16 +17,25 @@
package com.android.server.wm.flicker.ime
import android.app.Instrumentation
-import android.platform.test.annotations.Postsubmit
+import android.platform.test.annotations.Presubmit
+import android.platform.test.annotations.RequiresDevice
import android.view.Surface
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.*
+import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.*
+import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper
+import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -67,26 +76,26 @@
}
}
- @Postsubmit
+ @Presubmit
@Test
fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
- @Postsubmit
+ @Presubmit
@Test
fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
- @Postsubmit
+ @Presubmit
@Test
fun imeWindowBecomesVisible() = testSpec.imeWindowBecomesVisible()
- @Postsubmit
+ @Presubmit
@Test
fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
@FlakyTest(bugId = 206753786)
fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
- @Postsubmit
+ @Presubmit
@Test
fun imeLayerBecomesVisible() = testSpec.imeLayerBecomesVisible()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
index 6f2edd0..db2e645 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
@@ -17,15 +17,23 @@
package com.android.server.wm.flicker.ime
import android.app.Instrumentation
-import android.platform.test.annotations.Postsubmit
+import android.platform.test.annotations.Presubmit
import android.platform.test.annotations.RequiresDevice
import android.view.Surface
import android.view.WindowManagerPolicyConstants
+import androidx.test.filters.FlakyTest
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.*
+import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
+import com.android.server.wm.flicker.navBarLayerIsVisible
+import com.android.server.wm.flicker.navBarWindowIsVisible
+import com.android.server.wm.flicker.statusBarLayerIsVisible
+import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.traces.common.FlickerComponentName
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import org.junit.Assume.assumeTrue
@@ -69,32 +77,32 @@
}
}
}
- @Postsubmit
+ @Presubmit
@Test
fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
- @Postsubmit
+ @Presubmit
@Test
fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
- @Postsubmit
+ @Presubmit
@Test
fun imeWindowIsAlwaysVisible() {
testSpec.imeWindowIsAlwaysVisible()
}
- @Postsubmit
+ @FlakyTest(bugId = 227189877)
@Test
fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
- @Postsubmit
+ @FlakyTest(bugId = 206753786)
@Test
fun statusBarLayerIsVisibleInPortrait() {
assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
testSpec.statusBarLayerIsVisible()
}
- @Postsubmit
+ @Presubmit
@Test
fun statusBarLayerIsInVisibleInLandscape() {
assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
@@ -106,7 +114,7 @@
}
}
- @Postsubmit
+ @Presubmit
@Test
fun imeLayerIsVisibleAndAssociatedWithAppWidow() {
testSpec.assertLayersStart {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
index c3a4769..f700416 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
@@ -74,7 +74,7 @@
* Checks that the nav bar layer starts invisible, becomes visible during unlocking animation
* and remains visible at the end
*/
- @Presubmit
+ @FlakyTest(bugId = 227083463)
@Test
fun navBarLayerVisibilityChanges() {
testSpec.assertLayers {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
index e5e2404..f83ae87 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
@@ -275,7 +275,7 @@
testSpec.assertLayers {
this.isVisible(LAUNCHER_COMPONENT)
.then()
- .isVisible(FlickerComponentName.SNAPSHOT)
+ .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
.then()
.isVisible(testApp.component)
}
diff --git a/tests/InputMethodStressTest/AndroidTest.xml b/tests/InputMethodStressTest/AndroidTest.xml
index fc54ca6..5fb260f 100644
--- a/tests/InputMethodStressTest/AndroidTest.xml
+++ b/tests/InputMethodStressTest/AndroidTest.xml
@@ -19,8 +19,8 @@
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="run-command" value="adb shell settings put secure show_ime_with_hard_keyboard 1" />
- <option name="teardown-command" value="adb shell settings delete secure show_ime_with_hard_keyboard" />
+ <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1" />
+ <option name="teardown-command" value="settings delete secure show_ime_with_hard_keyboard" />
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
index 0e86bc8..b3c63c8 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
@@ -18,16 +18,19 @@
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
+import static com.android.inputmethod.stresstest.ImeStressTestUtil.isImeShown;
import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntil;
-import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntilImeIsHidden;
-import static com.android.inputmethod.stresstest.ImeStressTestUtil.waitOnMainUntilImeIsShown;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
import android.os.Bundle;
+import android.os.SystemClock;
import android.platform.test.annotations.RootPermissionTest;
+import android.view.WindowInsets;
+import android.view.WindowInsetsAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
@@ -39,11 +42,13 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.List;
+
@RootPermissionTest
@RunWith(AndroidJUnit4.class)
public final class ImeOpenCloseStressTest {
- private static final int NUM_TEST_ITERATIONS = 100;
+ private static final int NUM_TEST_ITERATIONS = 10;
@Test
public void test() {
@@ -57,16 +62,46 @@
EditText editText = activity.getEditText();
waitOnMainUntil("activity should gain focus", editText::hasWindowFocus);
for (int i = 0; i < NUM_TEST_ITERATIONS; i++) {
+ String msgPrefix = "Iteration #" + i + " ";
instrumentation.runOnMainSync(activity::showIme);
- waitOnMainUntilImeIsShown(editText);
+ waitOnMainUntil(msgPrefix + "IME should be visible",
+ () -> !activity.isAnimating() && isImeShown(editText));
instrumentation.runOnMainSync(activity::hideIme);
- waitOnMainUntilImeIsHidden(editText);
+ waitOnMainUntil(msgPrefix + "IME should be hidden",
+ () -> !activity.isAnimating() && !isImeShown(editText));
+ // b/b/221483132, wait until IMS and IMMS handles IMM#notifyImeHidden.
+ // There is no good signal, so we just wait a second.
+ SystemClock.sleep(1000);
}
}
public static class TestActivity extends Activity {
private EditText mEditText;
+ private boolean mIsAnimating;
+
+ private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
+ new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
+ @Override
+ public WindowInsetsAnimation.Bounds onStart(WindowInsetsAnimation animation,
+ WindowInsetsAnimation.Bounds bounds) {
+ mIsAnimating = true;
+ return super.onStart(animation, bounds);
+ }
+
+ @Override
+ public void onEnd(WindowInsetsAnimation animation) {
+ super.onEnd(animation);
+ mIsAnimating = false;
+ }
+
+ @Override
+ public WindowInsets onProgress(WindowInsets insets,
+ List<WindowInsetsAnimation> runningAnimations) {
+ return insets;
+ }
+ };
+
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -76,6 +111,9 @@
mEditText = new EditText(this);
rootView.addView(mEditText, new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
setContentView(rootView);
+ // Enable WindowInsetsAnimation.
+ getWindow().setDecorFitsSystemWindows(false);
+ mEditText.setWindowInsetsAnimationCallback(mWindowInsetsAnimationCallback);
}
public EditText getEditText() {
@@ -92,5 +130,9 @@
InputMethodManager imm = getSystemService(InputMethodManager.class);
imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
}
+
+ public boolean isAnimating() {
+ return mIsAnimating;
+ }
}
}
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java
new file mode 100644
index 0000000..e0215f55
--- /dev/null
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.stresstest;
+
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.RemoteInput;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.platform.test.annotations.RootPermissionTest;
+import android.provider.Settings;
+import android.view.KeyEvent;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.TimeUnit;
+
+@RootPermissionTest
+@RunWith(AndroidJUnit4.class)
+public final class NotificationTest {
+
+ private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(10);
+
+ private static final String CHANNEL_ID = "TEST_CHANNEL";
+ private static final String CHANNEL_NAME = "Test channel";
+
+ private static final String REPLY_INPUT_KEY = "REPLY_KEY";
+ private static final String REPLY_INPUT_LABEL = "Test reply label";
+ private static final String ACTION_REPLY = "com.android.inputmethod.stresstest.ACTION_REPLY";
+ private static final String REPLY_ACTION_LABEL = "Test reply";
+ private static final int REPLY_REQUEST_CODE = 1;
+
+ private static final String NOTIFICATION_TITLE = "Test notification";
+ private static final String NOTIFICATION_CONTENT = "Test notification content";
+ private static final int NOTIFICATION_ID = 2000;
+
+ // This is for AOSP System UI for phones. When testing customized System UI, please modify here.
+ private static final BySelector REPLY_SEND_BUTTON_SELECTOR =
+ By.res("com.android.systemui", "remote_input_send");
+
+ private Context mContext;
+ private NotificationManager mNotificationManager;
+ private UiDevice mUiDevice;
+
+ @Before
+ public void setUp() {
+ mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ mNotificationManager = mContext.getSystemService(NotificationManager.class);
+ }
+
+ @After
+ public void tearDown() {
+ mNotificationManager.cancelAll();
+ }
+
+ @Test
+ public void testDirectReply() {
+ postMessagingNotification();
+ mUiDevice.openNotification();
+ mUiDevice.wait(Until.findObject(By.text(REPLY_ACTION_LABEL)), TIMEOUT).click();
+ // Verify that IME is visible.
+ assertThat(mUiDevice.wait(Until.findObject(By.pkg(getImePackage(mContext))), TIMEOUT))
+ .isNotNull();
+ // Type something, which enables the Send button, then click the Send button.
+ mUiDevice.pressKeyCode(KeyEvent.KEYCODE_A);
+ mUiDevice.pressKeyCode(KeyEvent.KEYCODE_B);
+ mUiDevice.pressKeyCode(KeyEvent.KEYCODE_C);
+ mUiDevice.wait(Until.findObject(REPLY_SEND_BUTTON_SELECTOR.enabled(true)), TIMEOUT).click();
+ // Verify that IME is gone.
+ assertThat(mUiDevice.wait(Until.gone(By.pkg(getImePackage(mContext))), TIMEOUT)).isTrue();
+ }
+
+ private void postMessagingNotification() {
+ // Register the channel. It's safe to register the same channel again and again.
+ NotificationChannel channel =
+ new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, IMPORTANCE_HIGH);
+ mNotificationManager.createNotificationChannel(channel);
+
+ // Post inline reply notification.
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(
+ mContext, REPLY_REQUEST_CODE, new Intent().setAction(ACTION_REPLY),
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
+ RemoteInput remoteInput = new RemoteInput.Builder(REPLY_INPUT_KEY)
+ .setLabel(REPLY_INPUT_LABEL)
+ .build();
+ Icon icon = Icon.createWithResource(mContext, android.R.drawable.ic_menu_edit);
+ Notification.Action action =
+ new Notification.Action.Builder(icon, REPLY_ACTION_LABEL, pendingIntent)
+ .addRemoteInput(remoteInput)
+ .build();
+ Notification notification = new Notification.Builder(mContext, CHANNEL_ID)
+ .setSmallIcon(android.R.drawable.ic_menu_edit)
+ .setContentTitle(NOTIFICATION_TITLE)
+ .setContentText(NOTIFICATION_CONTENT)
+ .addAction(action)
+ .build();
+ mNotificationManager.notify(NOTIFICATION_ID, notification);
+ }
+
+ private static String getImePackage(Context context) {
+ String imeId = Settings.Secure.getString(
+ context.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
+ ComponentName cn = ComponentName.unflattenFromString(imeId);
+ assertThat(cn).isNotNull();
+ return cn.getPackageName();
+ }
+}